MoTLab -GO Inc. Engineering Blog-MoTLab -GO Inc. Engineering Blog-

AWS IAM Identity Centerによるそこそこ複雑な権限管理の事例

SREAWS
June 02, 2023

こんにちは、SREグループの水戸 (@y_310) です。GO株式会社ではスタッフがAWSアカウントにログインする際の認証方法としてAWS IAM Identity Center (旧AWS SSO)を使用しています。

今回はAWS IAM Identity Centerを使ったAWSアカウントの権限管理の事例についてご紹介します。


背景

まず今回の権限管理方法の背景となる状況を説明します。GOでは現在60以上のAWSアカウントをAWS Organizationsの下で管理しており、それぞれのアカウントが様々な部署で利用されています。アカウントによっては事業のメインアカウントで非常に様々なリソースを含み詳細な権限管理が求められるものもあれば、反対にサンドボックス用途で単純な管理で問題ないものもあります。

アカウントや権限グループがこの先も増え続けていく中でセキュリティをコントロールするためには、複雑なケースもカバーした一貫した権限管理のルールが必要でした。

AWS IAM Identity Centerについて

AWS IAM Identity Centerは複数のAWSアカウントに対してSSOを実現するサービスです。ユーザの管理や権限付与の方法について独自の概念を持っているためAWS IAM Identity Centerの仕様について理解したい場合は公式ドキュメントと以下のクラスメソッドさんの記事がオススメです。

AWS SSOを図解してみた - https://dev.classmethod.jp/articles/aws-sso-wakewakame/

以降はAWS IAM Identity Centerの基本的な挙動を理解している前提で説明を進めます。

権限グループの分け方

AWS IAM Identity Centerでは権限をユーザかグループに付与することが出来ます。GOではユーザに直接権限を付与すると権限が細分化しすぎてしまうため、グループへの権限付与を必須としました。

そこでグループをどういう単位で分割するかが権限管理をする上での重要な意思決定になります。

グループの分け方にも色々な方法がありますが、大きな方向性として「会社の組織をベースとした分け方」と「開発するプロダクトのドメインをベースとした分け方」の2つがあると考えています。後者におけるプロダクトのドメインとは、例えば大きなところでは同じ社内の全く異なる事業の境界であったり、細かいところでは1プロダクト内における機能単位での境界であったりという事が考えられます。

それぞれのパターンについて具体的に解説します。

なお前提として権限管理をする際には権限を付与する対象のリソース(EC2インスタンスやS3バケットなど)が存在し、またそれぞれのリソースは何らかのサービス(APIサーバなど)を所有者としてグルーピングされていることを想定しています。

組織をベースとした分け方

組織をベースとした分け方は具体的にはユーザが所属する部署を権限グループとする分け方です。

An image from Notion

チームAに所属しているユーザはチームAグループ、チームBに所属しているユーザはチームBグループと各ユーザは原則として1つのグループに所属し、それぞれの所属部署以外のグループには参加しないものとします。一方リソースについては多くの場合1つの開発チームがあるサービスの全ての権限を持つものの、例外的に複数のチームが1つのサービスの開発に関わることもあるため、1つのリソースに対して異なるチームが権限を持つという状況がありえます。

この方式の場合チームに所属したメンバーが必要な権限を一気に付与できる分かりやすさと手間の少なさがありますが、一方で組織変更が発生するとグループの大規模な作り直しと権限の付け直しが発生する可能性があります。

プロダクトのドメインをベースとした分け方

プロダクトのドメインをベースとした分け方はリソースを使っているサービスをドメインの境界としてそれをグループとし、そのグループに対して権限を必要とするユーザを所属させるという分け方です。

An image from Notion

各ユーザはそれぞれの所属とは関係なく自分の業務に必要な権限を保有しているグループに参加します。そのため一人のユーザが複数のグループに所属することがありえます。一方リソースについてはその所有者であるサービスのグループしか権限を保有しません。

この方式の場合、組織が変わってもユーザの所属関係だけを調整すれば良く、権限グループ自体の作り直しは発生しません。一方チームに所属したメンバーが必要な権限を獲得するために複数グループへの所属が必要なケースもあるため、権限付与の作業が煩雑になることがあります。

開発するプロダクトの特性や組織構造によってそれぞれの方式の良し悪しは変わりますが、GOの場合組織変更に伴うチーム構成の変化が多いためその度にグループの作り直しが発生するのは運用コストが高いと判断し後者のプロダクトのドメインベースの分け方を採用しました。

なお、上記の例においては説明の簡略化のために1つのAWSアカウント内でのグループ管理として表現していますが、実際には複数のAWSアカウント内に複数のグループがある、という形でAWSアカウント、アカウント内グループそれぞれがドメインの境界になります。

AWS IAM Identity Centerにおけるドメインベースの権限管理

AWS IAM Identity CenterではAWSアカウントとグループ、許可セットという3つのリソースを紐付けることで権限付与を行います。この3つのリソースは任意の組み合わせで紐付けることができるため仕様上は以下の図のように1つのグループを複数のAWSアカウントや許可セットに紐づけすることも可能です。

An image from Notion

しかしAWSアカウントは明確にドメインの境界になるため今回の権限管理方法においては複数のアカウントをまたいだグループというのは存在しません。また許可セットはあるドメインに含まれるリソースへの権限を設定するポリシーの集合のためドメインを境界とするグループと1:1の関係になります。結果として今回の権限管理方法においては以下のように各AWSアカウント専用のグループが任意の数あり、それぞれのグループに対して専用の許可セットが1つ紐づく形になります。

