組織が成長するにつれて、IAM管理者だけですべてのIAMユーザーやロールを作成・管理することが難しくなります。しかし、開発者にIAM権限を委譲すると、意図しない過剰な権限が付与されるリスクがあります。本記事では、Permission Boundary(アクセス許可境界)を活用して、安全に権限管理を委譲する方法を解説します。

Permission Boundaryとは

Permission Boundaryは、IAMエンティティ(ユーザーまたはロール)に付与できるアクセス許可の上限を設定する高度な機能です。管理ポリシーを使用してアイデンティティベースのポリシーがIAMエンティティに付与できる最大権限を制限します。

重要なのは、Permission Boundary自体は権限を付与しないという点です。あくまでも「許可できる範囲の上限」を定義するだけであり、実際の権限はアイデンティティベースのポリシー(アクセス許可ポリシー)によって付与されます。

Permission Boundaryの仕組み

Permission Boundaryを設定した場合、IAMエンティティの有効なアクセス許可は、アイデンティティベースのポリシーとPermission Boundaryの「共通部分(交差部分)」になります。

graph TB
    subgraph "有効なアクセス許可の算出"
        PB[Permission Boundary<br/>許可する範囲の上限]
        IP[アイデンティティベース<br/>ポリシー<br/>実際に付与する権限]
        EP[有効なアクセス許可<br/>Effective Permissions]
        
        PB --> |交差| EP
        IP --> |交差| EP
    end
    
    style EP fill:#90EE90

たとえば、Permission BoundaryでS3、CloudWatch、EC2のみを許可し、アイデンティティベースのポリシーでS3とIAMを許可した場合、有効なアクセス許可はS3のみとなります。

具体例で理解するPermission Boundary

以下の例で、Permission Boundaryの効果を確認します。

Permission Boundary(上限の設定)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*",
                "cloudwatch:*",
                "ec2:*"
            ],
            "Resource": "*"
        }
    ]
}

アイデンティティベースのポリシー(実際の権限付与)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iam:CreateUser",
            "Resource": "*"
        }
    ]
}

この場合、アイデンティティベースのポリシーでiam:CreateUserを許可していますが、Permission Boundaryではiam:*が許可されていないため、iam:CreateUserの操作は拒否されます。

IAMポリシーとPermission Boundaryの違い

Permission Boundaryと通常のIAMポリシーは、それぞれ異なる役割を持っています。

比較項目 IAMポリシー(アイデンティティベース) Permission Boundary
役割 権限を付与する 権限の上限を設定する
単独での効果 権限が有効になる 権限は付与されない
設定対象 ユーザー、グループ、ロール ユーザー、ロールのみ
評価順序 Permission Boundaryと交差して評価 IAMポリシーと交差して評価

ポリシー評価ロジックとPermission Boundary

AWSのポリシー評価では、複数のポリシータイプが関係します。Permission Boundaryを含めた評価の流れを理解することが重要です。

flowchart TD
    A[リクエスト開始] --> B{明示的なDenyが<br/>あるか?}
    B -->|Yes| C[アクセス拒否]
    B -->|No| D{Organizations SCP<br/>で許可されているか?}
    D -->|No| C
    D -->|Yes| E{Permission Boundary<br/>で許可されているか?}
    E -->|No| C
    E -->|Yes| F{セッションポリシー<br/>で許可されているか?}
    F -->|No| C
    F -->|Yes| G{アイデンティティベース<br/>ポリシーで許可<br/>されているか?}
    G -->|No| H{リソースベース<br/>ポリシーで許可<br/>されているか?}
    H -->|No| C
    H -->|Yes| I[アクセス許可]
    G -->|Yes| I

Permission Boundaryは、Organizations SCPの後、セッションポリシーの前に評価されます。いずれかのポリシータイプで明示的に拒否されている場合、そのリクエストは拒否されます。

リソースベースのポリシーとの相互作用

Permission Boundaryとリソースベースのポリシーの関係は、プリンシパルの種類によって異なります。

IAMユーザーの場合

