概要
開発チームにIAMロールの作成権限を委任したい場面は多くあります。Lambda関数やECSタスクには専用のIAMロールが必要であり、開発のたびにセキュリティチームにロール作成を依頼するのは効率的ではありません。
しかし、IAMロールの作成権限をそのまま委任すると、開発者が自分自身よりも強い権限を持つロールを作成する「権限昇格」が可能になってしまいます。この問題を解決するのが Permissions Boundary(アクセス許可の境界) です。
本記事では、Permissions Boundaryの仕組みを理解し、実際にPermissions Boundaryを使って開発者の権限昇格を防止する設定を行います。

この記事のメリット
- Permissions Boundaryの概念と、IDベースポリシーとの関係を正確に理解できる
- 「有効な権限 = IDベースポリシー ∩ Permissions Boundary」という評価ロジックを把握できる
- 開発者がIAMロールを作成する際にPermissions Boundaryの付与を強制するポリシーの書き方を習得できる
- Permissions Boundaryなしではロールを作成できないことをハンズオンで確認できる
- SCS試験の「IAM権限委任・権限昇格防止」に関する問いに正確に答えられるようになる
技術解説
権限昇格の問題
IAMロールの作成権限(iam:CreateRole、iam:AttachRolePolicy)を持つユーザーは、AdministratorAccessを持つロールを作成し、そのロールを引き受ける(AssumeRole)ことで、自分に付与された権限を超えた操作が可能になります。これが権限昇格です。
例えば、S3とEC2の操作権限のみを持つ開発者が、AdministratorAccessポリシーを付与したIAMロールを作成し、そのロールをLambda関数に割り当てれば、Lambda経由であらゆるAWSリソースを操作できてしまいます。

Permissions Boundaryとは
Permissions Boundaryは、IAMユーザーまたはIAMロールに設定できる 権限の上限 です。AWSマネージドポリシーまたはカスタマー管理ポリシーを使って定義します。
重要なのは、Permissions Boundary自体は権限を付与しないという点です。Permissions Boundaryはあくまで「ここまでの権限なら許可してよい」という上限を設定するものであり、実際に権限を付与するのはIDベースポリシーです。
有効な権限の決定方法
Permissions Boundaryが設定されたエンティティの有効な権限は、IDベースポリシーとPermissions Boundaryの 共通部分(交差) になります。
有効な権限 = IDベースポリシー ∩ Permissions Boundary
以下の表で具体例を示します。
| IDベースポリシー | Permissions Boundary | 有効な権限 |
|---|---|---|
| S3, EC2, IAM | S3, EC2, CloudWatch | S3, EC2 |
| AdministratorAccess | S3, EC2 | S3, EC2 |
| S3 のみ | S3, EC2, CloudWatch | S3 のみ |
IDベースポリシーでAdministratorAccessを付与しても、Permissions Boundaryで許可されていないサービスは利用できません。逆に、Permissions Boundaryで広く許可していても、IDベースポリシーで付与されていない権限は有効になりません。
Permissions Boundaryで権限昇格を防止する仕組み
Permissions Boundaryを使った権限昇格の防止は、以下の2つの設定を組み合わせることで実現します。
- Permissions Boundaryポリシーの作成: 開発者が作成するロールに付与可能な権限の上限を定義する
- ロール作成時のPermissions Boundary付与の強制: 開発者がロールを作成する際に、必ず指定のPermissions Boundaryを付与することを条件にする
2つ目の設定が特に重要です。iam:CreateRoleやiam:AttachRolePolicyのアクションに対して、iam:PermissionsBoundary条件キーを使い、指定されたPermissions Boundaryポリシーが付与されている場合のみ操作を許可します。
{
"Sid": "CreateRoleOnlyWithBoundary",
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:AttachRolePolicy"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::123456789012:policy/AppBoundaryPolicy"
}
}
}
この条件により、開発者はPermissions Boundaryを付けずにロールを作成することができなくなります。作成するロールには必ずAppBoundaryPolicyが適用されるため、たとえAdministratorAccessをアタッチしても、実際に有効な権限はBoundaryの範囲内に制限されます。
他の選択肢との比較
冒頭のシナリオで挙げられた他の選択肢と比較します。
| アプローチ | 種別 | 管理オーバーヘッド | 権限昇格の防止 |
|---|---|---|---|
| Permissions Boundary | 予防的 | 低い | 確実に防止 |
| CloudTrail + Lambda監視 | 検知的 | 高い(Lambda関数の開発・運用が必要) | 事後検知のみ |
| Organizations SCP | 予防的 | 中程度(Organizations導入が前提) | 防止可能だがスコープが広すぎる |
| IAM操作拒否 + チケット制 | 予防的 | 高い(チケット運用が必要) | 防止可能だが開発速度が低下 |
Permissions Boundaryは権限委任と権限制限を両立でき、管理オーバーヘッドも最小限に抑えられるため、このシナリオに最も適しています。
実践
前提条件
- リージョン:
ap-northeast-1(東京) - IAMユーザーが1つ作成済みであること(本記事では
developer-userとします) developer-userにはマネジメントコンソールへのログインが可能なパスワードが設定済みであること
作成するリソース一覧
| リソース種別 | リソース名 | 用途 |
|---|---|---|
| IAMポリシー | AppPermissionsBoundary | ロールに設定するPermissions Boundary |
| IAMポリシー | DeveloperPolicy | 開発者ユーザーに付与するポリシー |
| IAMロール | LambdaAppRole(実践中に作成) | Lambda用ロール(Boundary付き) |

