What happens when bucket.grantRead() in AWS CDK
Diving deep on how grant works in AWS CDK
Pahud Hsieh
Amazon Employee
Published Aug 3, 2024
Last Modified Sep 11, 2024
Have you ever wondered what actually happens when you grantRead from a S3 bucket to an IAM role?
In AWS, when an identity is accessing a resource, both IAM policies(identity-based policies) and resource-based policies (like S3 bucket policies) are evaluated together to determine the effective permissions.
In CDK, when
resource.grantRead(identity)
, it essentially execute the addToPrincipalOrResource() method. What's happening behind the scene: - CDK first tries to add relevant read permissions to that identity if it's an IAM principal.(update identity-based policies)
- If it doesn't work, it tries to add relevant statements to the resource policies.(update resource-based policies)
Now, if the identity is a
role
created from new iam.Role(), which is created by CDK, 1) would work as CDK would render the policies for the iam.Role it is creating. However, if the role is from iam.Role.fromRoleArn()
or fromRoleName()
, which returns the IRole
interface. CDK would not add identity-based policies to it. Because that role as type IRole could already be created out of current CDK stack and it would not be able to update the existing iam policies attached to this role. When this happens, step 1 would not change anything, falling to step 2.Similarly, in step 2, if the resource is actually an interface like IBucket, it would not add any statements to the resource-based policy because that could be created out of this CDK stack.
You get a concrete
Bucket
when you new s3.Bucket()
in current stack otherwise you would get IBucket
interface when you use the fromXxx()
methods to reference an existing resource or simply reference another bucket from another stack. That returns IBucket
to you as well.Next time when you use construct methods like
resource.grantRead(identity)
, grantWrite()
or grantInvoke()
. Think about it:- Is the identity an IAM principal like IAM role? If yes, is it a concrete principal or just an interface that references an existing one?
- Does the resource have resource-based policies? If yes, is it a concrete resource or just an interface that references an existing one?
bucket.grantRead()
won't work if both resource-based and identity-based policies can't be updated. For example:- Both the iam principal and resource are created out of CDK and we just reference them as interfaces in CDK.
- The identity could be something like CloudFront OAI, which is not an IAM principal and the bucket is actually
IBucket
, which references an existing bucket in another stack or created out of CDK.
Any opinions in this post are those of the individual author and may not reflect the opinions of AWS.