Classi開発者ブログ

教育プラットフォーム「Classi」を開発・運営するClassi株式会社の開発者ブログです。

GitHub運用委員の紹介

みなさま、おはこんハロチャオ〜。開発支援部所属のid:aerealです。

この記事ではClassiにおけるGitHub運用委員という役割とその仕事について紹介します。

また、この記事はClassi developers Advent Calendar 2022 - Adventarの2日目の記事としてお届けします。

GitHub運用委員とは

Classiでは開発のコラボレーションツールとしてGitHubを活用しています。

Webサービスで事業を提供する企業にとって最も重要なソフトウェア資産といえるソースコードをホストするサービスですから不適切に扱えば重大な損害を被ることになりますし、最近はGitHub ActionsというCIサービスも利用できますから一歩間違えれば本番環境で稼働動しているサービスに大きな影響を与えかねません。

当社には情シスやサイバーセキュリティ推進部といった部署が存在し、基本的なセキュリティガードレールの設置や情報システムの管理はそれら部署が責任をもって行ってくれています。

しかしながら上記の通りGitHubは誤用・濫用してしまった場合の影響が大きく、また機能も多岐に渡るため、サービスと我々の業務フローを深く理解した上でより進んだサポートが必要と考えられます。

そういった背景からGitHub運用委員は生まれました。

GitHub運用委員はClassiのメンバーがGitHubを利用する上で望ましいデフォルトを提供したり、安全かつ快適に利用できるようサポートしたり、といったことをミッションに掲げています。

アカウント管理や基本的なセキュリティ施策 (SSOなど) は情シスやサイバーセキュリティ推進部と連携しお願いしつつ、よりサービスに寄り添った運用業務をしています。

活動内容

実際に我々が行っている活動をピックアップして紹介したいと思います。

各種クレジットの残高管理

ClassiではEnterprise Cloudというプランに加入しています。詳しい説明は省きますが、GitHubがホストするサービス形態の中で最も機能が充実しているプランと認識いただければ間違いはありません。

このプランにはGitHub Actionsなど従量課金制のサービスに対するクレジットが一定額含まれており、このクレジット以内であれば追加のコストを支払う必要はありません。

言い換えればこのクレジットを使い切ると追加のコストを支払わなければなりません。

特にGitHub ActionsやPackagesなどサービスのデプロイに不可欠なサービスも該当するので使えなくなった場合の影響はとても大きいです。

従来GitHubのWeb上で毎月各種クレジットの残高を確認していたのですが、単純作業な割にそれなりに重要で忘れてはいけないためなんとかしたい業務のひとつとなっていました。

GitHub運用委員はこの作業を引き受け、自動化および可視化することに成功しました。

Classiは既にBIツールとしてRedashを、データウェアハウスとしてBigQueryを活用しています。可視化と監視にRedashを、データの蓄積場所としてBigQueryを選び、APIから取得したデータをBigQueryに定期的に挿入する作戦をとっています。

たとえばGitHub ActionsのクレジットはGET /orgs/{org}/settings/billing/actionsというREST APIで取得することができます。

以下のような設定ファイルを書くとレスポンス結果をBigQueryのカラム定義にマッピングし、毎日自動でテーブルに挿入するツールを開発・運用しています。

{
  "action_billings": {
    "name": "action_billings",
    "timePartitioning": {
      "type": "DAY",
      "field": "calculatedOn"
    },
    "schema": [ // (1)
      {
        "name": "total_minutes_used",
        "required": true,
        "type": "INT64"
      },
      {
        "name": "total_paid_minutes_used",
        "required": true,
        "type": "FLOAT64"
      },
      {
        "name": "included_minutes",
        "required": true,
        "type": "INT64"
      },
      {
        "name": "minutes_used_breakdown",
        "required": true,
        "type": "RECORD",
        "schema": [
          {
            "name": "UBUNTU",
            "required": true,
            "type": "INT64"
          },
          // snip
          {
            "name": "total",
            "required": true,
            "type": "INT64"
          }
        ]
      },
      {
        "name": "calculatedOn",
        "required": true,
        "type": "DATETIME"
      }
    ],
    "source": { // (2)
      "kind": "rest", // (3)
      "config": { // (4)
        "method": "GET",
        "resource": "orgs/classi/settings/billing/actions"
      }
    }
  }
}
  • (1) … schema 以下でカラム定義を書きます
    • BigQuery APIのTableSchemaに相当するプロパティが使えます
  • (2) … source でデータの取得先を書きます
  • (3) … kind でREST APIを示します。他にあらかじめ取得しておいたJSONファイルを指定する file も対応しています
  • (4) … config でアクセスするREST APIのメソッドとリソース名 (パス) を書きます

このようにしておくことで似たようなコードを繰り返し書かずとも、設定ファイルを追記するだけで取得するデータを増やせます。

実際にPackagesの使用量も新たに監視することにしたのですが、設定ファイルの変更のみで簡単に追加できました。

さらに必要であればビューも定義します。 たとえば以下はGitHub Actionsの使用量を計算するビュークエリです。

SELECT
  total_minutes_used - LEAD(total_minutes_used) OVER (ORDER BY calculatedOn DESC) AS used_minutes_in_a_day,
  included_minutes - total_minutes_used AS remaining_minutes,
  calculatedOn
