Slide 1

Slide 1 text

CDKにおける Permissions Boundary の適用と運用時の課題 2025.11.08 Security-JAWS IAMスペシャル! Hisashi Ikenogami 1

Slide 2

Slide 2 text

自己紹介 2 池ノ上 寿志 / Hisashi Ikenogami 株式会社エヌデーデー CCoE支援

Slide 3

Slide 3 text

アジェンダ 3 1. 本日のキーワード 2. IAMエンティティに境界を設ける方法 3. Permissions Boundaryを利用した背景 4. CDKに関連するロール 5. CDKへのPermissions Boundary適用方法 6. Permissions Boundary適用パターン 7. AWSアカウントという境界 8. まとめ

Slide 4

Slide 4 text

アジェンダ 4 1. 本日のキーワード 2. IAMエンティティに境界を設ける方法 3. Permissions Boundaryを利用した背景 4. CDKに関連するロール 5. CDKへのPermissions Boundary適用方法 6. Permissions Boundary適用パターン 7. AWSアカウントという境界 8. まとめ

Slide 5

Slide 5 text

本日キーワード 5 • CDK • Permissions Boundary

Slide 6

Slide 6 text

CDK 6 • プログラミング言語でAWSリソースを定義 • CloudFormationを通じてプロビジョニング • あるべき状態を定義するIaCに柔軟性を持たせられる Source code User CDK Resource CloudFormation

Slide 7

Slide 7 text

Permissions Boundary 7 • 日本語で「権限の境界」 • Permissions Boundary自体は権限を付与しない • Identity-based policyと合わせて利用する • 権限の最大範囲を設定できる Permissions Boundary Identity-based policy

Slide 8

Slide 8 text

アジェンダ 8 1. 本日のキーワード 2. IAMエンティティに境界を設ける方法 3. Permissions Boundaryを利用した背景 4. CDKに関連するロール 5. CDKへのPermissions Boundary適用方法 6. Permissions Boundary適用パターン 7. AWSアカウントという境界 8. まとめ

Slide 9

Slide 9 text

IAMエンティティに境界を設ける方法 9 • SCP (Service Control Policy) • Permissions Boundary AWS account SCP User Permissions Boundary Role

Slide 10

Slide 10 text

IAMエンティティに境界を設ける方法 10 • SCP (Service Control Policy) • Permissions Boundary AWS account SCP User Permissions Boundary Role アカウント に適用

Slide 11

Slide 11 text

AWS account IAMエンティティに境界を設ける方法 11 • SCP (Service Control Policy) • Permissions Boundary SCP User Permissions Boundary Role IAMエンティティ に適用

Slide 12

Slide 12 text

アジェンダ 12 1. 本日のキーワード 2. IAMエンティティに境界を設ける方法 3. Permissions Boundaryを利用した背景 4. CDKに関連するロール 5. CDKへのPermissions Boundary適用方法 6. Permissions Boundary適用パターン 7. AWSアカウントという境界 8. まとめ

Slide 13

Slide 13 text

Permissions Boundaryを利用した背景 13 • ゲートキーパー • 境界防御 • 事前承認 • 一元管理 • ガードレール • はみ出してはいけない境界を定める • 境界内で自由に動く

Slide 14

Slide 14 text

Permissions Boundaryを利用した背景 14 • ゲートキーパー • 境界防御 • 事前承認 • 一元管理 • ガードレール • はみ出してはいけない境界を定める • 境界内で自由に動く 開発スピードの阻害 ボトルネックになりやすい

Slide 15

Slide 15 text

Permissions Boundaryを利用した背景 15 • ゲートキーパー • 境界防御 • 事前承認 • 一元管理 • ガードレール • はみ出してはいけない境界を定める • 境界内で自由に動く 自律性を保ちながら 安全性を確保 開発スピードの阻害 ボトルネックになりやすい

Slide 16

Slide 16 text

