diff --git a/packages/@aws-cdk/aws-iam/lib/policy-statement.ts b/packages/@aws-cdk/aws-iam/lib/policy-statement.ts index ce817a58e508e..78a588760c9d6 100644 --- a/packages/@aws-cdk/aws-iam/lib/policy-statement.ts +++ b/packages/@aws-cdk/aws-iam/lib/policy-statement.ts @@ -64,7 +64,8 @@ export class PolicyStatement { constructor(props: PolicyStatementProps = {}) { // Validate actions for (const action of [...props.actions || [], ...props.notActions || []]) { - if (!/^(\*|[a-zA-Z0-9-]+:[a-zA-Z0-9*]+)$/.test(action)) { + + if (!/^(\*|[a-zA-Z0-9-]+:[a-zA-Z0-9*]+)$/.test(action) && !cdk.Token.isUnresolved(action)) { throw new Error(`Action '${action}' is invalid. An action string consists of a service namespace, a colon, and the name of an action. Action names can include wildcards.`); } } 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 d8a9b1337c21c..bd3bd6fd31aa3 100644 --- a/packages/@aws-cdk/aws-iam/test/policy-document.test.ts +++ b/packages/@aws-cdk/aws-iam/test/policy-document.test.ts @@ -102,6 +102,19 @@ describe('IAM policy document', () => { }).toThrow(/Action 'in:val:id' is invalid/); }); + // https://github.com/aws/aws-cdk/issues/13479 + test('Does not validate unresolved tokens', () => { + const stack = new Stack(); + const perm = new PolicyStatement({ + actions: [`${Lazy.string({ produce: () => 'sqs:sendMessage' })}`], + }); + + expect(stack.resolve(perm.toStatementJson())).toEqual({ + Effect: 'Allow', + Action: 'sqs:sendMessage', + }); + }); + test('Cannot combine Resources and NotResources', () => { expect(() => { new PolicyStatement({