同じアカウント内で、IAMユーザーARNへのアクセス許可を付与しているリソースベースのポリシーは、Permission Boundaryの暗黙的な拒否によって制限されません。

IAMロールの場合

IAMロールARNにアクセス許可を与えるリソースベースのポリシーは、Permission Boundaryの暗黙的な拒否によって制限されます。

Permission Boundaryを使った権限委譲の実装

Permission Boundaryの真価は、セキュリティを維持しながらIAM管理を委譲できる点にあります。以下に、管理者が開発者に権限作成を委譲するパターンを示します。

ユースケース:開発者へのIAM作成権限の委譲

管理者(Maria)が開発者(Zhang)にIAMユーザー作成を委譲するシナリオを考えます。ただし、以下のルールを適用します。

  • 作成されるユーザーはS3、CloudWatch、EC2、DynamoDBのみ使用可能
  • 特定のS3バケット(logs)へのアクセスは禁止
  • 特定のEC2インスタンスへのアクセスは禁止
  • 作成されるユーザーはIAM管理操作を実行できない

ステップ1:新規ユーザー用のPermission Boundaryを作成

まず、作成されるユーザーに適用するPermission Boundaryを定義します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ServiceBoundaries",
            "Effect": "Allow",
            "Action": [
                "s3:*",
                "cloudwatch:*",
                "ec2:*",
                "dynamodb:*"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowIAMConsoleForCredentials",
            "Effect": "Allow",
            "Action": [
                "iam:ListUsers",
                "iam:GetAccountPasswordPolicy"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowManageOwnPasswordAndAccessKeys",
            "Effect": "Allow",
            "Action": [
                "iam:*AccessKey*",
                "iam:ChangePassword",
                "iam:GetUser",
                "iam:*ServiceSpecificCredential*",
                "iam:*SigningCertificate*"
            ],
            "Resource": ["arn:aws:iam::*:user/${aws:username}"]
        },
        {
            "Sid": "DenyS3Logs",
            "Effect": "Deny",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::logs",
                "arn:aws:s3:::logs/*"
            ]
        },
        {
            "Sid": "DenyEC2Production",
            "Effect": "Deny",
            "Action": "ec2:*",
            "Resource": "arn:aws:ec2:*:*:instance/i-1234567890abcdef0"
        }
    ]
}

このポリシーをXCompanyBoundariesという名前で作成します。

各ステートメントの役割は以下のとおりです。

  • ServiceBoundaries:許可するサービスの範囲を定義
  • AllowIAMConsoleForCredentials:IAMコンソールでの基本操作を許可
  • AllowManageOwnPasswordAndAccessKeys:自分自身の認証情報管理を許可
  • DenyS3Logs:特定のS3バケットへのアクセスを明示的に拒否
  • DenyEC2Production:本番環境のEC2インスタンスへのアクセスを明示的に拒否

ステップ2:委譲対象者(Zhang)用のPermission Boundaryを作成

次に、IAM作成を委譲される開発者(Zhang)に適用するPermission Boundaryを定義します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "CreateOrChangeOnlyWithBoundary",
            "Effect": "Allow",
            "Action": [
                "iam:AttachUserPolicy",
                "iam:CreateUser",
                "iam:DeleteUserPolicy",
                "iam:DetachUserPolicy",
                "iam:PutUserPermissionsBoundary",
                "iam:PutUserPolicy"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "iam:PermissionsBoundary": "arn:aws:iam::123456789012:policy/XCompanyBoundaries"
                }
            }
        },
        {
            "Sid": "CloudWatchAndOtherIAMTasks",
            "Effect": "Allow",
            "Action": [
                "cloudwatch:*",
                "iam:CreateAccessKey",
                "iam:CreateGroup",
                "iam:CreateLoginProfile",
                "iam:CreatePolicy",
                "iam:DeleteGroup",
                "iam:DeletePolicy",
                "iam:DeleteUser",
                "iam:GetAccountPasswordPolicy",
                "iam:GetGroup",
                "iam:GetLoginProfile",
                "iam:GetPolicy",
                "iam:GetUser",
                "iam:ListAccessKeys",
                "iam:ListAttachedUserPolicies",
                "iam:ListGroups",
                "iam:ListGroupsForUser",
                "iam:ListPolicies",
                "iam:ListUsers",
                "iam:UpdateGroup",
                "iam:UpdateLoginProfile",
                "iam:UpdateUser"
            ],
            "NotResource": "arn:aws:iam::123456789012:user/Maria"
        },
        {
            "Sid": "NoBoundaryPolicyEdit",
            "Effect": "Deny",
            "Action": [
                "iam:CreatePolicyVersion",
                "iam:DeletePolicy",
                "iam:DeletePolicyVersion",
                "iam:SetDefaultPolicyVersion"
            ],
            "Resource": [
                "arn:aws:iam::123456789012:policy/XCompanyBoundaries",
                "arn:aws:iam::123456789012:policy/DelegatedUserBoundary"
            ]
        },
        {
            "Sid": "NoBoundaryUserDelete",
            "Effect": "Deny",
            "Action": "iam:DeleteUserPermissionsBoundary",
            "Resource": "*"
        }
    ]
}

