Skip to content

Commit 1a166d2

Browse files
committed
fix(s3,kms): use tags for granting cross-account
When a bucket or key grant targets a CDK-owned principal in another account, the resource policy referenced the role by its ARN. S3 and KMS validate that every principal in a resource policy exists at the time the policy is deployed, so unless the principal's stack happens to deploy first, the first deployment fails with "Invalid principal in policy" (S3) or "Policy contains a statement with one or more invalid principals" (KMS). The most common way to hit this is a cross-account + cross-region CodePipeline: the action role lives in a support stack with no deploy-ordering guarantee relative to the bucket/key stack, so there is no deploy order that works on the first attempt. ecr.Repository.grant() already solves this exact problem: when the grantee is a CDK-owned resource in another account and the resource's stack does not depend on the grantee's stack, tag the grantee (aws-cdk:id) and trust the grantee's account root scoped by an aws:PrincipalTag condition instead of the bare role ARN. Account-root principals and condition values are not existence-checked, so deploy order no longer matters, while the tag keeps the trust scoped to the single intended role. This change extracts the ECR implementation into a shared private helper (aws-iam/lib/private/cross-account-grants.ts) and applies it to S3 bucket grants and KMS key grants. ECR is refactored to use the helper with no behavior change. Imported principals, same-account grants, grants where the resource stack already depends on the principal stack, and the KMS trustAccountIdentities are not affected. The @aws-cdk/aws-iam:crossAccountGrantsViaPrincipalTag flag gates the S3 and KMS behavior and is off by default for existing apps. It acknowledges that tag-scoped account-root trust survives role recreation and can be spoofed in-account by principals allowed to tag roles.
1 parent 08a2543 commit 1a166d2

43 files changed

Lines changed: 3183 additions & 93 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-cross-account-grant.js.snapshot/KeyCrossAccountGrantDefaultTestDeployAssert9CB4ED73.assets.json

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-cross-account-grant.js.snapshot/KeyCrossAccountGrantDefaultTestDeployAssert9CB4ED73.metadata.json

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-cross-account-grant.js.snapshot/KeyCrossAccountGrantDefaultTestDeployAssert9CB4ED73.template.json

Lines changed: 36 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-cross-account-grant.js.snapshot/KeyPrincipalStack.assets.json

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-cross-account-grant.js.snapshot/KeyPrincipalStack.metadata.json

Lines changed: 91 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
{
2+
"Resources": {
3+
"Role1ABCC5F0": {
4+
"Type": "AWS::IAM::Role",
5+
"Properties": {
6+
"AssumeRolePolicyDocument": {
7+
"Statement": [
8+
{
9+
"Action": "sts:AssumeRole",
10+
"Effect": "Allow",
11+
"Principal": {
12+
"Service": "lambda.amazonaws.com"
13+
}
14+
}
15+
],
16+
"Version": "2012-10-17"
17+
},
18+
"Tags": [
19+
{
20+
"Key": "aws-cdk:id",
21+
"Value": "KeyPrincipalStack_c85d3058e02f077dbb6fd93c359ae2c9117aa61d16"
22+
}
23+
]
24+
}
25+
},
26+
"RoleDefaultPolicy5FFB7DAB": {
27+
"Type": "AWS::IAM::Policy",
28+
"Properties": {
29+
"PolicyDocument": {
30+
"Statement": [
31+
{
32+
"Action": "kms:Decrypt",
33+
"Effect": "Allow",
34+
"Resource": "*"
35+
}
36+
],
37+
"Version": "2012-10-17"
38+
},
39+
"PolicyName": "RoleDefaultPolicy5FFB7DAB",
40+
"Roles": [
41+
{
42+
"Ref": "Role1ABCC5F0"
43+
}
44+
]
45+
}
46+
}
47+
},
48+
"Parameters": {
49+
"BootstrapVersion": {
50+
"Type": "AWS::SSM::Parameter::Value<String>",
51+
"Default": "/cdk-bootstrap/hnb659fds/version",
52+
"Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]"
53+
}
54+
},
55+
"Rules": {
56+
"CheckBootstrapVersion": {
57+
"Assertions": [
58+
{
59+
"Assert": {
60+
"Fn::Not": [
61+
{
62+
"Fn::Contains": [
63+
[
64+
"1",
65+
"2",
66+
"3",
67+
"4",
68+
"5"
69+
],
70+
{
71+
"Ref": "BootstrapVersion"
72+
}
73+
]
74+
}
75+
]
76+
},
77+
"AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI."
78+
}
79+
]
80+
}
81+
}
82+
}

packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-cross-account-grant.js.snapshot/KeyResourceStack.assets.json

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk-testing/framework-integ/test/aws-kms/test/integ.key-cross-account-grant.js.snapshot/KeyResourceStack.metadata.json

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)