こんにちは、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アカウントに対して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サーバなど)を所有者としてグルーピングされていることを想定しています。
組織をベースとした分け方は具体的にはユーザが所属する部署を権限グループとする分け方です。
チームAに所属しているユーザはチームAグループ、チームBに所属しているユーザはチームBグループと各ユーザは原則として1つのグループに所属し、それぞれの所属部署以外のグループには参加しないものとします。一方リソースについては多くの場合1つの開発チームがあるサービスの全ての権限を持つものの、例外的に複数のチームが1つのサービスの開発に関わることもあるため、1つのリソースに対して異なるチームが権限を持つという状況がありえます。
この方式の場合チームに所属したメンバーが必要な権限を一気に付与できる分かりやすさと手間の少なさがありますが、一方で組織変更が発生するとグループの大規模な作り直しと権限の付け直しが発生する可能性があります。
プロダクトのドメインをベースとした分け方はリソースを使っているサービスをドメインの境界としてそれをグループとし、そのグループに対して権限を必要とするユーザを所属させるという分け方です。
各ユーザはそれぞれの所属とは関係なく自分の業務に必要な権限を保有しているグループに参加します。そのため一人のユーザが複数のグループに所属することがありえます。一方リソースについてはその所有者であるサービスのグループしか権限を保有しません。
この方式の場合、組織が変わってもユーザの所属関係だけを調整すれば良く、権限グループ自体の作り直しは発生しません。一方チームに所属したメンバーが必要な権限を獲得するために複数グループへの所属が必要なケースもあるため、権限付与の作業が煩雑になることがあります。
開発するプロダクトの特性や組織構造によってそれぞれの方式の良し悪しは変わりますが、GOの場合組織変更に伴うチーム構成の変化が多いためその度にグループの作り直しが発生するのは運用コストが高いと判断し後者のプロダクトのドメインベースの分け方を採用しました。
なお、上記の例においては説明の簡略化のために1つのAWSアカウント内でのグループ管理として表現していますが、実際には複数のAWSアカウント内に複数のグループがある、という形でAWSアカウント、アカウント内グループそれぞれがドメインの境界になります。
AWS IAM Identity CenterではAWSアカウントとグループ、許可セットという3つのリソースを紐付けることで権限付与を行います。この3つのリソースは任意の組み合わせで紐付けることができるため仕様上は以下の図のように1つのグループを複数のAWSアカウントや許可セットに紐づけすることも可能です。
しかしAWSアカウントは明確にドメインの境界になるため今回の権限管理方法においては複数のアカウントをまたいだグループというのは存在しません。また許可セットはあるドメインに含まれるリソースへの権限を設定するポリシーの集合のためドメインを境界とするグループと1:1の関係になります。結果として今回の権限管理方法においては以下のように各AWSアカウント専用のグループが任意の数あり、それぞれのグループに対して専用の許可セットが1つ紐づく形になります。
AWS IAM Identity Centerにおいてはグループと許可セットというリソースの作成が必要なため一貫した管理のためにそれぞれの命名規則を定めました。前述のようにグループも許可セットもAWSアカウントに依存したリソースとして設計したため名前にアカウントを含めて表現できる形式としています。
具体的には、
としています。許可セット名においてAWSアカウントの省略名としているのは許可セット名の文字数上限が32文字と短いためです。省略方法としては例えばアカウント名が go-product-dev であればそれぞれの頭文字を取って gpdとします。重複が発生する場合は gpde など重複しなくなるまで最後の単語の文字を追加します。また go-product1-devのように連番が含まれる場合は gp1dのように連番を含めます。
このルールに従うと以下のような組み合わせでAWSアカウントとグループ、許可セットが紐付けられることになります。
一部のアカウントは様々なサービスのリソースを内包しており大勢のユーザがアクセスする状況にあります。そういったアカウントにおいてはドメイン境界の中で更に詳細な権限管理が必要になるためグループをより細分化するための追加ルールを設定します。
細分化の基準は組織ごとに様々なパターンがありえますが、GOでは実際のニーズを観察した結果、以下の基準で分割しています。
これらの分割点を元にグループを構成すると例えば以下のようになります。(前述の例ではdomain1となっていた部分がdomain1-eng-ro-devのような構造化された文字列になります)
許可セットも同様に以下のようになります。(許可セットの文字数制約によりengineer→eng、readonly→roなど短縮した表現を使っています)
全て紐付けると以下のようになります。
この方式で実際に設定しAWSアクセスポータルを開くとこのようになります。この例ではdwhドメインとenterpriseドメインという2つのプロダクト領域があり、それぞれについて参照権限や更新権限が付与されています。アクセスしたいリソースに応じて対象の許可セットを選択しマネージメントコンソールにログインします。異なるドメインのリソースにアクセスしたい場合はこのAWSアクセスポータルに戻り別の許可セットを選択することになります。
実際にこの方式で権限管理を進めたことでメリットやデメリットが見えてきたのでご紹介します。
GOではこの方式で約150個の権限グループを管理しています。数は多いですが一貫したルールのもとで管理できているため認知負荷は低く、意図しない権限付与も起きづらい状態を維持できています。SREグループではこれらのグループやメンバー、ポリシーを全てTerraformで管理しており、ルール通りにグループ等を生成するためのモジュールも作成しているため作業負荷も低く運用できています。
権限管理は組織や扱うプロダクトの特性に応じてベストプラクティスが変わると思いますが、こちらで紹介した設計が1つの叩き台として参考になれば幸いです。
興味のある方は 採用ページ も見ていただけると嬉しいです。
Twitter @goinc_techtalk のフォローもよろしくお願いします!