アクセス許可と AWS CDK - AWS Cloud Development Kit (AWS CDK) v2

これは AWS CDK v2 デベロッパーガイドです。古い v1 CDK は 2022 年 6 月 1 日にメンテナンスを開始し、2023 年 6 月 1 日にサポートを終了しました。

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

アクセス許可と AWS CDK

AWS コンストラクトライブラリは、アクセスとアクセス許可を管理するために、広く実装されているいくつかの一般的なイディオムを使用します。IAM モジュールには、これらのイディオムを使用するために必要なツールが用意されています。

AWS CDK は を使用して変更 AWS CloudFormation をデプロイします。すべてのデプロイには、 AWS CloudFormation デプロイを開始するアクター (開発者または自動システム) が含まれます。これを行う過程で、アクターは 1 つ以上の ID (ユーザーまたはロール) IAM を引き受け、オプションでロールを に渡します AWS CloudFormation。

AWS IAM Identity Center を使用してユーザーとして認証する場合、シングルサインオンプロバイダーは、事前定義されたIAMロールとして動作することを許可する有効期間の短いセッション認証情報を提供します。が IAM Identity Center 認証から AWS 認証情報 AWS CDK を取得する方法については、「」およびAWS SDKs「ツールリファレンスガイド」のIAM「アイデンティティセンター認証を理解する」を参照してください。

プリンシパル

IAM プリンシパルは、 を呼び出すことができるユーザー、サービス、またはアプリケーションを表す認証された AWS エンティティです AWS APIs。 AWS コンストラクトライブラリは、プリンシパルに AWS リソースへのアクセスを許可する複数の柔軟な方法でプリンシパルを指定することをサポートしています。

セキュリティコンテキストでは、「プリンシパル」という用語は、特にユーザーなどの認証されたエンティティを指します。グループやロールなどのオブジェクトは、ユーザー (およびその他の認証されたエンティティ) を表すのではなく、アクセス許可を付与する目的で間接的に識別します。

例えば、 IAMグループを作成する場合、グループ (およびそのメンバー) に Amazon RDSテーブルへの書き込みアクセス権を付与できます。ただし、グループ自体は単一のエンティティを表していないため、プリンシパルではありません (グループにログインすることもできません)。

