From 2b894b9494bfc74451ee52439f08525173f76acc Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Thu, 16 Dec 2021 11:30:00 +0100 Subject: [PATCH] feat(iam): session tagging (#17689) To allow session tagging, the `sts:TagSession` permission needs to be added to the role's AssumeRolePolicyDocument. Introduce a new principal which enables this, and add a convenience method `.withSessionTags()` to the `PrincipalBase` class so all built-in principals will have this convenience method by default. To build this, we had to get rid of some cruft and assumptions around policy documents and statements, and defer more power to the `IPrincipal` objects themselves. In order not to break existing implementors, introduce a new interface `IAssumeRolePrincipal` which knows how to add itself to an AssumeRolePolicyDocument and gets complete freedom doing so. That same new interface could be used to lift some old limitations on `CompositePrincipal` so did that as well. Fixes #15908, closes #16725, fixes #2041, fixes #1578. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../fargate/integ.executionrole.expected.json | 12 +- packages/@aws-cdk/aws-iam/README.md | 28 +++- packages/@aws-cdk/aws-iam/lib/principals.ts | 148 +++++++++++++----- .../aws-iam/lib/private/assume-role-policy.ts | 25 +++ .../aws-iam/lib/private/policydoc-adapter.ts | 17 ++ packages/@aws-cdk/aws-iam/lib/role.ts | 42 ++--- .../integ.composite-principal.expected.json | 8 +- .../aws-iam/test/policy-document.test.ts | 76 +++++++-- .../@aws-cdk/aws-iam/test/principals.test.ts | 32 ++++ packages/@aws-cdk/aws-iam/test/role.test.ts | 6 + .../@aws-cdk/aws-lambda/lib/function-base.ts | 6 +- ...nteg.job-submission-workflow.expected.json | 70 +++++---- .../integ.start-job-run.expected.json | 88 ++++++----- .../pipelines/test/compliance/assets.test.ts | 56 ++++--- .../integ.newpipeline-with-vpc.expected.json | 8 +- ...ne-with-assets-single-upload.expected.json | 8 +- .../integ.pipeline-with-assets.expected.json | 8 +- 17 files changed, 452 insertions(+), 186 deletions(-) create mode 100644 packages/@aws-cdk/aws-iam/lib/private/assume-role-policy.ts create mode 100644 packages/@aws-cdk/aws-iam/lib/private/policydoc-adapter.ts diff --git a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.executionrole.expected.json b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.executionrole.expected.json index 6d2654abe539c..dc83169a668a9 100644 --- a/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.executionrole.expected.json +++ b/packages/@aws-cdk/aws-ecs-patterns/test/fargate/integ.executionrole.expected.json @@ -367,10 +367,14 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": [ - "ecs.amazonaws.com", - "ecs-tasks.amazonaws.com" - ] + "Service": "ecs.amazonaws.com" + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "ecs-tasks.amazonaws.com" } } ], diff --git a/packages/@aws-cdk/aws-iam/README.md b/packages/@aws-cdk/aws-iam/README.md index 66d720ba8a708..438b54693b5b5 100644 --- a/packages/@aws-cdk/aws-iam/README.md +++ b/packages/@aws-cdk/aws-iam/README.md @@ -209,13 +209,31 @@ The `WebIdentityPrincipal` class can be used as a principal for web identities l Cognito, Amazon, Google or Facebook, for example: ```ts -const principal = new iam.WebIdentityPrincipal('cognito-identity.amazonaws.com') - .withConditions({ - "StringEquals": { "cognito-identity.amazonaws.com:aud": "us-east-2:12345678-abcd-abcd-abcd-123456" }, - "ForAnyValue:StringLike": {"cognito-identity.amazonaws.com:amr": "unauthenticated" }, - }); +const principal = new iam.WebIdentityPrincipal('cognito-identity.amazonaws.com', { + 'StringEquals': { 'cognito-identity.amazonaws.com:aud': 'us-east-2:12345678-abcd-abcd-abcd-123456' }, + 'ForAnyValue:StringLike': {'cognito-identity.amazonaws.com:amr': 'unauthenticated' }, +}); ``` +If your identity provider is configured to assume a Role with [session +tags](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html), you +need to call `.withSessionTags()` to add the required permissions to the Role's +policy document: + +```ts +new iam.Role(this, 'Role', { + assumedBy: new iam.WebIdentityPrincipal('cognito-identity.amazonaws.com', { + 'StringEquals': { + 'cognito-identity.amazonaws.com:aud': 'us-east-2:12345678-abcd-abcd-abcd-123456', + }, + 'ForAnyValue:StringLike': { + 'cognito-identity.amazonaws.com:amr': 'unauthenticated', + }, + }).withSessionTags(), +}); +``` + + ## Parsing JSON Policy Documents The `PolicyDocument.fromJson` and `PolicyStatement.fromJson` static methods can be used to parse JSON objects. For example: diff --git a/packages/@aws-cdk/aws-iam/lib/principals.ts b/packages/@aws-cdk/aws-iam/lib/principals.ts index 5a3abd6c0a76d..aecd493192142 100644 --- a/packages/@aws-cdk/aws-iam/lib/principals.ts +++ b/packages/@aws-cdk/aws-iam/lib/principals.ts @@ -1,7 +1,9 @@ import * as cdk from '@aws-cdk/core'; import { Default, FactName, RegionInfo } from '@aws-cdk/region-info'; import { IOpenIdConnectProvider } from './oidc-provider'; +import { PolicyDocument } from './policy-document'; import { Condition, Conditions, PolicyStatement } from './policy-statement'; +import { defaultAddPrincipalToAssumeRole } from './private/assume-role-policy'; import { ISamlProvider } from './saml-provider'; import { LITERAL_STRING_KEY, mergePrincipal } from './util'; @@ -68,6 +70,25 @@ export interface IPrincipal extends IGrantable { addToPrincipalPolicy(statement: PolicyStatement): AddToPrincipalPolicyResult; } +/** + * A type of principal that has more control over its own representation in AssumeRolePolicyDocuments + * + * More complex types of identity providers need more control over Role's policy documents + * than simply `{ Effect: 'Allow', Action: 'AssumeRole', Principal: }`. + * + * If that control is necessary, they can implement `IAssumeRolePrincipal` to get full + * access to a Role's AssumeRolePolicyDocument. + */ +export interface IAssumeRolePrincipal extends IPrincipal { + /** + * Add the princpial to the AssumeRolePolicyDocument + * + * Add the statements to the AssumeRolePolicyDocument necessary to give this principal + * permissions to assume the given role. + */ + addToAssumeRolePolicy(document: PolicyDocument): void; +} + /** * Result of calling `addToPrincipalPolicy` */ @@ -89,7 +110,7 @@ export interface AddToPrincipalPolicyResult { /** * Base class for policy principals */ -export abstract class PrincipalBase implements IPrincipal { +export abstract class PrincipalBase implements IAssumeRolePrincipal { public readonly grantPrincipal: IPrincipal = this; public readonly principalAccount: string | undefined = undefined; @@ -113,6 +134,14 @@ export abstract class PrincipalBase implements IPrincipal { return { statementAdded: false }; } + public addToAssumeRolePolicy(document: PolicyDocument): void { + // Default implementation of this protocol, compatible with the legacy behavior + document.addStatements(new PolicyStatement({ + actions: [this.assumeRoleAction], + principals: [this], + })); + } + public toString() { // This is a first pass to make the object readable. Descendant principals // should return something nicer. @@ -138,9 +167,39 @@ export abstract class PrincipalBase implements IPrincipal { * * @returns a new PrincipalWithConditions object. */ - public withConditions(conditions: Conditions): IPrincipal { + public withConditions(conditions: Conditions): PrincipalBase { return new PrincipalWithConditions(this, conditions); } + + /** + * Returns a new principal using this principal as the base, with session tags enabled. + * + * @returns a new SessionTagsPrincipal object. + */ + public withSessionTags(): PrincipalBase { + return new SessionTagsPrincipal(this); + } +} + +/** + * Base class for Principals that wrap other principals + */ +class PrincipalAdapter extends PrincipalBase { + public readonly assumeRoleAction = this.wrapped.assumeRoleAction; + public readonly principalAccount = this.wrapped.principalAccount; + + constructor(protected readonly wrapped: IPrincipal) { + super(); + } + + public get policyFragment(): PrincipalPolicyFragment { return this.wrapped.policyFragment; } + + addToPolicy(statement: PolicyStatement): boolean { + return this.wrapped.addToPolicy(statement); + } + addToPrincipalPolicy(statement: PolicyStatement): AddToPrincipalPolicyResult { + return this.wrapped.addToPrincipalPolicy(statement); + } } /** @@ -149,15 +208,11 @@ export abstract class PrincipalBase implements IPrincipal { * For more information about conditions, see: * https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html */ -export class PrincipalWithConditions implements IPrincipal { - public readonly grantPrincipal: IPrincipal = this; - public readonly assumeRoleAction: string = this.principal.assumeRoleAction; +export class PrincipalWithConditions extends PrincipalAdapter { private additionalConditions: Conditions; - constructor( - private readonly principal: IPrincipal, - conditions: Conditions, - ) { + constructor(principal: IPrincipal, conditions: Conditions) { + super(principal); this.additionalConditions = conditions; } @@ -186,27 +241,15 @@ export class PrincipalWithConditions implements IPrincipal { * See [the IAM documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html). */ public get conditions() { - return this.mergeConditions(this.principal.policyFragment.conditions, this.additionalConditions); + return this.mergeConditions(this.wrapped.policyFragment.conditions, this.additionalConditions); } public get policyFragment(): PrincipalPolicyFragment { - return new PrincipalPolicyFragment(this.principal.policyFragment.principalJson, this.conditions); - } - - public get principalAccount(): string | undefined { - return this.principal.principalAccount; - } - - public addToPolicy(statement: PolicyStatement): boolean { - return this.addToPrincipalPolicy(statement).statementAdded; - } - - public addToPrincipalPolicy(statement: PolicyStatement): AddToPrincipalPolicyResult { - return this.principal.addToPrincipalPolicy(statement); + return new PrincipalPolicyFragment(this.wrapped.policyFragment.principalJson, this.conditions); } public toString() { - return this.principal.toString(); + return this.wrapped.toString(); } /** @@ -247,6 +290,30 @@ export class PrincipalWithConditions implements IPrincipal { } } +/** + * Enables session tags on role assumptions from a principal + * + * For more information on session tags, see: + * https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html + */ +export class SessionTagsPrincipal extends PrincipalAdapter { + constructor(principal: IPrincipal) { + super(principal); + } + + public addToAssumeRolePolicy(doc: PolicyDocument) { + // Lazy import to avoid circular import dependencies during startup + + // eslint-disable-next-line @typescript-eslint/no-require-imports + const adapter: typeof import('./private/policydoc-adapter') = require('./private/policydoc-adapter'); + + defaultAddPrincipalToAssumeRole(this.wrapped, new adapter.MutatingPolicyDocumentAdapter(doc, (statement) => { + statement.addActions('sts:TagSession'); + return statement; + })); + } +} + /** * A collection of the fields in a PolicyStatement that can be used to identify a principal. * @@ -441,6 +508,7 @@ export class FederatedPrincipal extends PrincipalBase { * @param federated federated identity provider (i.e. 'cognito-identity.amazonaws.com' for users authenticated through Cognito) * @param conditions The conditions under which the policy is in effect. * See [the IAM documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html). + * @param sessionTags Whether to enable session tagging (see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html) */ constructor( public readonly federated: string, @@ -471,6 +539,7 @@ export class WebIdentityPrincipal extends FederatedPrincipal { * @param identityProvider identity provider (i.e. 'cognito-identity.amazonaws.com' for users authenticated through Cognito) * @param conditions The conditions under which the policy is in effect. * See [the IAM documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html). + * @param sessionTags Whether to enable session tagging (see https://docs.aws.amazon.com/IAM/latest/UserGuide/id_session-tags.html) */ constructor(identityProvider: string, conditions: Conditions = {}) { super(identityProvider, conditions ?? {}, 'sts:AssumeRoleWithWebIdentity'); @@ -606,9 +675,9 @@ export class StarPrincipal extends PrincipalBase { */ export class CompositePrincipal extends PrincipalBase { public readonly assumeRoleAction: string; - private readonly principals = new Array(); + private readonly principals = new Array(); - constructor(...principals: PrincipalBase[]) { + constructor(...principals: IPrincipal[]) { super(); if (principals.length === 0) { throw new Error('CompositePrincipals must be constructed with at least 1 Principal but none were passed.'); @@ -623,28 +692,29 @@ export class CompositePrincipal extends PrincipalBase { * * @param principals IAM principals that will be added to the composite principal */ - public addPrincipals(...principals: PrincipalBase[]): this { - for (const p of principals) { - if (p.assumeRoleAction !== this.assumeRoleAction) { - throw new Error( - 'Cannot add multiple principals with different "assumeRoleAction". ' + - `Expecting "${this.assumeRoleAction}", got "${p.assumeRoleAction}"`); - } + public addPrincipals(...principals: IPrincipal[]): this { + this.principals.push(...principals); + return this; + } + + public addToAssumeRolePolicy(doc: PolicyDocument) { + for (const p of this.principals) { + defaultAddPrincipalToAssumeRole(p, doc); + } + } + public get policyFragment(): PrincipalPolicyFragment { + // We only have a problem with conditions if we are trying to render composite + // princpals into a single statement (which is when `policyFragment` would get called) + for (const p of this.principals) { const fragment = p.policyFragment; if (fragment.conditions && Object.keys(fragment.conditions).length > 0) { throw new Error( 'Components of a CompositePrincipal must not have conditions. ' + `Tried to add the following fragment: ${JSON.stringify(fragment)}`); } - - this.principals.push(p); } - return this; - } - - public get policyFragment(): PrincipalPolicyFragment { const principalJson: { [key: string]: string[] } = {}; for (const p of this.principals) { diff --git a/packages/@aws-cdk/aws-iam/lib/private/assume-role-policy.ts b/packages/@aws-cdk/aws-iam/lib/private/assume-role-policy.ts new file mode 100644 index 0000000000000..9a2a474fcb2d4 --- /dev/null +++ b/packages/@aws-cdk/aws-iam/lib/private/assume-role-policy.ts @@ -0,0 +1,25 @@ +import { PolicyDocument } from '../policy-document'; +import { PolicyStatement } from '../policy-statement'; +import { IPrincipal, IAssumeRolePrincipal } from '../principals'; + +/** + * Add a principal to an AssumeRolePolicyDocument in the right way + * + * Delegate to the principal if it can do the job itself, do a default job if it can't. + */ +export function defaultAddPrincipalToAssumeRole(principal: IPrincipal, doc: PolicyDocument) { + if (isAssumeRolePrincipal(principal)) { + // Principal knows how to add itself + principal.addToAssumeRolePolicy(doc); + } else { + // Principal can't add itself, we do it for them + doc.addStatements(new PolicyStatement({ + actions: [principal.assumeRoleAction], + principals: [principal], + })); + } +} + +function isAssumeRolePrincipal(principal: IPrincipal): principal is IAssumeRolePrincipal { + return !!(principal as IAssumeRolePrincipal).addToAssumeRolePolicy; +} diff --git a/packages/@aws-cdk/aws-iam/lib/private/policydoc-adapter.ts b/packages/@aws-cdk/aws-iam/lib/private/policydoc-adapter.ts new file mode 100644 index 0000000000000..c6f95631ea495 --- /dev/null +++ b/packages/@aws-cdk/aws-iam/lib/private/policydoc-adapter.ts @@ -0,0 +1,17 @@ +import { PolicyDocument } from '../policy-document'; +import { PolicyStatement } from '../policy-statement'; + +/** + * A PolicyDocument adapter that can modify statements flowing through it + */ +export class MutatingPolicyDocumentAdapter extends PolicyDocument { + constructor(private readonly wrapped: PolicyDocument, private readonly mutator: (s: PolicyStatement) => PolicyStatement) { + super(); + } + + public addStatements(...statements: PolicyStatement[]): void { + for (const st of statements) { + this.wrapped.addStatements(this.mutator(st)); + } + } +} diff --git a/packages/@aws-cdk/aws-iam/lib/role.ts b/packages/@aws-cdk/aws-iam/lib/role.ts index b103b21231e23..ac48fdd3d7710 100644 --- a/packages/@aws-cdk/aws-iam/lib/role.ts +++ b/packages/@aws-cdk/aws-iam/lib/role.ts @@ -8,7 +8,9 @@ import { Policy } from './policy'; import { PolicyDocument } from './policy-document'; import { PolicyStatement } from './policy-statement'; import { AddToPrincipalPolicyResult, ArnPrincipal, IPrincipal, PrincipalPolicyFragment } from './principals'; +import { defaultAddPrincipalToAssumeRole } from './private/assume-role-policy'; import { ImmutableRole } from './private/immutable-role'; +import { MutatingPolicyDocumentAdapter } from './private/policydoc-adapter'; import { AttachedPolicies, UniqueStringSet } from './util'; /** @@ -484,17 +486,21 @@ export interface IRole extends IIdentity { } function createAssumeRolePolicy(principal: IPrincipal, externalIds: string[]) { - const statement = new AwsStarStatement(); - statement.addPrincipals(principal); - statement.addActions(principal.assumeRoleAction); + const actualDoc = new PolicyDocument(); + + // If requested, add externalIds to every statement added to this doc + const addDoc = externalIds.length === 0 + ? actualDoc + : new MutatingPolicyDocumentAdapter(actualDoc, (statement) => { + statement.addCondition('StringEquals', { + 'sts:ExternalId': externalIds.length === 1 ? externalIds[0] : externalIds, + }); + return statement; + }); - if (externalIds.length) { - statement.addCondition('StringEquals', { 'sts:ExternalId': externalIds.length === 1 ? externalIds[0] : externalIds }); - } + defaultAddPrincipalToAssumeRole(principal, addDoc); - const doc = new PolicyDocument(); - doc.addStatements(statement); - return doc; + return actualDoc; } function validateMaxSessionDuration(duration?: number) { @@ -507,24 +513,6 @@ function validateMaxSessionDuration(duration?: number) { } } -/** - * A PolicyStatement that normalizes its Principal field differently - * - * Normally, "anyone" is normalized to "Principal: *", but this statement - * normalizes to "Principal: { AWS: * }". - */ -class AwsStarStatement extends PolicyStatement { - public toStatementJson(): any { - const stat = super.toStatementJson(); - - if (stat.Principal === '*') { - stat.Principal = { AWS: '*' }; - } - - return stat; - } -} - /** * Options for the `withoutPolicyUpdates()` modifier of a Role */ diff --git a/packages/@aws-cdk/aws-iam/test/integ.composite-principal.expected.json b/packages/@aws-cdk/aws-iam/test/integ.composite-principal.expected.json index a715e411d83ae..4090b7be4e15e 100644 --- a/packages/@aws-cdk/aws-iam/test/integ.composite-principal.expected.json +++ b/packages/@aws-cdk/aws-iam/test/integ.composite-principal.expected.json @@ -19,7 +19,13 @@ } ] ] - }, + } + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { "AWS": "*" } } diff --git a/packages/@aws-cdk/aws-iam/test/policy-document.test.ts b/packages/@aws-cdk/aws-iam/test/policy-document.test.ts index ff30531f5fc59..16a9904087647 100644 --- a/packages/@aws-cdk/aws-iam/test/policy-document.test.ts +++ b/packages/@aws-cdk/aws-iam/test/policy-document.test.ts @@ -3,7 +3,7 @@ import { testDeprecated } from '@aws-cdk/cdk-build-tools'; import { Lazy, Stack, Token } from '@aws-cdk/core'; import { AccountPrincipal, Anyone, AnyPrincipal, ArnPrincipal, CanonicalUserPrincipal, CompositePrincipal, - Effect, FederatedPrincipal, IPrincipal, PolicyDocument, PolicyStatement, PrincipalPolicyFragment, ServicePrincipal, + Effect, FederatedPrincipal, IPrincipal, PolicyDocument, PolicyStatement, PrincipalPolicyFragment, ServicePrincipal, Role, } from '../lib'; describe('IAM policy document', () => { @@ -483,10 +483,46 @@ describe('IAM policy document', () => { expect(stack.resolve(statement.toStatementJson())).toEqual({ Effect: 'Allow', Principal: { AWS: 'i:am:an:arn' } }); }); - test('conditions are not allowed on individual principals of a composite', () => { - const p = new CompositePrincipal(new ArnPrincipal('i:am')); - expect(() => p.addPrincipals(new FederatedPrincipal('federated', { StringEquals: { 'aws:some-key': 'some-value' } }))) - .toThrow(/Components of a CompositePrincipal must not have conditions/); + test('conditions are allowed in an assumerolepolicydocument', () => { + const stack = new Stack(); + new Role(stack, 'Role', { + assumedBy: new CompositePrincipal( + new ArnPrincipal('i:am'), + new FederatedPrincipal('federated', { StringEquals: { 'aws:some-key': 'some-value' } }), + ), + }); + + expect(stack).toHaveResourceLike('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { AWS: 'i:am' }, + }, + { + Action: 'sts:AssumeRole', + Condition: { + StringEquals: { 'aws:some-key': 'some-value' }, + }, + Effect: 'Allow', + Principal: { Federated: 'federated' }, + }, + ], + }, + }); + }); + + test('conditions are not allowed when used in a single statement', () => { + + expect(() => { + new PolicyStatement({ + actions: ['s3:test'], + principals: [new CompositePrincipal( + new ArnPrincipal('i:am'), + new FederatedPrincipal('federated', { StringEquals: { 'aws:some-key': 'some-value' } }))], + }); + }).toThrow(/Components of a CompositePrincipal must not have conditions/); }); test('principals and conditions are a big nice merge', () => { @@ -521,13 +557,33 @@ describe('IAM policy document', () => { }); }); - test('cannot mix types of assumeRoleAction in a single composite', () => { - // GIVEN - const p = new CompositePrincipal(new ArnPrincipal('arn')); // assumeRoleAction is "sts:AssumeRule" + test('can mix types of assumeRoleAction in a single composite', () => { + const stack = new Stack(); + + // WHEN + new Role(stack, 'Role', { + assumedBy: new CompositePrincipal( + new ArnPrincipal('arn'), + new FederatedPrincipal('fed', {}, 'sts:Boom')), + }); // THEN - expect(() => p.addPrincipals(new FederatedPrincipal('fed', {}, 'sts:Boom'))) - .toThrow(/Cannot add multiple principals with different "assumeRoleAction". Expecting "sts:AssumeRole", got "sts:Boom"/); + expect(stack).toHaveResourceLike('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { AWS: 'arn' }, + }, + { + Action: 'sts:Boom', + Effect: 'Allow', + Principal: { Federated: 'fed' }, + }, + ], + }, + }); }); }); diff --git a/packages/@aws-cdk/aws-iam/test/principals.test.ts b/packages/@aws-cdk/aws-iam/test/principals.test.ts index 18dc72f4d760b..fdbeaa0dc87d4 100644 --- a/packages/@aws-cdk/aws-iam/test/principals.test.ts +++ b/packages/@aws-cdk/aws-iam/test/principals.test.ts @@ -260,4 +260,36 @@ test('ServicePrincipal in agnostic stack generates lookup table', () => { const mappings = template.findMappings('ServiceprincipalMap'); expect(mappings.ServiceprincipalMap['af-south-1']?.ssm).toEqual('ssm.af-south-1.amazonaws.com'); expect(mappings.ServiceprincipalMap['us-east-1']?.ssm).toEqual('ssm.amazonaws.com'); +}); + +test('Can enable session tags', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new iam.Role(stack, 'Role', { + assumedBy: new iam.WebIdentityPrincipal( + 'cognito-identity.amazonaws.com', + { + 'StringEquals': { 'cognito-identity.amazonaws.com:aud': 'asdf' }, + 'ForAnyValue:StringLike': { 'cognito-identity.amazonaws.com:amr': 'authenticated' }, + }).withSessionTags(), + }); + + // THEN + expect(stack).toHaveResourceLike('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: ['sts:AssumeRoleWithWebIdentity', 'sts:TagSession'], + Condition: { + 'StringEquals': { 'cognito-identity.amazonaws.com:aud': 'asdf' }, + 'ForAnyValue:StringLike': { 'cognito-identity.amazonaws.com:amr': 'authenticated' }, + }, + Effect: 'Allow', + Principal: { Federated: 'cognito-identity.amazonaws.com' }, + }, + ], + }, + }); }); \ No newline at end of file diff --git a/packages/@aws-cdk/aws-iam/test/role.test.ts b/packages/@aws-cdk/aws-iam/test/role.test.ts index f251f8388a6d2..ffa1ccd305c58 100644 --- a/packages/@aws-cdk/aws-iam/test/role.test.ts +++ b/packages/@aws-cdk/aws-iam/test/role.test.ts @@ -309,6 +309,12 @@ describe('IAM role', () => { Effect: 'Allow', Principal: { Service: 'boom.amazonaws.test', + }, + }, + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { AWS: '1111111', }, }, diff --git a/packages/@aws-cdk/aws-lambda/lib/function-base.ts b/packages/@aws-cdk/aws-lambda/lib/function-base.ts index a0953b93d1a85..d1aaa17c38072 100644 --- a/packages/@aws-cdk/aws-lambda/lib/function-base.ts +++ b/packages/@aws-cdk/aws-lambda/lib/function-base.ts @@ -255,6 +255,8 @@ export abstract class FunctionBase extends Resource implements IFunction, ec2.IC return; } + // eslint-disable-next-line no-console + console.log(permission); const principal = this.parsePermissionPrincipal(permission.principal); const { sourceAccount, sourceArn } = this.parseConditions(permission.principal) ?? {}; const action = permission.action ?? 'lambda:InvokeFunction'; @@ -418,9 +420,9 @@ export abstract class FunctionBase extends Resource implements IFunction, ec2.IC // Try some specific common classes first. // use duck-typing, not instance of // @deprecated: after v2, we can change these to 'instanceof' - if ('conditions' in principal) { + if ('wrapped' in principal) { // eslint-disable-next-line dot-notation - principal = principal['principal']; + principal = principal['wrapped']; } if ('accountId' in principal) { diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.job-submission-workflow.expected.json b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.job-submission-workflow.expected.json index a3b99bf3fb6ed..ec1551086d626 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.job-submission-workflow.expected.json +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.job-submission-workflow.expected.json @@ -1127,7 +1127,7 @@ }, "/", { - "Ref": "AssetParameters8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945S3BucketC636D050" + "Ref": "AssetParameters5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81S3BucketD82D4551" }, "/", { @@ -1137,7 +1137,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945S3VersionKey40C5ADFE" + "Ref": "AssetParameters5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81S3VersionKey897D64BB" } ] } @@ -1150,7 +1150,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945S3VersionKey40C5ADFE" + "Ref": "AssetParameters5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81S3VersionKey897D64BB" } ] } @@ -1172,11 +1172,11 @@ "Arn" ] }, - "referencetoawsstepfunctionstasksemrcontainersallservicesintegAssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3Bucket42FF7F94Ref": { - "Ref": "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3Bucket3B443230" + "referencetoawsstepfunctionstasksemrcontainersallservicesintegAssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3Bucket1AC4E28ARef": { + "Ref": "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3Bucket9AE1EC0F" }, - "referencetoawsstepfunctionstasksemrcontainersallservicesintegAssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3VersionKeyD44C8135Ref": { - "Ref": "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3VersionKeyAA4674FB" + "referencetoawsstepfunctionstasksemrcontainersallservicesintegAssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3VersionKeyEFDBE51DRef": { + "Ref": "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3VersionKey451EAA56" }, "referencetoawsstepfunctionstasksemrcontainersallservicesintegAssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3Bucket5978B8B5Ref": { "Ref": "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1" @@ -1304,21 +1304,25 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": [ - "emr-containers.amazonaws.com", - { - "Fn::Join": [ - "", - [ - "states.", - { - "Ref": "AWS::Region" - }, - ".amazonaws.com" - ] + "Service": "emr-containers.amazonaws.com" + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "states.", + { + "Ref": "AWS::Region" + }, + ".amazonaws.com" ] - } - ] + ] + } } } ], @@ -1721,17 +1725,17 @@ "Type": "String", "Description": "Artifact hash for asset \"26ac61b4195cccf80ff73f332788ad7ffaab36d81ce570340a583a8364901665\"" }, - "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3Bucket3B443230": { + "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3Bucket9AE1EC0F": { "Type": "String", - "Description": "S3 bucket for asset \"5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720\"" + "Description": "S3 bucket for asset \"00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5af\"" }, - "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3VersionKeyAA4674FB": { + "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3VersionKey451EAA56": { "Type": "String", - "Description": "S3 key for asset version \"5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720\"" + "Description": "S3 key for asset version \"00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5af\"" }, - "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720ArtifactHash3D7A279D": { + "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afArtifactHash761F4689": { "Type": "String", - "Description": "Artifact hash for asset \"5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720\"" + "Description": "Artifact hash for asset \"00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5af\"" }, "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1": { "Type": "String", @@ -1781,17 +1785,17 @@ "Type": "String", "Description": "Artifact hash for asset \"ea17febe6d04c66048f3e8e060c71685c0cb53122abceff44842d27bc0d4a03e\"" }, - "AssetParameters8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945S3BucketC636D050": { + "AssetParameters5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81S3BucketD82D4551": { "Type": "String", - "Description": "S3 bucket for asset \"8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945\"" + "Description": "S3 bucket for asset \"5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81\"" }, - "AssetParameters8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945S3VersionKey40C5ADFE": { + "AssetParameters5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81S3VersionKey897D64BB": { "Type": "String", - "Description": "S3 key for asset version \"8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945\"" + "Description": "S3 key for asset version \"5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81\"" }, - "AssetParameters8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945ArtifactHash89120E1C": { + "AssetParameters5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81ArtifactHash8B07F4C4": { "Type": "String", - "Description": "Artifact hash for asset \"8d0ccbee43ce642958da8926fed939a9fde9d6631e9297740d640c0859ca5945\"" + "Description": "Artifact hash for asset \"5ec12699a2590c6c682ce53d895ebfe56ed437e75e4f28b0b1aebe2941d96f81\"" }, "AssetParameters249207c004483eea61658aceb796afc5f7a8b39d3b2333951c04ac8787af6d50S3BucketDBE4A868": { "Type": "String", diff --git a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.start-job-run.expected.json b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.start-job-run.expected.json index 3ec75b7ba0384..1cd5ed999f0b5 100644 --- a/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.start-job-run.expected.json +++ b/packages/@aws-cdk/aws-stepfunctions-tasks/test/emrcontainers/integ.start-job-run.expected.json @@ -1186,7 +1186,7 @@ }, "/", { - "Ref": "AssetParameters3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591S3BucketC38C4355" + "Ref": "AssetParameters8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35S3Bucket37C1382F" }, "/", { @@ -1196,7 +1196,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591S3VersionKey31FFCA42" + "Ref": "AssetParameters8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35S3VersionKey5D044A85" } ] } @@ -1209,7 +1209,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591S3VersionKey31FFCA42" + "Ref": "AssetParameters8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35S3VersionKey5D044A85" } ] } @@ -1231,11 +1231,11 @@ "Arn" ] }, - "referencetoawsstepfunctionstasksemrcontainersstartjobrunintegtestAssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3Bucket7AE1E7DBRef": { - "Ref": "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3Bucket3B443230" + "referencetoawsstepfunctionstasksemrcontainersstartjobrunintegtestAssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3Bucket90E6B403Ref": { + "Ref": "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3Bucket9AE1EC0F" }, - "referencetoawsstepfunctionstasksemrcontainersstartjobrunintegtestAssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3VersionKey5842C10ARef": { - "Ref": "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3VersionKeyAA4674FB" + "referencetoawsstepfunctionstasksemrcontainersstartjobrunintegtestAssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3VersionKeyAD902FD9Ref": { + "Ref": "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3VersionKey451EAA56" }, "referencetoawsstepfunctionstasksemrcontainersstartjobrunintegtestAssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3Bucket977A6FD0Ref": { "Ref": "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1" @@ -1384,21 +1384,25 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": [ - "emr-containers.amazonaws.com", - { - "Fn::Join": [ - "", - [ - "states.", - { - "Ref": "AWS::Region" - }, - ".amazonaws.com" - ] + "Service": "emr-containers.amazonaws.com" + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": { + "Fn::Join": [ + "", + [ + "states.", + { + "Ref": "AWS::Region" + }, + ".amazonaws.com" ] - } - ] + ] + } } } ], @@ -1712,7 +1716,7 @@ "Properties": { "Code": { "S3Bucket": { - "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E" + "Ref": "AssetParameters3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87S3Bucket36F31A16" }, "S3Key": { "Fn::Join": [ @@ -1725,7 +1729,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" + "Ref": "AssetParameters3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87S3VersionKeyF80D542B" } ] } @@ -1738,7 +1742,7 @@ "Fn::Split": [ "||", { - "Ref": "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632" + "Ref": "AssetParameters3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87S3VersionKeyF80D542B" } ] } @@ -2142,17 +2146,17 @@ "Type": "String", "Description": "Artifact hash for asset \"26ac61b4195cccf80ff73f332788ad7ffaab36d81ce570340a583a8364901665\"" }, - "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3Bucket3B443230": { + "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3Bucket9AE1EC0F": { "Type": "String", - "Description": "S3 bucket for asset \"5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720\"" + "Description": "S3 bucket for asset \"00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5af\"" }, - "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720S3VersionKeyAA4674FB": { + "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afS3VersionKey451EAA56": { "Type": "String", - "Description": "S3 key for asset version \"5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720\"" + "Description": "S3 key for asset version \"00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5af\"" }, - "AssetParameters5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720ArtifactHash3D7A279D": { + "AssetParameters00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5afArtifactHash761F4689": { "Type": "String", - "Description": "Artifact hash for asset \"5afea6e8e6c743a8d1766f21465e28d471e56bcb95c5970054b0514bc62a3720\"" + "Description": "Artifact hash for asset \"00d62edb46d4e11942f8a3afeca5526ec56ff1d63eb753bd46ceecff8b01f5af\"" }, "AssetParametersdaeb79e3cee39c9b902dc0d5c780223e227ed573ea60976252947adab5fb2be1S3BucketDC4B98B1": { "Type": "String", @@ -2202,17 +2206,17 @@ "Type": "String", "Description": "Artifact hash for asset \"ea17febe6d04c66048f3e8e060c71685c0cb53122abceff44842d27bc0d4a03e\"" }, - "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3BucketF482197E": { + "AssetParameters3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87S3Bucket36F31A16": { "Type": "String", - "Description": "S3 bucket for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" + "Description": "S3 bucket for asset \"3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87\"" }, - "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2S3VersionKey38B69632": { + "AssetParameters3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87S3VersionKeyF80D542B": { "Type": "String", - "Description": "S3 key for asset version \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" + "Description": "S3 key for asset version \"3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87\"" }, - "AssetParameters6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2ArtifactHash4BE92B79": { + "AssetParameters3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87ArtifactHash40DDF5EE": { "Type": "String", - "Description": "Artifact hash for asset \"6ee0a36dd10d630708c265bcf7616c64030040c1bbc383b34150db74b744cad2\"" + "Description": "Artifact hash for asset \"3744fa896361f81b76b1efde632ac07b1920ce09a4ca1ff15ab486f262a19b87\"" }, "AssetParametersb866fb0fd5a9b4215d1e23188632d74c01f3195f6f9d706134b197b400afb680S3Bucket56B5C500": { "Type": "String", @@ -2226,17 +2230,17 @@ "Type": "String", "Description": "Artifact hash for asset \"b866fb0fd5a9b4215d1e23188632d74c01f3195f6f9d706134b197b400afb680\"" }, - "AssetParameters3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591S3BucketC38C4355": { + "AssetParameters8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35S3Bucket37C1382F": { "Type": "String", - "Description": "S3 bucket for asset \"3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591\"" + "Description": "S3 bucket for asset \"8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35\"" }, - "AssetParameters3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591S3VersionKey31FFCA42": { + "AssetParameters8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35S3VersionKey5D044A85": { "Type": "String", - "Description": "S3 key for asset version \"3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591\"" + "Description": "S3 key for asset version \"8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35\"" }, - "AssetParameters3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591ArtifactHash2A3C4E8F": { + "AssetParameters8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35ArtifactHash907D4CC2": { "Type": "String", - "Description": "Artifact hash for asset \"3d62bd1f77b829ff043268ba044023fc21ba7d29ffad099d58873aa490a20591\"" + "Description": "Artifact hash for asset \"8d4e2482ff0cc6756dec9686c2446eea35c5a917ce2a8d56d8b83bc148894d35\"" }, "AssetParameters922360c7d159ef358ec5feeac54b70297766064bb1dc00b03a7f147d6f3a882bS3Bucket6FC76F07": { "Type": "String", diff --git a/packages/@aws-cdk/pipelines/test/compliance/assets.test.ts b/packages/@aws-cdk/pipelines/test/compliance/assets.test.ts index b8aed3fd714bf..e4bb58afc47f5 100644 --- a/packages/@aws-cdk/pipelines/test/compliance/assets.test.ts +++ b/packages/@aws-cdk/pipelines/test/compliance/assets.test.ts @@ -387,18 +387,26 @@ describe('basic pipeline', () => { function THEN_codePipelineExpectation() { Template.fromStack(pipelineStack).hasResourceProperties('AWS::IAM::Role', { AssumeRolePolicyDocument: { - Statement: [{ - Action: 'sts:AssumeRole', - Effect: 'Allow', - Principal: { - Service: 'codebuild.amazonaws.com', - AWS: { - 'Fn::Join': ['', [ - 'arn:', { Ref: 'AWS::Partition' }, `:iam::${PIPELINE_ENV.account}:root`, - ]], + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: 'codebuild.amazonaws.com', }, }, - }], + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + AWS: { + 'Fn::Join': ['', [ + 'arn:', { Ref: 'AWS::Partition' }, `:iam::${PIPELINE_ENV.account}:root`, + ]], + }, + }, + }, + ], }, }); Template.fromStack(pipelineStack).hasResourceProperties('AWS::IAM::Policy', @@ -493,18 +501,26 @@ describe('basic pipeline', () => { function THEN_codePipelineExpectation() { Template.fromStack(pipelineStack).hasResourceProperties('AWS::IAM::Role', { AssumeRolePolicyDocument: { - Statement: [{ - Action: 'sts:AssumeRole', - Effect: 'Allow', - Principal: { - Service: 'codebuild.amazonaws.com', - AWS: { - 'Fn::Join': ['', [ - 'arn:', { Ref: 'AWS::Partition' }, `:iam::${PIPELINE_ENV.account}:root`, - ]], + Statement: [ + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + Service: 'codebuild.amazonaws.com', }, }, - }], + { + Action: 'sts:AssumeRole', + Effect: 'Allow', + Principal: { + AWS: { + 'Fn::Join': ['', [ + 'arn:', { Ref: 'AWS::Partition' }, `:iam::${PIPELINE_ENV.account}:root`, + ]], + }, + }, + }, + ], }, }); Template.fromStack(pipelineStack).hasResourceProperties('AWS::IAM::Policy', diff --git a/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json b/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json index 80a17d7243cb1..b10333fdc0ca9 100644 --- a/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json +++ b/packages/@aws-cdk/pipelines/test/integ.newpipeline-with-vpc.expected.json @@ -1970,7 +1970,13 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": "codebuild.amazonaws.com", + "Service": "codebuild.amazonaws.com" + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { "AWS": { "Fn::Join": [ "", diff --git a/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets-single-upload.expected.json b/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets-single-upload.expected.json index 85f20ecf8995f..d5143a1b24ecf 100644 --- a/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets-single-upload.expected.json +++ b/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets-single-upload.expected.json @@ -1344,7 +1344,13 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": "codebuild.amazonaws.com", + "Service": "codebuild.amazonaws.com" + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { "AWS": { "Fn::Join": [ "", diff --git a/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets.expected.json b/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets.expected.json index e236dbdb569ac..545dc0f39651e 100644 --- a/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets.expected.json +++ b/packages/@aws-cdk/pipelines/test/integ.pipeline-with-assets.expected.json @@ -1370,7 +1370,13 @@ "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { - "Service": "codebuild.amazonaws.com", + "Service": "codebuild.amazonaws.com" + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { "AWS": { "Fn::Join": [ "",