ステップ1: Permissions Boundaryポリシーの作成
開発者が作成するロールの権限上限を定義するポリシーを作成します。ここではLambdaとECSのアプリケーションに必要なS3、DynamoDB、CloudWatch Logsへのアクセスのみを許可します。
- AWSマネジメントコンソールにログインし、リージョンが
ap-northeast-1(東京)であることを確認します - 上部の検索バーに
IAMと入力し、表示された「IAM」を選択します - 左側ナビゲーションの「ポリシー」を選択します
- 「ポリシーの作成」をクリックします
- 「JSON」タブを選択し、以下のポリシーを入力します
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAppServices",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:ListBucket",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:Query",
"dynamodb:Scan",
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
}
]
}
- 「次へ」をクリックします
- ポリシー名に
AppPermissionsBoundaryと入力します - 「ポリシーの作成」をクリックします

ステップ2: 開発者用ポリシーの作成
開発者ユーザーに付与するポリシーを作成します。このポリシーにはアプリケーションに必要な権限に加えて、Permissions Boundaryの付与を条件としたIAMロール作成権限を含めます。
- IAMコンソールの「ポリシー」画面で「ポリシーの作成」をクリックします
- 「JSON」タブを選択し、以下のポリシーを入力します
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowAppDevelopment",
"Effect": "Allow",
"Action": [
"s3:*",
"dynamodb:*",
"logs:*",
"lambda:*",
"ecs:*",
"ecr:*"
],
"Resource": "*"
},
{
"Sid": "AllowCreateRoleWithBoundary",
"Effect": "Allow",
"Action": [
"iam:CreateRole",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy",
"iam:PutRolePermissionsBoundary"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::ACCOUNT_ID:policy/AppPermissionsBoundary"
}
}
},
{
"Sid": "AllowRoleManagement",
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:ListRoles",
"iam:ListRolePolicies",
"iam:ListAttachedRolePolicies",
"iam:PassRole",
"iam:CreatePolicy",
"iam:GetPolicy",
"iam:ListPolicies"
],
"Resource": "*"
},
{
"Sid": "DenyBoundaryPolicyModification",
"Effect": "Deny",
"Action": [
"iam:DeletePolicy",
"iam:CreatePolicyVersion",
"iam:DeletePolicyVersion",
"iam:SetDefaultPolicyVersion"
],
"Resource": "arn:aws:iam::ACCOUNT_ID:policy/AppPermissionsBoundary"
},
{
"Sid": "DenyRemoveBoundary",
"Effect": "Deny",
"Action": "iam:DeleteRolePermissionsBoundary",
"Resource": "*"
}
]
}
注意:
ACCOUNT_IDの部分は、ご自身のAWSアカウントIDに置き換えてください。アカウントIDはコンソール右上のアカウント名をクリックすると確認できます。
各ステートメントの役割を説明します。

- AllowAppDevelopment: アプリケーション開発に必要なサービス(S3、DynamoDB、Lambda、ECS等)の操作を許可します
- AllowCreateRoleWithBoundary:
AppPermissionsBoundaryをPermissions Boundaryとして付与する場合に限り、IAMロールの作成とポリシーのアタッチを許可します。iam:PermissionsBoundary条件キーがこの制御の要です - AllowRoleManagement: ロールの参照やPassRoleなど、ロール管理に必要な補助的な操作を許可します
- DenyBoundaryPolicyModification:
AppPermissionsBoundaryポリシー自体の変更・削除を明示的に拒否します。これにより、開発者がBoundaryの内容を書き換えて権限を拡大することを防止します - DenyRemoveBoundary: ロールからPermissions Boundaryを削除する操作を拒否します。Boundaryを外して権限昇格することを防止します
- 「次へ」をクリックします
- ポリシー名に
DeveloperPolicyと入力します - 「ポリシーの作成」をクリックします
ステップ3: 開発者ユーザーにポリシーを付与する
- 左側ナビゲーションの「ユーザー」を選択します
- ユーザー一覧から
developer-userをクリックします - 「許可」タブの「許可を追加」をクリックし、「ポリシーを直接アタッチする」を選択します
- 検索バーに
DeveloperPolicyと入力し、表示されたポリシーにチェックを入れます - 「次へ」→「許可を追加」をクリックします
ステップ4: Permissions Boundaryなしでのロール作成を試みる(失敗の確認)
developer-userでログインし、Permissions Boundaryを付けずにロールを作成できないことを確認します。
- 現在のセッションからサインアウトし、
developer-userでマネジメントコンソールにログインします
- 上部の検索バーに
IAMと入力し、「IAM」を選択します - 左側ナビゲーションの「ロール」を選択します
- 「ロールを作成」をクリックします
- 信頼されたエンティティタイプで「AWSのサービス」を選択し、ユースケースで「Lambda」を選択します