Permissions Boundaryを利用した背景 16 • ゲートキーパー • 境界防御 • 事前承認 • 一元管理 • ガードレール • はみ出してはいけない境界を定める • 境界内で自由に動く 「開発スピード」×「セキュリティ担保」を実現するためには ガードレールの考え方が重要 自律性を保ちながら 安全性を確保 ※文脈としては、ゲートキーパーだけでは開発スピードを阻害するため、 基本をガードレールとし、局面によってゲートキーパーで押さえる、のように併用するイメージ 開発スピードの阻害 ボトルネックになりやすい

Slide 17

Slide 17 text

IAMの変更権限を誰が持つか 17 1. 管理者が全てのIAMを管理 ➢ゲートキーパー 2. 開発者が全てのIAMを管理 ➢過剰な自由 3. 管理者がアプリに必要なIAMの管理だけを開発者に委任 ➢ガードレール

Slide 18

Slide 18 text

IAMの変更権限を誰が持つか 18 1. 管理者が全てのIAMを管理 ➢ゲートキーパー 2. 開発者が全てのIAMを管理 ➢過剰な自由 3. 管理者がアプリに必要なIAMの管理だけを開発者に委任 ➢ガードレール これを Permissions Boundary を用いて実現する

Slide 19

Slide 19 text

Permissions Boundaryで実現したかったこと 19 • 開発者がアプリに必要なロールを自身で作成できる • 開発者が権限昇格できない • 管理者が必要な制限を入れられる 管理者 開発者 アプリ Permissions Boundary Role Role 管理者の管理範囲 開発者の管理範囲

Slide 20

Slide 20 text

アジェンダ 20 1. 本日のキーワード 2. IAMエンティティに境界を設ける方法 3. Permissions Boundaryを利用した背景 4. CDKに関連するロール 5. CDKへのPermissions Boundary適用方法 6. Permissions Boundary適用パターン 7. AWSアカウントという境界 8. まとめ

Slide 21

Slide 21 text

CDKに関連するロール 21 1. CDKが使うロール 2. CDK利用者が作るロール 3. CDKが暗黙的に作るロール

Slide 22

Slide 22 text

CDKに関連するロール 22 ImagePublishing Deployment Action FilePublishing Lookup IAM Credential ECR S3 CloudFormation CloudFormation Execution Contextとして 参照するリソース User AssumeRole AssumeRole AssumeRole AssumeRole PassRole Deploy

Slide 23

Slide 23 text

1. CDKが使うロール 23 ImagePublishing Deployment Action FilePublishing Lookup IAM Credential ECR S3 CloudFormation CloudFormation Execution Contextとして 参照するリソース User AssumeRole AssumeRole AssumeRole AssumeRole PassRole Deploy 用途ごとに5種類 Bootstrapにて作成

Slide 24

Slide 24 text

2. CDK利用者が作るロール 24 ImagePublishing Deployment Action FilePublishing Lookup IAM Credential ECR S3 CloudFormation CloudFormation Execution Contextとして 参照するリソース User AssumeRole AssumeRole AssumeRole AssumeRole PassRole Deploy Lambda等に 付与するロール

Slide 25

Slide 25 text

3. CDKが暗黙的に作るロール 25 ImagePublishing Deployment Action FilePublishing Lookup IAM Credential ECR S3 CloudFormation CloudFormation Execution Contextとして 参照するリソース User AssumeRole AssumeRole AssumeRole AssumeRole PassRole Deploy CloudFormation カスタムリソース用Role 【例】 aws_s3.Bucketコンストラクトの autoDeleteObjectsをtrueにすると CloudFormationカスタムリソースとして LambdaとRoleが作成される

Slide 26

Slide 26 text

アジェンダ 26 1. 本日のキーワード 2. IAMエンティティに境界を設ける方法 3. Permissions Boundaryを利用した背景 4. CDKに関連するロール 5. CDKへのPermissions Boundary適用方法 6. Permissions Boundary適用パターン 7. AWSアカウントという境界 8. まとめ