このポリシーをDelegatedUserBoundaryという名前で作成し、Zhangのアクセス許可境界として設定します。

重要なポイントは以下のとおりです。

  • CreateOrChangeOnlyWithBoundaryiam:PermissionsBoundary条件キーにより、XCompanyBoundariesをPermission Boundaryとして設定する場合のみ、IAMユーザーの作成や変更を許可
  • NoBoundaryPolicyEdit:Permission Boundaryポリシー自体の変更を禁止
  • NoBoundaryUserDelete:Permission Boundaryの削除を禁止

ステップ3:委譲対象者(Zhang)のアクセス許可ポリシーを作成

Permission Boundaryは上限を設定するだけなので、実際に許可する操作を定義するアクセス許可ポリシーが必要です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "IAM",
            "Effect": "Allow",
            "Action": "iam:*",
            "Resource": "*"
        },
        {
            "Sid": "CloudWatchLimited",
            "Effect": "Allow",
            "Action": [
                "cloudwatch:GetDashboard",
                "cloudwatch:GetMetricData",
                "cloudwatch:ListDashboards",
                "cloudwatch:GetMetricStatistics",
                "cloudwatch:ListMetrics"
            ],
            "Resource": "*"
        }
    ]
}

このポリシーをDelegatedUserPermissionsという名前でZhangにアタッチします。

ポリシーではiam:*を許可していますが、実際に実行できるIAM操作はDelegatedUserBoundary(Permission Boundary)で許可されている範囲に制限されます。

Permission Boundaryを使った権限委譲の流れ

上記の設定が完了した後の、Zhangによるユーザー作成の流れを説明します。

sequenceDiagram
    participant Zhang as 開発者<br/>Zhang
    participant IAM as AWS IAM
    participant NewUser as 新規ユーザー<br/>Nikhil
    
    Zhang->>IAM: CreateUser (Nikhil)
    Note over IAM: Permission Boundary<br/>XCompanyBoundariesを<br/>指定しているか確認
    
    alt Permission Boundaryなし
        IAM-->>Zhang: アクセス拒否
    else Permission Boundaryあり
        IAM->>NewUser: ユーザー作成
        IAM-->>Zhang: 成功
    end
    
    Zhang->>IAM: AttachUserPolicy (Nikhil)
    Note over IAM: 対象ユーザーに<br/>XCompanyBoundariesが<br/>設定されているか確認
    IAM-->>Zhang: 成功
    
    Note over NewUser: 有効な権限 =<br/>ポリシー ∩ Boundary

Zhangが新規ユーザーを作成する際、XCompanyBoundariesをPermission Boundaryとして指定しないと、作成は失敗します。この仕組みにより、管理者が定めたセキュリティルールを確実に適用できます。

ロールへのPermission Boundary適用

Permission Boundaryはユーザーだけでなく、IAMロールにも適用できます。これにより、開発者が作成するロールの権限も制限できます。

EC2インスタンスロールへの適用例

開発者がEC2用のIAMロールを作成する場合、Permission Boundaryを必須とすることで、過剰な権限を持つロールの作成を防止できます。