FROM
  `{{ .DatasetID }}.action_billings`
ORDER BY
  calculatedOn DESC

LEAD() 関数を使うことで前日と比較した値を計算できるのでこれを使ってその日に使った量を取得できます。

実際に利用料を観察しようと思うと月毎では粗すぎるため、日毎の利用料を可視化することである日を境に傾向が変わったことを認識できます。

最後にBigQueryをデータソースとして設定したRedashのグラフを作ります。

実際にプロットした様子が以下のグラフです。

github-actions-usage

月末にかけてきれいに減って月初で戻っている様子が伺えますね。

またこのグラフからわかるように9月はクレジットをぎりぎり使い切りそうでした。これも月末にいきなり気付くのではなく月の途中で発見し、変わった利用が起きたのかヒアリングしています。

ポリシーの制定と広報

GitHub運用委員はGitHubの社内エキスパートとして望ましいデフォルトを用意したり広めることもまた重要な責務となっています。

たとえばPersonal Access Token (以下、PAT) を使うとGitHubのAPIにアクセスでき、個人やチームの生産性向上に役立てることができます。

一方、粗い粒度でしか権限を与えられないため過剰な権限を持ちがちで漏洩した際のリスクも大きくなりがちです。

また個人に紐付く認可情報なので異動や退職などのイベントで引き継ぎ漏れが起きやすいです。

GitHub運用委員としてはPATのアクセス許可がリソースベースポリシーではなくアイデンティティベースポリシーになっていることも大きな懸念です。

ざっくりいえばアクセスされる対象 (APIエンドポイント、リポジトリなど) ごとにアクセスできるPATを一覧することができないので、知らぬ間に強い権限を持っているPATが増えているということが起きがちです。

つまりGitHub運用委員としてはPATはできるだけ使わないでほしい・どうしてもPATでなければいけないケースでのみやむなく使ってほしいものとして扱いたいです。

組織の開発者にとってもいらぬリスクを背負わず効率化にいそしんでもらうため、上記のような問題点と回避策をまとめてポリシーを定め広報しています。

たとえば以下のような内容をPATに関するポリシーとして定めています。

ちょっと待って!それ、本当にPATが必要ですか?

GitHub Actionsで実行されるワークフロー環境には、使い捨ての GITHUB_TOKEN が発行されます。 このトークンはそのワークフローを実行するレポジトリに閉じた権限が与えられます。

複数のレポジトリを横断しない限り、GitHub APIの呼び出しはActions備え付けの GITHUB_TOKEN で十分です。

Classiの設定では、GitHub Actionsに与えられるデフォルトの権限は contents:read だけです。 必要な権限は各ワークフローのYAMLファイルの中で明示的に permissions を記述してください。

参考資料

余談: PATとAudit Logの改善

上記でPAT自体やそれにまつわる運用上の懸念について述べましたが、GitHubのリリースによって改善されている点も多くあります。

たとえばFine-grained PATのリリースはとても大きな変更です。

参考: Introducing fine-grained personal access tokens | GitHub Changelog

GitHub Appsなどと同等のきめ細やかな単位で権限を設定できるのでまさに待望の機能といえます。

余談ですがfine-grained PATsのリリースにより従来のPATはclassic PATsと呼ばれるようになります。

しかしfine-grained PATsが銀の弾丸かといえば現時点ではそうはいえません。

GitHub Packagesなどへのアクセスはこの記事執筆時点で許可できないので引き続きclassic PATsを使う必要があります。 完全に置き換えるにはまだGitHubのリリースを待たなければいけない状況です。

また運用面ではAudit Logの改善が目覚ましい点にも言及しなければなりません。

Audit Logといういわゆる監査ログ機能がGitHubにもあるのですが、最近の変更で使われてトークンの情報がログに含まれるようになりました。

つまりあるAPIアクセスに使われたトークンの所有者が誰で、GitHub Appsなのかclassic PATsなのかfine-grained PATsなのかを把握できるようになりました。

参考: Display Authentication Token Data in your Enterprise Audit Log - Beta | GitHub Changelog

classic PATsをやむなく使うシーンがしばらく続くことを考えるとこの機能はとてもありがたいです。

このようにGitHub運用委員はポリシーを定める傍ら、新機能のリリースもしっかり追ってより現状に即したポリシーへのアップデートや利用の促進も行っています。

まとめ

ClassiにおけるGitHub運用委員の取り組みについて紹介しました。

筆者はClassiではじめてこういったGitHubの運用に深く関わるようになったのですが、とても強い権限が与えられるので今まで見たことのない画面が見えるようになってワクワクする反面、力の大きさに震えそうになることもあります。

しかしGitHubはソフトウェアを開発する上でとても大きな存在になっていますから、この運用をより安全・快適にすることでClassiの開発者全体に貢献できます。 そのテコで生まれる力の大きさはやはり楽しいです。

またこの記事で紹介したGitHubのAPIから取得したデータをBigQueryに取り込むツールは他にも様々なユースケースに沿えるような工夫をしているので、また改めて紹介したいですし、ゆくゆくはオープンなものにしたいという野望も抱いています。

以上、ClassiのGitHub運用委員の取り組みについての紹介でした。

明日12/3は id:tkdn よりお届けする予定です。

© 2020 Classi Corp.