Slide 27

Slide 27 text

1. CDKが使うロール 27 ① Bootstrapオプション ② Bootstrapテンプレートをカスタマイズ cdk bootstrap --custom-permissions-boundary policy-name cdk bootstrap --template cutom-template.yaml

Slide 28

Slide 28 text

1. CDKが使うロール 28 ImagePublishing Deployment Action FilePublishing Lookup IAM Credential ECR S3 CloudFormation CloudFormation Execution Contextとして 参照するリソース User AssumeRole AssumeRole AssumeRole AssumeRole PassRole Deploy 用途ごとに5種類 Bootstrapにて作成

Slide 29

Slide 29 text

1. CDKが使うロール 29 ImagePublishing Deployment Action FilePublishing Lookup IAM Credential ECR S3 CloudFormation CloudFormation Execution Contextとして 参照するリソース User AssumeRole AssumeRole AssumeRole AssumeRole PassRole Deploy ① Bootstrapオプション cdk bootstrap --custom-permissions-boundary policy-name

Slide 30

Slide 30 text

1. CDKが使うロール 30 ImagePublishing Deployment Action FilePublishing Lookup IAM Credential ECR S3 CloudFormation CloudFormation Execution Contextとして 参照するリソース User AssumeRole AssumeRole AssumeRole AssumeRole PassRole Deploy ② Bootstrapテンプレートをカスタマイズ cdk bootstrap --template custom-template.yaml

Slide 31

Slide 31 text