ロール作成を許可するポリシー

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "CreateRoleWithBoundary",
            "Effect": "Allow",
            "Action": [
                "iam:CreateRole",
                "iam:AttachRolePolicy",
                "iam:DetachRolePolicy",
                "iam:PutRolePolicy",
                "iam:DeleteRolePolicy"
            ],
            "Resource": "arn:aws:iam::123456789012:role/MyApp*",
            "Condition": {
                "StringEquals": {
                    "iam:PermissionsBoundary": "arn:aws:iam::123456789012:policy/AppRoleBoundary"
                }
            }
        },
        {
            "Sid": "PassRoleToEC2",
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::123456789012:role/MyApp*",
            "Condition": {
                "StringEquals": {
                    "iam:PassedToService": "ec2.amazonaws.com"
                }
            }
        }
    ]
}

このポリシーでは、以下の制約を設けています。

  • ロール名はMyAppで始まる必要がある
  • AppRoleBoundaryをPermission Boundaryとして設定する必要がある
  • ロールはEC2サービスにのみ渡すことができる

Permission Boundaryのベストプラクティス

Permission Boundaryを効果的に活用するためのベストプラクティスを紹介します。

命名規則の統一

Permission Boundaryポリシーには明確な命名規則を適用します。

  • *Boundaryサフィックスを使用する(例:DeveloperBoundary
  • 適用対象を明確にする(例:EC2AppRoleBoundary

最小権限の原則に従った設計

Permission Boundaryでも最小権限の原則を適用します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowSpecificServices",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "dynamodb:GetItem",
                "dynamodb:PutItem",
                "dynamodb:Query"
            ],
            "Resource": "*"
        }
    ]
}

サービス全体(s3:*)ではなく、必要なアクションのみを許可することで、より厳格な制限を実現できます。

Permission Boundaryの変更を防ぐ

Permission Boundaryポリシー自体の変更や削除を防ぐため、明示的なDenyステートメントを設けます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
{
    "Sid": "PreventBoundaryModification",
    "Effect": "Deny",
    "Action": [
        "iam:DeletePolicy",
        "iam:CreatePolicyVersion",
        "iam:DeletePolicyVersion",
        "iam:SetDefaultPolicyVersion"
    ],
    "Resource": "arn:aws:iam::123456789012:policy/*Boundary*"
}

条件キーを活用した細かな制御

iam:PermissionsBoundary条件キーを使用して、特定のPermission Boundaryが設定されている場合のみIAM操作を許可します。

1
2
3
4
5
6
7
{
    "Condition": {
        "StringEquals": {
            "iam:PermissionsBoundary": "arn:aws:iam::123456789012:policy/RequiredBoundary"
        }
    }
}

Permission Boundaryの制限事項

Permission Boundaryを使用する際には、以下の制限事項に注意してください。

適用対象の制限

  • Permission BoundaryはIAMグループには設定できません
  • グループに所属するユーザーには個別に設定する必要があります

リソースベースポリシーとの関係

  • IAMユーザーに対するリソースベースポリシーは、Permission Boundaryの暗黙的な拒否に制限されません
  • IAMロールに対するリソースベースポリシーは、Permission Boundaryの暗黙的な拒否に制限されます

明示的なDenyの扱い

Permission Boundaryで明示的にDenyされたアクションは、リソースベースポリシーでも許可できません。

まとめ

Permission Boundaryは、IAM管理を安全に委譲するための強力な機能です。本記事で解説した内容をまとめます。

  • Permission Boundaryは、IAMエンティティに付与できる権限の上限を設定する
  • 有効な権限は、アイデンティティベースポリシーとPermission Boundaryの共通部分となる
  • iam:PermissionsBoundary条件キーを使用して、Permission Boundaryの設定を強制できる
  • Permission Boundaryポリシー自体の変更を防ぐために、明示的なDenyを設定する

Permission Boundaryを適切に活用することで、セキュリティを維持しながら開発チームの自律性を高め、組織全体のAWS運用を効率化できます。

参考リンク