IAM Identity Center の許可セットで禁止した操作、自作ロールなら回避できる? SCP で権限昇格を防げるか検証してみた
クラウド事業本部 コンサルティング部のいたくらです。
はじめに
AWS Organizations でマルチアカウント環境を設計していると、「IAM Identity Center の許可セットにインラインポリシーで操作制限を掛けたはいいものの、これって本当に安全なんだっけ?」と気になったことはありませんか。私はあります。
具体的には、利用部門のメンバーに割り当てる許可セット(本記事では RestrictedAdmin と呼びます)に AdministratorAccess ポリシーをベースとしつつ、インラインポリシーで IAM ユーザー・グループの作成や更新、アクセスキーの発行といった操作を禁止するケースはよくあると思います。
ここで気になるのが、「そのユーザーが新しい IAM ロールを自作して AdministratorAccess をアタッチし、そのロールに切り替えたら、インラインポリシーの制限を回避できてしまうのでは」という懸念です。インラインポリシーは許可セット(=特定のロール)に紐づくものなので、ユーザーが別のロールを経由すれば理論上は制限の外に出られてしまいます。
そこで、この権限昇格の抜け道を SCP(サービスコントロールポリシー)で塞げるかどうかを検証してみました。
三行まとめ
- IAM Identity Center の許可セットに設定したインラインポリシーは、その許可セットのセッションにのみ適用され、ユーザーが新規に作成した IAM ロールには継承されない
- SCP はアカウント内の全プリンシパルに強制適用されるため、同じ制限を SCP に追加すれば権限昇格の抜け道を塞げる
- 検証では、
AdministratorAccessを付与した自作ロールからインラインポリシーで禁止しているiam:CreateUser(IAM ユーザー作成)を実行しても SCP の Deny が効くことを確認できた
前提
- AWS Organizations 管理下のマルチアカウント環境
- IAM Identity Center 経由でログイン
- 許可セット
RestrictedAdmin:AdministratorAccessポリシー + IAM ユーザー・グループ操作を禁止するインラインポリシーをアタッチ - 検証アカウントが所属する OU に、IAM ユーザー・グループ操作を拒否する SCP(詳細は後述)をあらかじめアタッチ済み
- 検証は本番影響のないテストアカウントで実施
やってみた
1. 許可セットのインラインポリシーの内容
RestrictedAdmin 許可セットには、以下のようなインラインポリシーをアタッチしていました。IAM ユーザー・グループに関する操作を一通り禁止する内容です。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyIamUserAndGroupOperations",
"Effect": "Deny",
"Action": [
"iam:CreateUser",
"iam:DeleteUser",
"iam:UpdateUser",
"iam:CreateGroup",
"iam:DeleteGroup",
"iam:UpdateGroup",
"iam:AddUserToGroup",
"iam:RemoveUserFromGroup",
"iam:AttachUserPolicy",
"iam:DetachUserPolicy",
"iam:PutUserPolicy",
"iam:DeleteUserPolicy",
"iam:AttachGroupPolicy",
"iam:DetachGroupPolicy",
"iam:PutGroupPolicy",
"iam:DeleteGroupPolicy",
"iam:CreateLoginProfile",
"iam:DeleteLoginProfile",
"iam:UpdateLoginProfile",
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:UpdateAccessKey"
],
"Resource": "*"
}
]
}
このインラインポリシーは、あくまで RestrictedAdmin 許可セット(= AWSReservedSSO_RestrictedAdmin_xxxx という IAM ロール)にのみ適用されます。裏を返すと、ユーザーが同一アカウント内で全く別の IAM ロールを新規作成した場合、そのロールにはこの制限が一切継承されません。
2. 権限昇格の懸念を実際に確かめる
まずは RestrictedAdmin でログインした状態のまま、直接 iam:CreateUser を実行してみます。
aws iam create-user --user-name test-user
aws: [ERROR]: An error occurred (AccessDenied) when calling the CreateUser operation: User: arn:aws:sts::<AWSアカウントID>:assumed-role/AWSReservedSSO_RestrictedAdministratorAccess_xxxx/CT-admin is not authorized to perform: iam:CreateUser on resource: arn:aws:iam::<AWSアカウントID>:user/test-user with an explicit deny in an identity-based policy
想定どおり AccessDenied になりました。ポイントはエラーメッセージの末尾で、with an explicit deny in an identity-based policy と表示されています。つまりこれは ID ベースポリシー(インラインポリシー)による拒否 であり、SCP による拒否ではないということが分かります。
ここで「本当に SCP でも防げているのか」を確認するには、インラインポリシーの影響を受けない別のロールで試す必要があります。
3. 新規ロールを自作して権限昇格を試みる
RestrictedAdmin から、自分自身を信頼する新規 IAM ロールを作成します。