CDKのライブラリではIAM、プリンシパルを直接または間接的に識別するクラスがIPrincipalインターフェイスを実装するため、これらのオブジェクトをアクセスポリシーで互換的に使用できます。ただし、セキュリティ上の意味では、これらすべてがプリンシパルであるわけではありません。これらのオブジェクトには以下が含まれます。

  1. IAM Role、、 Userなどの リソース Group

  2. サービスプリンシパル (new iam.ServicePrincipal('service.amazonaws.com')

  3. フェデレーティッドプリンシパル (new iam.FederatedPrincipal('cognito-identity.amazonaws.com')

  4. アカウントプリンシパル (new iam.AccountPrincipal('0123456789012'))

  5. 正規ユーザープリンシパル (new iam.CanonicalUserPrincipal('79a59d[...]7ef2be')

  6. AWS Organizations プリンシパル (new iam.OrganizationPrincipal('org-id')

  7. 任意のプリンシARNパル (new iam.ArnPrincipal(res.arn)

  8. 複数のプリンシパルを信頼iam.CompositePrincipal(principal1, principal2, ...)する

権限

Amazon S3 バケットや Amazon DynamoDB テーブルなど、アクセスできるリソースを表すすべてのコンストラクトには、別のエンティティへのアクセスを許可するメソッドがあります。 DynamoDB このようなメソッドには、すべてグラント で始まる名前があります。

例えば、Amazon S3 バケットには、エンティティからバケットへの読み取り/書き込みアクセスをそれぞれ有効にするメソッド grantReadgrantReadWrite (Python: grant_readgrant_read_write) があります。エンティティは、これらのオペレーションを実行するために必要な Amazon S3 アクセスIAM許可を正確に把握する必要はありません。

グラントメソッドの最初の引数は、常にタイプ ですIGrantable。このインターフェイスは、アクセス許可を付与できるエンティティを表します。つまり、IAMオブジェクト 、、 Role Userなどのロールを持つリソースを表しますGroup

他のエンティティに許可を付与することもできます。例えば、このトピックの後半では、Amazon S3 バケットへのプロジェクトアクセスを許可する CodeBuild方法を示します。通常、関連付けられたロールは、アクセス権が付与されているエンティティの role プロパティを介して取得されます。

などの実行ロールを使用するリソースlambda.Functionも を実装するためIGrantable、ロールへのアクセス権を付与するのではなく、直接アクセス権を付与できます。例えば、 bucketが Amazon S3 バケットで、 functionが Lambda 関数の場合、次のコードは関数にバケットへの読み取りアクセスを許可します。

TypeScript
bucket.grantRead(function);
JavaScript
bucket.grantRead(function);
Python
bucket.grant_read(function)
Java
bucket.grantRead(function);
C#
bucket.GrantRead(function);

スタックのデプロイ中にアクセス許可を適用する必要がある場合があります。このようなケースの 1 つは、 AWS CloudFormation カスタムリソースに他のリソースへのアクセスを許可する場合です。カスタムリソースはデプロイ時に呼び出されるため、デプロイ時に指定されたアクセス許可が必要です。

もう 1 つのケースは、サービスが渡すロールに適切なポリシーが適用されていることを確認する場合です。(ポリシーの設定を忘れないように、多くの AWS のサービスがこれを行います。) このような場合、アクセス許可の適用が遅すぎると、デプロイが失敗する可能性があります。

別のリソースが作成される前にグラントのアクセス許可を強制的に適用するには、次に示すように、グラント自体への依存関係を追加できます。グラントメソッドの戻り値は一般的に破棄されますが、実際にはすべてのグラントメソッドが iam.Grant オブジェクトを返します。

TypeScript
const grant = bucket.grantRead(lambda); const custom = new CustomResource(...); custom.node.addDependency(grant);
JavaScript
const grant = bucket.grantRead(lambda); const custom = new CustomResource(...); custom.node.addDependency(grant);
Python
grant = bucket.grant_read(function) custom = CustomResource(...) custom.node.add_dependency(grant)
Java
Grant grant = bucket.grantRead(function); CustomResource custom = new CustomResource(...); custom.node.addDependency(grant);
C#
var grant = bucket.GrantRead(function); var custom = new CustomResource(...); custom.node.AddDependency(grant);

ロール

IAM パッケージには、IAMロールを表すRoleコンストラクトが含まれています。次のコードは、Amazon EC2サービスを信頼する新しいロールを作成します。

TypeScript
import * as iam from 'aws-cdk-lib/aws-iam'; const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'), // required });
JavaScript
const iam = require('aws-cdk-lib/aws-iam'); const role = new iam.Role(this, 'Role', { assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com') // required });
Python
import aws_cdk.aws_iam as iam role = iam.Role(self, "Role", assumed_by=iam.ServicePrincipal("ec2.amazonaws.com")) # required
Java
import software.amazon.awscdk.services.iam.Role; import software.amazon.awscdk.services.iam.ServicePrincipal; Role role = Role.Builder.create(this, "Role") .assumedBy(new ServicePrincipal("ec2.amazonaws.com")).build();
C#
using Amazon.CDK.AWS.IAM; var role = new Role(this, "Role", new RoleProps { AssumedBy = new ServicePrincipal("ec2.amazonaws.com"), // required });

ロールの addToPolicyメソッド (Python: add_to_policy) を呼び出して、追加PolicyStatementするルールを定義する を渡すことで、ロールにアクセス許可を追加できます。ステートメントはロールのデフォルトポリシーに追加されます。何もない場合は、1 つ作成されます。

次の例では、承認されたサービスが であることを条件s3:AnotherActionとして、 アクションの ロールec2:SomeActionと リソースの ロールbucket、および otherRole (Python: other_role) にDenyポリシーステートメントを追加します AWS CodeBuild。

TypeScript
role.addToPolicy(new iam.PolicyStatement({ effect: iam.Effect.DENY, resources: [bucket.bucketArn, otherRole.roleArn], actions: ['ec2:SomeAction', 's3:AnotherAction'], conditions: {StringEquals: { 'ec2:AuthorizedService': 'codebuild.amazonaws.com', }}}));
JavaScript
role.addToPolicy(new iam.PolicyStatement({ effect: iam.Effect.DENY, resources: [bucket.bucketArn, otherRole.roleArn], actions: ['ec2:SomeAction', 's3:AnotherAction'], conditions: {StringEquals: { 'ec2:AuthorizedService': 'codebuild.amazonaws.com' }}}));
Python
role.add_to_policy(iam.PolicyStatement( effect=iam.Effect.DENY, resources=[bucket.bucket_arn, other_role.role_arn], actions=["ec2:SomeAction", "s3:AnotherAction"], conditions={"StringEquals": { "ec2:AuthorizedService": "codebuild.amazonaws.com"}} ))
Java
role.addToPolicy(PolicyStatement.Builder.create() .effect(Effect.DENY) .resources(Arrays.asList(bucket.getBucketArn(), otherRole.getRoleArn())) .actions(Arrays.asList("ec2:SomeAction", "s3:AnotherAction")) .conditions(java.util.Map.of( // Map.of requires Java 9 or later "StringEquals", java.util.Map.of( "ec2:AuthorizedService", "codebuild.amazonaws.com"))) .build());
C#
role.AddToPolicy(new PolicyStatement(new PolicyStatementProps { Effect = Effect.DENY, Resources = new string[] { bucket.BucketArn, otherRole.RoleArn }, Actions = new string[] { "ec2:SomeAction", "s3:AnotherAction" }, Conditions = new Dictionary<string, object> { ["StringEquals"] = new Dictionary<string, string> { ["ec2:AuthorizedService"] = "codebuild.amazonaws.com" } } }));

前の例では、 addToPolicy (Python: add_to_policy) 呼び出しを使用して新しいPolicyStatementインラインを作成しました。既存のポリシーステートメントまたは変更したポリシーステートメントを渡すこともできます。PolicyStatement オブジェクトには、プリンシパル、リソース、条件、アクションを追加するための多数のメソッドがあります。

ロールが正しく機能する必要があるコンストラクトを使用している場合は、次のいずれかを実行できます。

  • コンストラクトオブジェクトをインスタンス化するときに、既存のロールを渡します。

  • 適切なサービスプリンシパルを信頼して、コンストラクトに新しいロールを作成させます。次の例では、このようなコンストラクト、つまり CodeBuild プロジェクトを使用しています。

TypeScript
import * as codebuild from 'aws-cdk-lib/aws-codebuild'; // imagine roleOrUndefined is a function that might return a Role object // under some conditions, and undefined under other conditions const someRole: iam.IRole | undefined = roleOrUndefined(); const project = new codebuild.Project(this, 'Project', { // if someRole is undefined, the Project creates a new default role, // trusting the codebuild.amazonaws.com service principal role: someRole, });
JavaScript
const codebuild = require('aws-cdk-lib/aws-codebuild'); // imagine roleOrUndefined is a function that might return a Role object // under some conditions, and undefined under other conditions const someRole = roleOrUndefined(); const project = new codebuild.Project(this, 'Project', { // if someRole is undefined, the Project creates a new default role, // trusting the codebuild.amazonaws.com service principal role: someRole });
Python
import aws_cdk.aws_codebuild as codebuild # imagine role_or_none is a function that might return a Role object # under some conditions, and None under other conditions some_role = role_or_none(); project = codebuild.Project(self, "Project", # if role is None, the Project creates a new default role, # trusting the codebuild.amazonaws.com service principal role=some_role)
Java
import software.amazon.awscdk.services.iam.Role; import software.amazon.awscdk.services.codebuild.Project; // imagine roleOrNull is a function that might return a Role object // under some conditions, and null under other conditions Role someRole = roleOrNull(); // if someRole is null, the Project creates a new default role, // trusting the codebuild.amazonaws.com service principal Project project = Project.Builder.create(this, "Project") .role(someRole).build();
C#
using Amazon.CDK.AWS.CodeBuild; // imagine roleOrNull is a function that might return a Role object // under some conditions, and null under other conditions var someRole = roleOrNull(); // if someRole is null, the Project creates a new default role, // trusting the codebuild.amazonaws.com service principal var project = new Project(this, "Project", new ProjectProps { Role = someRole });

オブジェクトが作成されると、ロール (ロールが渡されたか、 コンストラクトによって作成されたデフォルトのロールか) がプロパティ として使用できますrole。ただし、このプロパティは外部リソースでは使用できません。したがって、これらのコンストラクトには addToRolePolicy (Python: add_to_role_policy) メソッドがあります。

コンストラクトが外部リソースの場合、 メソッドは何もせず、それ以外の場合は roleプロパティの addToPolicy (Python: add_to_policy) メソッドを呼び出します。これにより、未定義のケースを明示的に処理する手間が省けます。

次の例は、以下を示しています。

TypeScript
// project is imported into the CDK application const project = codebuild.Project.fromProjectName(this, 'Project', 'ProjectName'); // project is imported, so project.role is undefined, and this call has no effect project.addToRolePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, // ... and so on defining the policy }));
JavaScript
// project is imported into the CDK application const project = codebuild.Project.fromProjectName(this, 'Project', 'ProjectName'); // project is imported, so project.role is undefined, and this call has no effect project.addToRolePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW // ... and so on defining the policy }));
Python
# project is imported into the CDK application project = codebuild.Project.from_project_name(self, 'Project', 'ProjectName') # project is imported, so project.role is undefined, and this call has no effect project.add_to_role_policy(iam.PolicyStatement( effect=iam.Effect.ALLOW, # ... and so on defining the policy )
Java
// project is imported into the CDK application Project project = Project.fromProjectName(this, "Project", "ProjectName"); // project is imported, so project.getRole() is null, and this call has no effect project.addToRolePolicy(PolicyStatement.Builder.create() .effect(Effect.ALLOW) // .. and so on defining the policy .build();
C#
// project is imported into the CDK application var project = Project.FromProjectName(this, "Project", "ProjectName"); // project is imported, so project.role is null, and this call has no effect project.AddToRolePolicy(new PolicyStatement(new PolicyStatementProps { Effect = Effect.ALLOW, // ... and so on defining the policy }));

リソースポリシー

Amazon S3 バケットやIAMロールなど AWS、 の一部のリソースにもリソースポリシーがあります。これらのコンストラクトには addToResourcePolicyメソッド (Python: add_to_resource_policy) があり、引数PolicyStatementとして を取ります。リソースポリシーに追加されるすべてのポリシーステートメントでは、少なくとも 1 つのプリンシパルを指定する必要があります。

次の例では、Amazon S3 バケットbucketは、それ自体に アクセスs3:SomeAction許可を持つロールを付与します。

TypeScript
bucket.addToResourcePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: ['s3:SomeAction'], resources: [bucket.bucketArn], principals: [role] }));
JavaScript
bucket.addToResourcePolicy(new iam.PolicyStatement({ effect: iam.Effect.ALLOW, actions: ['s3:SomeAction'], resources: [bucket.bucketArn], principals: [role] }));
Python
bucket.add_to_resource_policy(iam.PolicyStatement( effect=iam.Effect.ALLOW, actions=["s3:SomeAction"], resources=[bucket.bucket_arn], principals=role))
Java
bucket.addToResourcePolicy(PolicyStatement.Builder.create() .effect(Effect.ALLOW) .actions(Arrays.asList("s3:SomeAction")) .resources(Arrays.asList(bucket.getBucketArn())) .principals(Arrays.asList(role)) .build());
C#
bucket.AddToResourcePolicy(new PolicyStatement(new PolicyStatementProps { Effect = Effect.ALLOW, Actions = new string[] { "s3:SomeAction" }, Resources = new string[] { bucket.BucketArn }, Principals = new IPrincipal[] { role } }));

外部IAMオブジェクトの使用

AWS CDK アプリの外部でIAMユーザー、プリンシパル、グループ、またはロールを定義している場合は、 AWS CDK アプリでそのIAMオブジェクトを使用できます。そのためには、その ARNまたはその名前を使用して参照を作成します。(ユーザー、グループ、ロールの名前を使用します)。その後、返されたリファレンスを使用して、前述のようにアクセス許可を付与したり、ポリシーステートメントを作成したりできます。

ポリシー ( マネージドポリシーを含む) は、次の方法を使用して同様の方法で使用できます。これらのオブジェクトへの参照は、 IAM ポリシーが必要な場所で使用できます。

注記

外部 AWS リソースへのすべての参照と同様に、CDKアプリ内の外部IAMオブジェクトを変更することはできません。