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