This is the AWS CDK v2 Developer Guide. The older CDK v1 entered maintenance on June 1, 2022 and ended support on June 1, 2023.
Permissions and the AWS CDK
The AWS Construct Library uses a few common, widely implemented idioms to manage access and permissions. The IAM module provides you with the tools you need to use these idioms.
AWS CDK uses AWS CloudFormation to deploy changes. Every deployment involves an actor (either a developer, or an automated system) that starts a AWS CloudFormation deployment. In the course of doing this, the actor will assume one or more IAM Identities (user or roles) and optionally pass a role to AWS CloudFormation.
If you use AWS IAM Identity Center to authenticate as a user, then the single sign-on provider supplies short-lived session credentials that authorize you to act as a pre-defined IAM role. To learn how the AWS CDK obtains AWS credentials from IAM Identity Center authentication, see Understand IAM Identity Center authentication in the AWS SDKs and Tools Reference Guide.
Principals
An IAM principal is an authenticated AWS entity representing a user, service, or application that can call AWS APIs. The AWS Construct Library supports specifying principals in several flexible ways to grant them access your AWS resources.
In security contexts, the term "principal" refers specifically to authenticated entities such as users. Objects like groups and roles do not represent users (and other authenticated entities) but rather identify them indirectly for the purpose of granting permissions.
For example, if you create an IAM group, you can grant the group (and thus its members) write access to an Amazon RDS table. However, the group itself is not a principal because it doesn't represent a single entity (also, you cannot log in to a group).
In the CDK's IAM library, classes that directly or indirectly identify principals implement the IPrincipal
interface, allowing these objects to be used interchangeably in access policies. However, not all of them are
principals in the security sense. These objects include:
-
Service principals (
new iam.ServicePrincipal('service.amazonaws.com')
) -
Federated principals (
new iam.FederatedPrincipal('cognito-identity.amazonaws.com')
) -
Account principals (
new iam.AccountPrincipal('0123456789012'))
-
Canonical user principals (
new iam.CanonicalUserPrincipal('79a59d[...]7ef2be')
) -
AWS Organizations principals (
new iam.OrganizationPrincipal('org-id')
) -
Arbitrary ARN principals (
new iam.ArnPrincipal(res.arn)
) -
An
iam.CompositePrincipal(principal1, principal2, ...)
to trust multiple principals
Grants
Every construct that represents a resource that can be accessed, such as an Amazon S3 bucket or Amazon DynamoDB table, has methods that grant access to another entity. All such methods have names starting with grant.
For example, Amazon S3 buckets have the methods grantRead
and grantReadWrite
(Python: grant_read
, grant_read_write
) to enable read and
read/write access, respectively, from an entity to the bucket. The entity doesn't have to know exactly which Amazon S3 IAM
permissions are required to perform these operations.
The first argument of a grant method is always of type IGrantable. This interface represents
entities that can be granted permissions. That is, it represents resources with roles, such as the IAM objects
Role
,
User
,
and Group
.
Other entities can also be granted permissions. For example, later in this topic, we show how to grant a CodeBuild
project access to an Amazon S3 bucket. Generally, the associated role is obtained via a role
property on the
entity being granted access.
Resources that use execution roles, such as lambda.Function
, also implement
IGrantable
, so you can grant them access directly instead of granting access to their role. For example,
if bucket
is an Amazon S3 bucket, and function
is a Lambda function, the following code grants the
function read access to the bucket.
Sometimes permissions must be applied while your stack is being deployed. One such case is when you grant an AWS CloudFormation custom resource access to some other resource. The custom resource will be invoked during deployment, so it must have the specified permissions at deployment time.
Another case is when a service verifies that the role you pass to it has the right policies applied. (A number of AWS services do this to make sure that you didn't forget to set the policies.) In those cases, the deployment might fail if the permissions are applied too late.
To force the grant's permissions to be applied before another resource is created, you can add a dependency on the
grant itself, as shown here. Though the return value of grant methods is commonly discarded, every grant method in fact
returns an iam.Grant
object.
Roles
The IAM package contains a Role
construct that represents IAM
roles. The following code creates a new role, trusting the Amazon EC2 service.
You can add permissions to a role by calling the role's addToPolicy
method (Python: add_to_policy
), passing in a PolicyStatement
that defines
the rule to be added. The statement is added to the role's default policy; if it has none, one is created.
The following example adds a Deny
policy statement to the role for the actions
ec2:SomeAction
and s3:AnotherAction
on the resources bucket
and
otherRole
(Python: other_role
), under the condition that the authorized service is
AWS CodeBuild.
In the preceding example, we've created a new PolicyStatement
inline with the
addToPolicy
(Python: add_to_policy
) call. You can also pass in an existing policy statement or one you've modified.
The PolicyStatement object has numerous methods for adding
principals, resources, conditions, and actions.
If you're using a construct that requires a role to function correctly, you can do one of the following:
-
Pass in an existing role when instantiating the construct object.
-
Let the construct create a new role for you, trusting the appropriate service principal. The following example uses such a construct: a CodeBuild project.
Once the object is created, the role (whether the role passed in or the default one created by the construct) is
available as the property role
. However, this property is not available on external resources. Therefore,
these constructs have an addToRolePolicy
(Python: add_to_role_policy
) method.
The method does nothing if the construct is an external resource, and it calls the addToPolicy
(Python: add_to_policy
) method of the role
property otherwise. This saves you the trouble of
handling the undefined case explicitly.
The following example demonstrates:
Resource policies
A few resources in AWS, such as Amazon S3 buckets and IAM roles, also have a resource policy. These constructs have
an addToResourcePolicy
method (Python: add_to_resource_policy
), which takes a PolicyStatement
as its argument. Every policy statement added to a resource policy must specify at
least one principal.
In the following example, the Amazon S3 bucket
bucket
grants a role with the s3:SomeAction
permission to itself.
Using external IAM objects
If you have defined an IAM user, principal, group, or role outside your AWS CDK app, you can use that IAM object in your AWS CDK app. To do so, create a reference to it using its ARN or its name. (Use the name for users, groups, and roles.) The returned reference can then be used to grant permissions or to construct policy statements as explained previously.
-
For users, call
User.fromUserArn()
orUser.fromUserName()
.User.fromUserAttributes()
is also available, but currently provides the same functionality asUser.fromUserArn()
. -
For principals, instantiate an
ArnPrincipal
object. -
For groups, call
Group.fromGroupArn()
orGroup.fromGroupName()
. -
For roles, call
Role.fromRoleArn()
orRole.fromRoleName()
.
Policies (including managed policies) can be used in similar fashion using the following methods. You can use references to these objects anywhere an IAM policy is required.
Note
As with all references to external AWS resources, you cannot modify external IAM objects in your CDK app.