このキャプチャはマネジメントコンソールで作成した escalation-test-role です。信頼ポリシーはアカウントの root を Principal にしているため、アカウント内の権限を持つユーザーから Assume できる状態になっています。
このロールに AdministratorAccess をアタッチしました。
マネジメントコンソール上でスイッチロールし、escalation-test-role の状態で iam:CreateUser を実行した結果が以下です。

~ $ aws iam create-user --user-name test-user
aws: [ERROR]: An error occurred (AccessDenied) when calling the CreateUser operation: User: arn:aws:sts::<AWSアカウントID>:assumed-role/escalation-test-role/CT-admin is not authorized to perform: iam:CreateUser on resource: arn:aws:iam::<AWSアカウントID>:user/test-user with an explicit deny in a service control policy: arn:aws:organizations::<AWSアカウントID>:policy/<組織ID>/service_control_policy/p-xxxxxxxx
~ $
今度はエラーメッセージが with an explicit deny in a service control policy に変わりました。AdministratorAccess を持つ自作ロールであっても、SCP レベルで確実に拒否されることが確認できました。
インラインポリシーの制限が及ばない新規ロールを作っても、SCP はアカウント内の全プリンシパルに強制適用されるため、権限昇格の抜け道が塞がっていることが証明できたことになります。
4. 実際に適用した SCP
検証に使った SCP は、検証アカウントが所属する OU にアタッチしました。組織全体の管理者向け許可セットだけはフルアクセス権限を与えるため、ArnNotLike 条件で除外しています。
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyIamUserAndGroupOperations",
"Effect": "Deny",
"Action": [
"iam:CreateUser",
"iam:DeleteUser",
"iam:UpdateUser",
"iam:CreateGroup",
"iam:DeleteGroup",
"iam:UpdateGroup",
"iam:AddUserToGroup",
"iam:RemoveUserFromGroup",
"iam:AttachUserPolicy",
"iam:DetachUserPolicy",
"iam:PutUserPolicy",
"iam:DeleteUserPolicy",
"iam:AttachGroupPolicy",
"iam:DetachGroupPolicy",
"iam:PutGroupPolicy",
"iam:DeleteGroupPolicy",
"iam:CreateLoginProfile",
"iam:DeleteLoginProfile",
"iam:UpdateLoginProfile",
"iam:CreateAccessKey",
"iam:DeleteAccessKey",
"iam:UpdateAccessKey"
],
"Resource": "*",
"Condition": {
"ArnNotLike": {
"aws:PrincipalARN": [
"arn:aws:iam::*:role/aws-reserved/sso.amazonaws.com/*/AWSReservedSSO_AdministratorAccess_*",
"arn:aws:iam::*:root",
"arn:aws:iam::*:role/OrganizationAccountAccessRole",
"arn:aws:iam::*:role/AWSControlTowerExecution"
]
}
}
}
]
}
インラインポリシーと全く同じアクションリストを SCP 側にも用意している点がポイントです。二重管理にはなりますが、「人(許可セット)」と「アカウント全体」の両方のレイヤーで同じ制御を掛けることで、抜け道のない多層防御になります。
補足
IAM Policy Simulator は条件付き SCP を評価できない
最初は IAM Policy Simulator で SCP の効果を検証できるかなと考えました。Policy Simulator は Organizations 配下のアカウントであれば SCP が IAM ポリシーに与える影響をテストできる機能自体は持っているのですが、公式ドキュメントに The policy simulator doesn't evaluate SCPs that have any conditions. と明記されているとおり、条件(Condition)を含む SCP は評価対象外でした。今回のように ArnNotLike 等の Condition を使った SCP はまさにこのケースに該当するため、Policy Simulator の使用は断念しました。条件付き SCP の効果を確認したい場合は、本記事のように実際のテストアカウントで確かめる方が安全です。
SCPの文字数クォータに注意
SCP には 1 ポリシーあたり 10240 文字(空白を除いた文字数)というデフォルトのクォータがあります。今回のようにアクションを個別に列挙していく方式だと、Statement を増やすたびにあっという間にクォータへ近づいていきます。JSON を json.dumps(data, separators=(',', ':')) のように整形して文字数を都度確認しておくと、デプロイ時に想定外のエラーを回避できます。
参考ドキュメント
- サービスコントロールポリシー (SCP) - AWS Organizations
- SCP 構文 - AWS Organizations
- IAM ポリシーシミュレーターを使用した IAM ポリシーのテスト - AWS Identity and Access Management
- AWS Organizations のクォータとサービス制限 - AWS Organizations
さいごに
SCP を設定しておけば、権限昇格しても制限は効くと思いつつ、念のため確認しようと思って検証してみた結果を備忘としてまとめてみました。
エラーメッセージの explicit deny in an identity-based policy と explicit deny in a service control policy で、どのレイヤーで防御できているのかを確認できて理解が深まりました。
権限まわりのガードレールは「設定した」で終わらせず、実際に確かめてみるのが大事だと改めて感じました。
この記事がどなたかのお役に立てれば幸いです。
以上、クラウド事業本部 コンサルティング部のいたくら(@itkr2305)でした!