2. CDK利用者が作るロール 31 ① 個々のIAMエンティティへ適用 ② グローバルにCDKアプリ全体へ適用 new aws_iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), permissionsBoundary: iam.ManagedPolicy.fromManagedPolicyName(this, 'Policy', 'policy-name'), }); { "context": { "@aws-cdk/core:permissionsBoundary": { "name": “policy-name" } } } new App({ context: { [PERMISSIONS_BOUNDARY_CONTEXT_KEY]: { name: ' policy-name', }, }, }); cdk.json Appコンストラクター

Slide 32

Slide 32 text

2. CDK利用者が作るロール 32 ImagePublishing Deployment Action FilePublishing Lookup IAM Credential ECR S3 CloudFormation CloudFormation Execution Contextとして 参照するリソース User AssumeRole AssumeRole AssumeRole AssumeRole PassRole Deploy ※説明用に Role2個作成 する例に変更

Slide 33

Slide 33 text

2. CDK利用者が作るロール 33 ImagePublishing Deployment Action FilePublishing Lookup IAM Credential ECR S3 CloudFormation CloudFormation Execution Contextとして 参照するリソース User AssumeRole AssumeRole AssumeRole AssumeRole PassRole Deploy ① 個々のIAMエンティティへ適用 new aws_iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'), permissionsBoundary: iam.ManagedPolicy.fromManagedPolicyName(this, 'Policy', 'policy-name'), });

Slide 34

Slide 34 text

2. CDK利用者が作るロール 34 ImagePublishing Deployment Action FilePublishing Lookup IAM Credential ECR S3 CloudFormation CloudFormation Execution Contextとして 参照するリソース User AssumeRole AssumeRole AssumeRole AssumeRole PassRole Deploy ② グローバルにCDKアプリ全体へ適用 { "context": { "@aws-cdk/core:permissionsBoundary": { "name": “policy-name" } } } new App({ context: { [PERMISSIONS_BOUNDARY_CONTEXT_KEY]: { name: ' policy-name', }, }, });

Slide 35

Slide 35 text

2. CDK利用者が作るロール 35 ImagePublishing Deployment Action FilePublishing Lookup IAM Credential ECR S3 CloudFormation CloudFormation Execution Contextとして 参照するリソース User AssumeRole AssumeRole AssumeRole AssumeRole PassRole Deploy ② グローバルにCDKアプリ全体へ適用 { "context": { "@aws-cdk/core:permissionsBoundary": { "name": “policy-name" } } } new App({ context: { [PERMISSIONS_BOUNDARY_CONTEXT_KEY]: { name: ' policy-name', }, }, }); ※グローバルだけど 「CDKが暗黙的に作るロール」には適用されない

Slide 36

Slide 36 text

3. CDKが暗黙的に作るロール 36 ① Aspects import { Aws, IAspect, aws_iam as iam } from 'aws-cdk-lib'; import { IConstruct } from 'constructs'; export class PermissionsBoundaryAspect implements IAspect { public visit(node: IConstruct): void { if (node instanceof iam.CfnRole) { node.addPropertyOverride('PermissionsBoundary', `arn:${Aws.PARTITION}:iam::${Aws.ACCOUNT_ID}:policy/policy-name`, ); } } } Aspects.of(app).add(new PermissionsBoundaryAspect()); lib/aspect.ts bin/app.ts

Slide 37

Slide 37 text

3. CDKが暗黙的に作るロール 37 ImagePublishing Deployment Action FilePublishing Lookup IAM Credential ECR S3 CloudFormation CloudFormation Execution Contextとして 参照するリソース User AssumeRole AssumeRole AssumeRole AssumeRole PassRole Deploy CloudFormation カスタムリソース用Role 【例】 aws_s3.Bucketコンストラクトの autoDeleteObjectsをtrueにすると CloudFormationカスタムリソースとして LambdaとRoleが作成される

Slide 38

Slide 38 text

3. CDKが暗黙的に作るロール 38 ImagePublishing Deployment Action FilePublishing Lookup IAM Credential ECR S3 CloudFormation CloudFormation Execution Contextとして 参照するリソース User AssumeRole AssumeRole AssumeRole AssumeRole PassRole Deploy ① Aspects import { Aws, IAspect, aws_iam as iam } from 'aws-cdk-lib'; import { IConstruct } from 'constructs'; export class PermissionsBoundaryAspect implements IAspect { public visit(node: IConstruct): void { if (node instanceof iam.CfnRole) { node.addPropertyOverride('PermissionsBoundary', `arn:${Aws.PARTITION}:iam::${Aws.ACCOUNT_ID}:policy/policy-name`, ); } } } Aspects.of(app).add(new PermissionsBoundaryAspect());

Slide 39

Slide 39 text

• crossRegionReference 3. CDKが暗黙的に作るロール(例外) 39

Slide 40

Slide 40 text

Custom Resource • crossRegionReference Custom Resource us-east-1 ap-northeast-1 Stack Stack 3. CDKが暗黙的に作るロール(例外) 40 Parameter Store Role CloudFront WAF Exports Writer Exports Reader Role 書き込み インポート済 タグ付与 参照 ARN取得 リージョンを跨いで スタック間の値を参照する方法

Slide 41

Slide 41 text

Custom Resource • crossRegionReference Custom Resource us-east-1 ap-northeast-1 Stack Stack 3. CDKが暗黙的に作るロール(例外) 41 Parameter Store CloudFront WAF Exports Writer Exports Reader 書き込み インポート済 タグ付与 参照 CloudFormation カスタムリソース用Role Role Role CloudFormation カスタムリソース用Role ARN取得

Slide 42

Slide 42 text

Custom Resource ARN取得 Custom Resource • crossRegionReference us-east-1 ap-northeast-1 Stack Stack 3. CDKが暗黙的に作るロール(例外) 42 Parameter Store CloudFront WAF Exports Writer Exports Reader 書き込み インポート済 タグ付与 参照 Role Role CloudFormation カスタムリソース用Role CloudFormation カスタムリソース用Role Aspectsでも適用できない Aspectsでも適用できない

Slide 43

Slide 43 text

3. CDKが暗黙的に作るロール(例外) 43 • Issueに上がっていて未解決の状況 • コメントにある回避策(※)で適用できることは一応確認できた ※Permissions Boundary未設定ロールに対してPermissions Boundaryを設定する ベーススタッククラスを利用するというもの

Slide 44

Slide 44 text

CDKアプリ内のロールへの適用方法 44 方法 シンプル度 CDKアプリ内のロール CDK利用者が作るロール CDKが暗黙的に作るロール カスタムリソース crossRegion Reference cdk.json 高 ○ × × Aspects 中 ○ ○ × 回避策 低 ○ ○ ○

Slide 45

Slide 45 text

アジェンダ 45 1. 本日のキーワード 2. IAMエンティティに境界を設ける方法 3. Permissions Boundaryを利用した背景 4. CDKに関連するロール 5. CDKへのPermissions Boundary適用方法 6. Permissions Boundary適用パターン 7. AWSアカウントという境界 8. まとめ

Slide 46

Slide 46 text

Permissions Boundaryで実現したかったこと 46 • 開発者がアプリに必要なロールを自身で作成できる • 開発者が権限昇格できない • 管理者が必要な制限を入れられる 管理者 開発者 アプリ Permissions Boundary Role Role 管理者の管理範囲 開発者の管理範囲

Slide 47

Slide 47 text

• 最大限許可した上で必要最小限の拒否をリストアップ ブラックリスト方式 47 [Allow] Admin [Deny] Permissions Boundary identity-based policy [Allow] PowerUser+IAM Full ユーザに許可する操作

Slide 48

Slide 48 text

• 最大限許可した上で必要最小限の拒否をリストアップ ブラックリスト方式 48 [Allow] Admin [Deny] Permissions Boundary identity-based policy [Allow] PowerUser+IAM Full ユーザに許可する操作 以下を拒否 ① PB無しロール/ユーザ作成 ② PB自体の削除/解除 ③ その他管理者が制限したい操作

Slide 49

Slide 49 text

ブラックリスト方式(一部抜粋) 49 • Permissions Boundary有りロールだけ作成可とする - Sid: AllowAdminAccess Effect: Allow Action: '*' Resource: ‘*’ - Sid: DenyCreateOrChangeRoleWithoutBoundary Effect: Deny Action: - iam:CreateRole - iam:AttachRolePolicy - iam:DetachRolePolicy - iam:PutRolePolicy - iam:DeleteRolePolicy - iam:PutRolePermissionsBoundary Resource: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/* Condition: StringNotEquals: iam:PermissionsBoundary: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/${BoundaryPolicyName}

Slide 50

Slide 50 text

ブラックリスト方式(一部抜粋) 50 • Permissions Boundary有りロールだけ作成可とする - Sid: AllowAdminAccess Effect: Allow Action: '*' Resource: ‘*’ - Sid: DenyCreateOrChangeRoleWithoutBoundary Effect: Deny Action: - iam:CreateRole - iam:AttachRolePolicy - iam:DetachRolePolicy - iam:PutRolePolicy - iam:DeleteRolePolicy - iam:PutRolePermissionsBoundary Resource: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/* Condition: StringNotEquals: iam:PermissionsBoundary: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/${BoundaryPolicyName} 全て許可 Permissions Boundary無しロール作成を拒否

Slide 51

Slide 51 text

ブラックリスト方式の問題点 51 • PassRoleアクションは条件キーでPermissions Boundary を指定できない

Slide 52

Slide 52 text

ブラックリスト方式の問題点 52 • PassRoleとは • AWSサービスにロールを渡すことができる権限 • PassRoleだけでは何もできない(API呼出ではない) Administorator User Permissions Boundary Role Create Lambda { "Effect": "Deny", "Action": [ "iam:PassRole" ], "Resource": [ "*" ] } PassRole権限が無いと AdminでもLambdaが作成 できない ⇒リソース作成権限に加えて PassRoleが必要

Slide 53

Slide 53 text

ブラックリスト方式の問題点 53 • PassRoleアクションは条件キーでPermissions Boundary を指定できない - Sid: DenyPassRoleWithoutBoundary Effect: Deny Action: - iam:PassRole Resource: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/* Condition: StringNotEquals: iam:PermissionsBoundary: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/${BoundaryPolicyName}

Slide 54

Slide 54 text

ブラックリスト方式の問題点 54 • PassRoleアクションは条件キーでPermissions Boundary を指定できない - Sid: DenyPassRoleWithoutBoundary Effect: Deny Action: - iam:PassRole Resource: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/* Condition: StringNotEquals: iam:PermissionsBoundary: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/${BoundaryPolicyName}

Slide 55

Slide 55 text

PassRoleをどう制限するか 55 No 対応案 メリット デメリット 1 Roleのパスを利用する アプリごとのPBが不要 Role再作成+差替が必要(※) 2 リソース名にアプリ識別子が含まれ るものを制限対象とする Role再作成+差替が不要(※) アプリごとのPBが必要 3 開発者以外によって作成された ロールに対する操作をホワイトリス ト形式でDENYする ・アプリごとのPBが不要 ・Role再作成+差替が不要(※) リストアップしきれない、増減した ときに追随しきれない可能性あり ※Roleのパスは新規作成時しか指定できない⇒既存アプリの場合、Role再作成+差替が必要になる

Slide 56

Slide 56 text

PassRoleをどう制限するか 56 No 対応案 メリット デメリット 1 Roleのパスを利用する アプリごとのPBが不要 Role再作成+差替が必要(※) 2 リソース名にアプリ識別子が含まれ るものを制限対象とする Role再作成+差替が不要(※) アプリごとのPBが必要 3 開発者以外によって作成された ロールに対する操作をホワイトリス ト形式でDENYする ・アプリごとのPBが不要 ・Role再作成+差替が不要(※) リストアップしきれない、増減した ときに追随しきれない可能性あり 新規アプリに適用 既存アプリに適用 ※Roleのパスは新規作成時しか指定できない⇒既存アプリの場合、Role再作成+差替が必要になる

Slide 57

Slide 57 text

PassRoleをどう制限するか 57 • Roleのパスを利用する - Sid: AllowPassRoleForApp Effect: Allow Action: - iam:PassRole Resource: !Sub arn:${AWS::Partition}:iam::${AWS::AccountId}:role/app/* デフォルト : /policy-name 開発者用のパスを設ける : /app/policy-name

Slide 58

Slide 58 text

• IAM以外を許可 • IAMはホワイトリストで許可 • その他制限したい操作をブラックリストで拒否 ハイブリッド方式 58 [Allow] PowerUser+IAM Full Permissions Boundary identity-based policy [Deny] [Allow] IAM以外 ユーザに許可する操作 [Deny] [Allow] IAMのみ Permissions Boundary

Slide 59

Slide 59 text

アジェンダ 59 1. 本日のキーワード 2. IAMエンティティに境界を設ける方法 3. Permissions Boundaryを利用した背景 4. CDKに関連するロール 5. CDKへのPermissions Boundary適用方法 6. Permissions Boundary適用パターン 7. AWSアカウントという境界 8. まとめ

Slide 60

Slide 60 text

AWSアカウントという境界 60

Slide 61

Slide 61 text

AWSアカウントという境界 61 • AWSアカウント内は自由 • SCPでアカウントの外から制限 AWS account SCP User Role

Slide 62

Slide 62 text

アジェンダ 62 1. 本日のキーワード 2. IAMエンティティに境界を設ける方法 3. Permissions Boundaryを利用した背景 4. CDKに関連するロール 5. CDKへのPermissions Boundary適用方法 6. Permissions Boundary適用パターン 7. AWSアカウントという境界 8. まとめ

Slide 63

Slide 63 text

まとめ 63 • CDKでPermissions Boundaryを使った経験の共有 • スモールスタートで使い始めた • とりあえず使い始めてみたらいっぱい壁にぶつかった • 未だに最善策はわからず(IAMは奥が深い・・・) • フィードバックいただけるとうれしいです