- 「次へ」をクリックします
- 検索バーに
AmazonS3FullAccessと入力し、表示されたポリシーにチェックを入れます - 「次へ」をクリックします

- ロール名に
TestRoleWithoutBoundaryと入力します - Permissions Boundaryは設定せずに「ロールを作成」をクリックします

結果: 権限が不足している旨のエラーメッセージが表示され、ロールの作成に失敗します。DeveloperPolicyのAllowCreateRoleWithBoundaryステートメントの条件(iam:PermissionsBoundary)が満たされないため、iam:CreateRoleの実行が許可されません。

ステップ5: Permissions Boundaryを付けてロールを作成する(成功の確認)
続いて、Permissions Boundaryを付けてロールを作成できることを確認します。
- 再度「ロールを作成」をクリックします
- 信頼されたエンティティタイプで「AWSのサービス」を選択し、ユースケースで「Lambda」を選択します
- 「次へ」をクリックします
- 検索バーに
AmazonS3FullAccessと入力し、チェックを入れます - 「Permissions Boundary」セクションの「Permissions Boundaryを使用してアクセス許可の上限を設定する」を展開します
- 検索バーに
AppPermissionsBoundaryと入力し、表示されたポリシーを選択します

- 「次へ」をクリックします
- ロール名に
LambdaAppRoleと入力します - 「ロールを作成」をクリックします

結果: ロールの作成に成功します。条件キーiam:PermissionsBoundaryが指定したAppPermissionsBoundaryと一致するため、操作が許可されました。

ステップ6: 作成されたロールの有効な権限を確認する
作成したLambdaAppRoleの有効な権限を確認し、Permissions Boundaryが正しく機能していることを確かめます。
- 左側ナビゲーションの「ロール」を選択し、
LambdaAppRoleをクリックします - 「許可」タブを確認すると、以下の2つが表示されています。
- 許可ポリシー:
AmazonS3FullAccess - 許可の境界:
AppPermissionsBoundary
- 許可ポリシー:
- このロールの有効な権限を整理すると以下のようになります。
| 操作 | IDベースポリシー(S3FullAccess) | Permissions Boundary | 有効な権限 |
|---|---|---|---|
s3:GetObject | 許可 | 許可 | 許可 |
s3:PutObject | 許可 | 許可 | 許可 |
s3:ListBucket | 許可 | 許可 | 許可 |
s3:DeleteObject | 許可 | 許可されていない | 拒否 |
s3:DeleteBucket | 許可 | 許可されていない | 拒否 |
ec2:* | 許可されていない | 許可されていない | 拒否 |
iam:* | 許可されていない | 許可されていない | 拒否 |
IDベースポリシーでAmazonS3FullAccess(S3の全操作を許可)がアタッチされていますが、Permissions Boundary側で許可されているのはs3:GetObject、s3:PutObject、s3:ListBucketのみです。そのため、s3:DeleteObjectなどBoundaryで許可されていない操作は拒否されます。
このように、たとえ広い権限のポリシーをアタッチしても、Permissions Boundaryで定義した範囲内の操作しか実行できないことが確認できました。
まとめ
本記事のポイントを整理します。
- Permissions Boundaryは権限の上限を設定する仕組み です。権限を付与するのではなく、IDベースポリシーで付与できる権限の最大範囲を定義します
- 有効な権限はIDベースポリシーとPermissions Boundaryの共通部分 です。どちらか一方でも許可していない操作は実行できません
iam:PermissionsBoundary条件キー を使うことで、ロール作成時にPermissions Boundaryの付与を強制できます。これにより権限昇格を確実に防止できます- Boundaryポリシーの変更・削除の拒否 を組み合わせることで、開発者がBoundaryを回避することを防止します
- Permissions Boundaryは、CloudTrailによる事後検知やチケット制による運用と比べて、予防的かつ低オーバーヘッド なアプローチです
