1
2

複数アカウントへのスイッチロールを1つの許可セットで制御する

Posted at

1つのログインアカウントから複数の作業対象アカウントへスイッチロールを許可するための許可セットについて、ベストプラクティスを模索する。

AWS Identity CenterのAPIの問題

Identity Centerの許可セットのAPIは、ec2:DescribeInstancesのAPIのように一回のAPI実行で許可セットの属性情報が取得できない。具体的には、許可セットのARN一覧を取得(sso:ListPermissionSets)した後、許可セット毎に許可セットの属性情報を別のAPIで取得(sso:DescribePermissionSet)している。

これは、AWS管理コンソールのIAM Identity Center > 許可セットの画面で、許可セットの数だけAPIの呼び出しがブラウザの裏側で行われていることを示す。
そのため、許可セットの数が30-40程度であればさほど問題は発生しないが、300を超えたあたりから急激に応答が遅くなるし、目的の許可セットを許可セット名で絞り込み出来ないのもこのAPIの仕様のためと推測される。
(APIの仕様上sso:ListPermissionSetsでは許可セットの名称が分からないため、結局全ての許可セットの情報を1件1件sso:DescribePermissionSetで取得することになる)

参考:sso:ListPermissionSets API

ListPermissionSetsのResponse
{
   "NextToken": "string",
   "PermissionSets": [ "string" ]
}

参考:sso:DescribePermissionSet API

DescribePermissionSetのResponse
{
   "PermissionSet": { 
      "CreatedDate": number,
      "Description": "string",
      "Name": "string",
      "PermissionSetArn": "string",
      "RelayState": "string",
      "SessionDuration": "string"
   }
}

各AWSアカウントの管理者が異なる場合

ログインアカウントから各アカウントへスイッチロールすることを考える。
以下のように、各アカウント上には管理するチームおよびユーザーが異なるが、役割自体はチーム間で同一の考え方を用い、各アカウントには同名のIAMロールが存在するものとする(つまり、ユーザーはチームの兼任はしない)

アカウントA(管理チームA)

No IAMロール 担当するユーザー
1 Administrator 担当A1
2 PowerUser 担当A2
3 Readonly 担当A3

アカウントB(管理チームB)

No IAMロール 担当するユーザー
1 Administrator 担当B1
2 PowerUser 担当B2
3 Readonly 担当B3

アカウントC(管理チームC)

No IAMロール 担当するユーザー
1 Administrator 担当C1
2 PowerUser 担当C2
3 Readonly 担当C3

このとき、担当A1-A3はアカウントAにのみスイッチロール可能とし、アカウントB,Cにはスイッチロール不可、アカウントB,Cについても同様としたい。
とすると、そのままその要件を満たす許可セットは以下のようになる。

No 許可セット 担当するユーザー
1 A_Administrator 担当A1
2 A_PowerUser 担当A2
3 A_Readonly 担当A3
4 B_Administrator 担当B1
5 B_PowerUser 担当B2
6 B_Readonly 担当B3
7 C_Administrator 担当C1
8 C_PowerUser 担当C2
9 C_Readonly 担当C3

すると今後アカウントが追加された場合、許可セットも追加されることになるため汎用性がなく、また前述したように許可セットの数が多くなるとAWS管理コンソール上での操作が困難になるので推奨されない。

解決策

これを解決するには、許可セット側のポリシーではなくスイッチロール先のIAMロールの信頼ポリシーで制御する。
手順としては以下となる。

  1. 各アカウント共通となる許可セットを作成する。
    上記の例であれば、Administrator、PowerUser、Readonlyの3つを作成し、sts:AssumeRoleの許可ポリシーを記載する。この許可ポリシーはIAMロールのARNをResourceに記載することになるが、このときARNのアカウントに該当する部分を"*"のアスタリスクにしておく。
  2. この許可セットについてログインアカウントにプロビジョニングする。
    適当に選定したユーザー1人に割り当てを行わないとログインアカウント上にプロビジョニングできないので、テスト的な1人を選定してプロビジョニングする。
  3. 一度プロビジョニングすると、ログインアカウント内にIdentity Centerにて自動作成されたIAMロールが存在する。ロール名は"AWSReservedSSO_<許可セット名>_<ランダム十六進数16桁>"の形になっている。
  4. 上記"AWSReservedSSO_*"のIAMロールのロールIDを取得する。
    ロールIDの取得にはAWS CLIのコマンドを利用する。
  5. 各アカウント側にスイッチロール対象となるIAMロールを作成する。
    IAMロールの権限は各アカウント内で決定すれば良い(他のアカウントと細部が異なっていても問題はない)が、信頼ポリシーについてCondition句にスイッチロール元のロールIDと、使用を許可したいユーザーを識別する情報を設定する(下記参照)
許可セットの許可ポリシー(下記はAdministratorの役割のIAMロール名をCommon_Administratorとしている)
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": [
                "arn:aws:iam::*:role/Common_Administrator"
            ]
        }
    ]
}
アカウントAのCommon_Administratorロールの信頼ポリシー
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<ログインアカウント>:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:userid": [
            "<RoleId>:<UserName>"
          ]
        }
      }
    }
  ]
}
ロールIDを取得するAWS CLI
# aws iam get-role --role-name ロール名 | jq -r .Role.RoleId

信頼ポリシーのRoleIdにはAWS CLIコマンドで取得したロールID、UserNameにはIdentity Center上のユーザー名を指定する。
こうすることで、アカウントA上のIAMロールはアカウントAの管理チームのユーザー、アカウントB上のIAMロールはアカウントBの管理チームのユーザーのみが信頼ポリシーによってスイッチロールすることが可能となる。
また、許可セットのスイッチロールの許可ポリシーでスイッチロール先のロールARNでアカウント部分をアスタリスクにしておくことで、今後アカウントが追加されても許可セットの許可ポリシーを修正する必要がなくなるという利点がある。

留意事項

Identity Center上のユーザー名であるが、IDプールがActive Directoryの場合、デフォルトではActive Directory上のuserprincipalnameになっているため、username@example.com形式であることに注意する必要がある。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2