Skip to content

Commit d5050ce

Browse files
authored
fix(secretsmanager): fix cross-region policy arn for imported secrets (#26813)
Pre 2.89.0 we could import a secret from a complete secret arn in one stack and reference this secret from another stack in a different region to include it in a policy/role through grantRead on the secret construct. Since 2.89.0 the arn in the policy it treats the compledSecretArn as a partial arn adding -?????? which makes the policy invalid and not allowing access to the secret as intended. This PR fixes that by overriding arnForPolicies for imported secrets to either return provided complete arn or partial arn with suffix. Fixes #26811. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 9b93635 commit d5050ce

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

packages/aws-cdk-lib/aws-secretsmanager/lib/secret.ts

+2
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,8 @@ export class Secret extends SecretBase {
601601
public readonly secretName = parseSecretName(scope, secretArn);
602602
protected readonly autoCreatePolicy = false;
603603
public get secretFullArn() { return secretArnIsPartial ? undefined : secretArn; }
604+
protected get arnForPolicies() { return secretArnIsPartial ? `${secretArn}-??????` : secretArn; }
605+
604606
}(scope, id, { environmentFromArn: secretArn });
605607
}
606608

packages/aws-cdk-lib/aws-secretsmanager/test/secret.test.ts

+56
Original file line numberDiff line numberDiff line change
@@ -1390,3 +1390,59 @@ test('cross-environment grant with direct object reference', () => {
13901390
});
13911391

13921392
});
1393+
1394+
test('cross-environment grant with imported from completeArn', () => {
1395+
// GIVEN
1396+
const secretCompleteArn = 'arn:aws:secretsmanager:foobar:1111111111:secret:secret-name-suffix';
1397+
const producerStack = new cdk.Stack(app, 'ProducerStack', { env: { region: 'foo', account: '1111111111' } });
1398+
const consumerStack = new cdk.Stack(app, 'ConsumerStack', { env: { region: 'bar', account: '1111111111' } });
1399+
const secret = secretsmanager.Secret.fromSecretCompleteArn(producerStack, 'Secret', secretCompleteArn);
1400+
const role = new iam.Role(consumerStack, 'Role', { assumedBy: new iam.AccountRootPrincipal() });
1401+
1402+
// WHEN
1403+
secret.grantRead(role);
1404+
1405+
// THEN
1406+
Template.fromStack(consumerStack).hasResourceProperties('AWS::IAM::Policy', {
1407+
PolicyDocument: {
1408+
Version: '2012-10-17',
1409+
Statement: [{
1410+
Action: [
1411+
'secretsmanager:GetSecretValue',
1412+
'secretsmanager:DescribeSecret',
1413+
],
1414+
Effect: 'Allow',
1415+
Resource: secretCompleteArn,
1416+
}],
1417+
},
1418+
});
1419+
1420+
});
1421+
1422+
test('cross-environment grant with imported from partialArn', () => {
1423+
// GIVEN
1424+
const secretPartialArn = 'arn:aws:secretsmanager:foobar:1111111111:secret:secret-name';
1425+
const producerStack = new cdk.Stack(app, 'ProducerStack', { env: { region: 'foo', account: '1111111111' } });
1426+
const consumerStack = new cdk.Stack(app, 'ConsumerStack', { env: { region: 'bar', account: '1111111111' } });
1427+
const secret = secretsmanager.Secret.fromSecretPartialArn(producerStack, 'Secret', secretPartialArn);
1428+
const role = new iam.Role(consumerStack, 'Role', { assumedBy: new iam.AccountRootPrincipal() });
1429+
1430+
// WHEN
1431+
secret.grantRead(role);
1432+
1433+
// THEN
1434+
Template.fromStack(consumerStack).hasResourceProperties('AWS::IAM::Policy', {
1435+
PolicyDocument: {
1436+
Version: '2012-10-17',
1437+
Statement: [{
1438+
Action: [
1439+
'secretsmanager:GetSecretValue',
1440+
'secretsmanager:DescribeSecret',
1441+
],
1442+
Effect: 'Allow',
1443+
Resource: `${secretPartialArn}-??????`,
1444+
}],
1445+
},
1446+
});
1447+
1448+
});

0 commit comments

Comments
 (0)