カミナシ エンジニアブログ

株式会社カミナシのエンジニアが色々書くブログです

Terraform で実現する効率的な GitHub 権限管理

こんにちは。ソフトウェアエンジニアの坂井 (@manabusakai) です。

今月でカミナシに入社してちょうど 1 年が経ちました。前職では 6 年間 SRE チームにいたのでプロダクト開発はブランクがありましたが、さまざまな挑戦をさせてもらっていたらあっという間に 1 年が経っていました。

カミナシのエンジニアリング組織もこの 1 年で急拡大しており、入社当初から比べると正社員のエンジニアも倍以上に増えました。

GitHub の権限管理、どうしていますか?

ところで、みなさんが所属されている組織ではどのように GitHub の権限管理を行なっていますか?

カミナシではつい先日まで、ほとんどのエンジニアが Organization の Owner 権限を持っていました。理由は、メンターになったエンジニアがニューカマーのユーザーを招待していたからです。

しかし、統制が取れていないことでいくつか問題も発生していました。

  • 不必要に強い権限を持ってしまっている
  • Organization への招待や権限付与が適切なものかレビューされていない
  • GitHub のユーザー名と従業員名簿が突き合わせできない

実際に、アカウントの棚卸しを依頼されたエンジニアリングマネージャーが Slack で聞いて回るという事態が発生していました。

GitHub アカウントの棚卸しの様子

エンジニアリング組織が拡大していくと、いつか破綻してしまうのは目に見えていたので、このタイミングで Terraform を使った権限管理に移行しました。

Terraform で行う GitHub 権限管理

Terraform というと AWS や GCP などの Infrastructure as Code をイメージされる方が多いと思いますが、実は GitHub のリソースを管理する GitHub provider も存在します。

これは HashiCorp が直接メンテナンスしている Official provider ではなく、パートナーシップを結んだ企業がメンテナンスしている Partner provider のひとつです。

カミナシではこの provider を利用して、次の GitHub リソースを Terraform で管理しています。

今のカミナシのフェーズだとリポジトリごとの細かい権限管理は必要ないので、チームはもっぱら他チームにコードレビューを依頼するときに使っています(Organization に所属していれば、基本的にすべてのリポジトリが見れて誰でも Pull request を出せるようにしています)。

Terraform のコードは次のようなフラットな構成になっています。

$ tree
.
├── README.md
├── memberships_of_full_time.tf
├── memberships_of_outsourcing.tf
├── memberships_of_part_time.tf
├── provider.tf
├── repository_collaborators.tf
├── team_members_of_xxxxxx.tf
├── team_members_of_xxxxxx.tf
├── teams.tf
├── terraform.tfvars
└── variables.tf

Manage GitHub Users, Teams, and Repository Permissions” のように CSV ファイルをマスターにすることはせず、愚直に tf ファイルに定義しています。

CI は Terraform Cloud を利用しており、GitHub App で認証を行っています。 GitHub provider は OAuth Token / Personal Access Token で認証することもできますが、Organization の強い権限を与える必要があるため、永続的な token は漏洩したときのリスクが大きすぎます。

これまで手動で管理されていたリソースは、Terraform 1.5 で追加された import ブロックと -generate-config-out フラグを組み合わせて一気にインポートしました *1

アカウント管理を Pull request で行う

Terraform でコード化することの最大のメリットは、すべての作業をプロダクト開発と同じように Pull request で行えるようになることです。

Pull request で行うことで、最初に挙げた課題を解決することができました。ひとつずつ見ていきましょう。

Owner 権限は一部のメンバーにだけ付与する

本来 Organization の Owner 権限は全員が持つべき権限ではありません。

今回 Terraform で権限管理ができるようになったことで、Organization への招待や権限付与は Pull request を作成するだけで良くなりました。なので、このタイミングで Owner 権限を持っているのは CTO とエンジニアリングマネージャーだけにしました。

認証を行うための GitHub App も最小権限に絞っています。

Organization への招待や権限付与は必ずレビューされる

適切なレビューサイクルを作るために、GitHub のコードオーナーを活用しています。

具体的には、tf ファイルのコードオーナーをエンジニアリングマネージャーにして、マージするにはコードオーナーのレビューを必須としています(Branch protection rule の “Require review from Code Owners” の設定)。

こうすることでメンターは Pull request を作成し、マネージャーがその内容をレビューするというサイクルが作れます。チーム異動が発生した際もマネージャーの作業を待つ必要はなく、メンバー自らが Pull request を作成すれば良いのです。

またコードで管理されているので、あとから意図を汲み取るのも git blame するだけで済みます。

GitHub のユーザー名と従業員名を紐付ける

GitHub のユーザー名は本名と結びついていないケースも多いので、Terraform のリソース名を従業員名と一致させ、コメントに従業員番号も書くルールにしました。

例えば、次のような感じです。

# 0056
resource "github_membership" "tori_hara" {
  role     = "admin"
  username = "toricls"
}

# 0070
resource "github_membership" "manabu_sakai" {
  role     = "member"
  username = "manabusakai"
}

こうしておけば、棚卸しするときも聞いて回る必要はなく、誰でも簡単に従業員名簿と突き合わせすることができます。

おわりに

まだそこまで規模が大きくなかったこともあり、実質的な作業は 1 日もかからずに終わらせることができました(インポート作業が一番大変でした)。

直接的なプロダクトへの価値提供ではありませんが、組織内の課題を仕組みでうまく解決できたのは良かったです!


最後に宣伝です 📣

カミナシでは絶賛採用中です! 一緒に強いチームを作っていく仲間を募集しています!