diff --git a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/bootstrapping.integtest.ts b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/bootstrapping.integtest.ts index c76ea0f9bec21..18889bde7dd7e 100644 --- a/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/bootstrapping.integtest.ts +++ b/packages/@aws-cdk-testing/cli-integ/tests/cli-integ-tests/bootstrapping.integtest.ts @@ -255,6 +255,17 @@ integTest('can use the custom permissions boundary to bootstrap', withoutBootstr expect(template).toContain('permission-boundary-name'); })); +integTest('can use the custom permissions boundary (with slashes) to bootstrap', withoutBootstrap(async (fixture) => { + let template = await fixture.cdkBootstrapModern({ + // toolkitStackName doesn't matter for this particular invocation + toolkitStackName: fixture.bootstrapStackName, + showTemplate: true, + customPermissionsBoundary: 'permission-boundary-name/with/path', + }); + + expect(template).toContain('permission-boundary-name/with/path'); +})); + integTest('can remove customPermissionsBoundary', withoutBootstrap(async (fixture) => { const bootstrapStackName = fixture.bootstrapStackName; const policyName = `${bootstrapStackName}-pb`; diff --git a/packages/aws-cdk/lib/api/bootstrap/bootstrap-environment.ts b/packages/aws-cdk/lib/api/bootstrap/bootstrap-environment.ts index f4a1b22729831..f3041fd3864ec 100644 --- a/packages/aws-cdk/lib/api/bootstrap/bootstrap-environment.ts +++ b/packages/aws-cdk/lib/api/bootstrap/bootstrap-environment.ts @@ -279,7 +279,9 @@ export class Bootstrapper { private validatePolicyName(permissionsBoundary: string) { // https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreatePolicy.html - const regexp: RegExp = /[\w+=,.@-]+/; + // Added support for policy names with a path + // See https://github.com/aws/aws-cdk/issues/26320 + const regexp: RegExp = /[\w+\/=,.@-]+/; const matches = regexp.exec(permissionsBoundary); if (!(matches && matches.length === 1 && matches[0] === permissionsBoundary)) { throw new Error(`The permissions boundary name ${permissionsBoundary} does not match the IAM conventions.`); diff --git a/packages/aws-cdk/test/api/bootstrap2.test.ts b/packages/aws-cdk/test/api/bootstrap2.test.ts index b7e48f8493069..427ea1daf0906 100644 --- a/packages/aws-cdk/test/api/bootstrap2.test.ts +++ b/packages/aws-cdk/test/api/bootstrap2.test.ts @@ -207,6 +207,28 @@ describe('Bootstrapping v2', () => { ])); }); + test('adding permission boundary with path in policy name', async () => { + mockTheToolkitInfo({ + Parameters: [ + { + ParameterKey: 'InputPermissionsBoundary', + ParameterValue: '', + }, + ], + }); + await bootstrapper.bootstrapEnvironment(env, sdk, { + parameters: { + customPermissionsBoundary: 'permissions-boundary-name/with/path', + }, + }); + + expect(stderrMock.mock.calls).toEqual(expect.arrayContaining([ + expect.arrayContaining([ + expect.stringMatching(/Adding new permissions boundary permissions-boundary-name\/with\/path/), + ]), + ])); + }); + test('passing trusted accounts without CFN managed policies results in an error', async () => { await expect(bootstrapper.bootstrapEnvironment(env, sdk, { parameters: {