Skip to content

Commit

Permalink
chore(iam): support addSourceAccountCondition and addSourceArnConditi…
Browse files Browse the repository at this point in the history
…on (#25744)

The [addAccountCondition](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html#addwbraccountwbrconditionaccountid) method essentially create a `StringEquals` condition with `sts:ExternalId` which is used for [Cross-account confused deputy prevention](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html#mitigate-confused-deputy). This PR adds `addSourceArnCondition` and `addSourceAccountCondition` methods used for [Cross-service confused deputy prevention](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html#cross-service-confused-deputy-prevention) and improves the doc on the methods.

Closes #25732

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
pahud authored May 26, 2023
1 parent d19646b commit a5f7655
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 1 deletion.
7 changes: 7 additions & 0 deletions packages/aws-cdk-lib/aws-iam/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,13 @@ an `ExternalId` works like this:

[supplying an external ID](test/example.external-id.lit.ts)

## SourceArn and SourceAccount

If you need to create resource policies using `aws:SourceArn` and `aws:SourceAccount` for cross-service resource access,
use `addSourceArnCondition` and `addSourceAccountCondition` to create the conditions.

See [Cross-service confused deputy prevention for more details](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html#cross-service-confused-deputy-prevention).

## Principals vs Identities

When we say *Principal*, we mean an entity you grant permissions to. This
Expand Down
26 changes: 25 additions & 1 deletion packages/aws-cdk-lib/aws-iam/lib/policy-statement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -402,14 +402,38 @@ export class PolicyStatement {
}

/**
* Add a condition that limits to a given account
* Add a `StringEquals` condition that limits to a given account from `sts:ExternalId`.
*
* This method can only be called once: subsequent calls will overwrite earlier calls.
*
* @see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user_externalid.html
*/
public addAccountCondition(accountId: string) {
this.addCondition('StringEquals', { 'sts:ExternalId': accountId });
}

/**
* Add an `StringEquals` condition that limits to a given account from `aws:SourceAccount`.
*
* This method can only be called once: subsequent calls will overwrite earlier calls.
*
* @see https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount
*/
public addSourceAccountCondition(accountId: string) {
this.addCondition('StringEquals', { 'aws:SourceAccount': accountId });
}

/**
* Add an `ArnEquals` condition that limits to a given resource arn from `aws:SourceArn`.
*
* This method can only be called once: subsequent calls will overwrite earlier calls.
*
* @see https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn
*/
public addSourceArnCondition(arn: string) {
this.addCondition('ArnEquals', { 'aws:SourceArn': arn });
}

/**
* Create a new `PolicyStatement` with the same exact properties
* as this one, except for the overrides
Expand Down
23 changes: 23 additions & 0 deletions packages/aws-cdk-lib/aws-iam/test/policy-document.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,29 @@ describe('IAM policy document', () => {
});
});

test('addSourceAccountCondition and addSourceArnCondition for cross-service resource access', () => {
const stack = new Stack();

const p = new PolicyStatement();
p.addActions('sns:Publish');
p.addResources('myTopic');
p.addAllResources();
p.addServicePrincipal('s3.amazonaws.com');
p.addSourceAccountCondition('12221121221');
p.addSourceArnCondition('bucketArn');

expect(stack.resolve(p.toStatementJson())).toEqual({
Action: 'sns:Publish',
Resource: ['myTopic', '*'],
Effect: 'Allow',
Principal: { Service: 's3.amazonaws.com' },
Condition: {
StringEquals: { 'aws:SourceAccount': '12221121221' },
ArnEquals: { 'aws:SourceArn': 'bucketArn' },
},
});
});

test('the PolicyDocument class is a dom for iam policy documents', () => {
const stack = new Stack();
const doc = new PolicyDocument();
Expand Down

0 comments on commit a5f7655

Please sign in to comment.