An image from Notion

グループと許可セットの命名規則

AWS IAM Identity Centerにおいてはグループと許可セットというリソースの作成が必要なため一貫した管理のためにそれぞれの命名規則を定めました。前述のようにグループも許可セットもAWSアカウントに依存したリソースとして設計したため名前にアカウントを含めて表現できる形式としています。

具体的には、

  • グループ名: AWSアカウント名-ドメイン名
  • 許可セット名: AWSアカウントの省略名-ドメイン名

としています。許可セット名においてAWSアカウントの省略名としているのは許可セット名の文字数上限が32文字と短いためです。省略方法としては例えばアカウント名が go-product-dev であればそれぞれの頭文字を取って gpdとします。重複が発生する場合は gpde など重複しなくなるまで最後の単語の文字を追加します。また go-product1-devのように連番が含まれる場合は gp1dのように連番を含めます。

このルールに従うと以下のような組み合わせでAWSアカウントとグループ、許可セットが紐付けられることになります。

An image from Notion

詳細な権限管理をする場合の追加ルール

一部のアカウントは様々なサービスのリソースを内包しており大勢のユーザがアクセスする状況にあります。そういったアカウントにおいてはドメイン境界の中で更に詳細な権限管理が必要になるためグループをより細分化するための追加ルールを設定します。

細分化の基準は組織ごとに様々なパターンがありえますが、GOでは実際のニーズを観察した結果、以下の基準で分割しています。

  • アクセス権を付与するユーザの業務上の役割 (例えば社員と業務委託などの雇用形態の違い、エンジニアとプロダクトマネージャなど職種の違いなど)
  • 権限 (参照権限、更新権限)
  • 環境 (開発環境、本番環境)

これらの分割点を元にグループを構成すると例えば以下のようになります。(前述の例ではdomain1となっていた部分がdomain1-eng-ro-devのような構造化された文字列になります)

  • account1-domain1-eng-ro-dev (アカウント1のdomain1関連の開発環境リソースにエンジニアとして参照権限を付与)
  • account1-domain1-pdm-rw-prod (アカウント1のdomain1関連の本番環境リソースにプロダクトマネージャとして更新権限を付与)
  • account1-domain2-eng-ro-prod (アカウント1のdomain2関連の本番環境リソースにエンジニアとして参照権限を付与)

許可セットも同様に以下のようになります。(許可セットの文字数制約によりengineer→eng、readonly→roなど短縮した表現を使っています)

  • a1-domain1-eng-ro-dev
  • a1-domain1-pdm-rw-prod
  • a1-domain2-eng-ro-prod

全て紐付けると以下のようになります。

An image from Notion

この方式で実際に設定しAWSアクセスポータルを開くとこのようになります。この例ではdwhドメインとenterpriseドメインという2つのプロダクト領域があり、それぞれについて参照権限や更新権限が付与されています。アクセスしたいリソースに応じて対象の許可セットを選択しマネージメントコンソールにログインします。異なるドメインのリソースにアクセスしたい場合はこのAWSアクセスポータルに戻り別の許可セットを選択することになります。

An image from Notion

この権限管理方式のメリットとデメリット

実際にこの方式で権限管理を進めたことでメリットやデメリットが見えてきたのでご紹介します。

メリット

  • 組織変更が発生しても所属メンバーの入れ替えだけで対応でき、権限グループやポリシーの作り直しが発生しないため容易に対応できる
    • ドメインベースで権限グループを作った場合、含まれるリソースの所属ドメインが開発後に変わる可能性はかなり低いため作り直しが発生しづらい
  • リソースへのアクセス権がその所有権を持つドメインのグループのみになるため権限の適用範囲を把握しやすい
    • アクセス権の妥当性を調査したい場合、多くのケースでは「このリソースに誰がアクセス可能か」という観点で調査をする(このS3バケットを参照できるのは誰か、など)。その場合ドメインベースのグループだと権限を持つのはそのグループだけであることが明らかなので、所属メンバーを確認するだけで妥当性を確認することができる
  • 色々なケースに対して破綻することなく一貫したルールで権限管理ができている

デメリット

  • 権限グループの数が肥大化する
  • 開発者が自分がアクセスしたいリソースがどの権限グループに所属すると得られるのか分かりづらい
    • ドメインは複数のサービスをグルーピングした概念のため、あるサービスのリソースにアクセスしたい場合にそのサービスがどのドメインに含まれているのか把握する必要がある
  • アクセスしたいドメインや権限に応じてロールの切り替えが発生する
    • AWS IAM Identity Centerの仕様としてアカウントへのログインはロールによって実現されており、異なる権限グループにアクセスしたい場合はロールの切り替えをしないといけないため複数のドメインにまたがって業務を行う開発者にとっては切り替えの手間が発生する

まとめ

GOではこの方式で約150個の権限グループを管理しています。数は多いですが一貫したルールのもとで管理できているため認知負荷は低く、意図しない権限付与も起きづらい状態を維持できています。SREグループではこれらのグループやメンバー、ポリシーを全てTerraformで管理しており、ルール通りにグループ等を生成するためのモジュールも作成しているため作業負荷も低く運用できています。

権限管理は組織や扱うプロダクトの特性に応じてベストプラクティスが変わると思いますが、こちらで紹介した設計が1つの叩き台として参考になれば幸いです。


We're Hiring!

📢
GO株式会社ではともに働くエンジニアを募集しています。

興味のある方は 採用ページ も見ていただけると嬉しいです。

Twitter @goinc_techtalk のフォローもよろしくお願いします!