From 1b731c5a966d81901bc809d70679d283037284de Mon Sep 17 00:00:00 2001 From: Luca Pizzini Date: Thu, 28 Dec 2023 16:08:54 +0100 Subject: [PATCH] fix(iam): withConditions overrides Principal actions --- ...efaultTestDeployAssertA5074573.assets.json | 19 +++ ...aultTestDeployAssertA5074573.template.json | 36 ++++ .../cdk.out | 1 + ...cipal-with-conditions-and-tags.assets.json | 19 +++ ...pal-with-conditions-and-tags.template.json | 66 ++++++++ .../integ.json | 12 ++ .../manifest.json | 113 +++++++++++++ .../tree.json | 155 ++++++++++++++++++ ...nteg.principal-with-conditions-and-tags.ts | 23 +++ .../aws-cdk-lib/aws-iam/lib/principals.ts | 12 ++ .../aws-iam/test/principals.test.ts | 42 ++++- 11 files changed, 497 insertions(+), 1 deletion(-) create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/integ-principal-with-conditions-and-tags.assets.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/integ-principal-with-conditions-and-tags.template.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/integ.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/tree.json create mode 100644 packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.ts diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573.assets.json new file mode 100644 index 0000000000000..9e7a3d2096835 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/cdk.out new file mode 100644 index 0000000000000..2313ab5436501 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"34.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/integ-principal-with-conditions-and-tags.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/integ-principal-with-conditions-and-tags.assets.json new file mode 100644 index 0000000000000..91171df754ba7 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/integ-principal-with-conditions-and-tags.assets.json @@ -0,0 +1,19 @@ +{ + "version": "34.0.0", + "files": { + "b1be1c3b71795063ddb9f2ddecfacb8c43d85575e30ff877dca4d378e2f1a53a": { + "source": { + "path": "integ-principal-with-conditions-and-tags.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "b1be1c3b71795063ddb9f2ddecfacb8c43d85575e30ff877dca4d378e2f1a53a.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/integ-principal-with-conditions-and-tags.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/integ-principal-with-conditions-and-tags.template.json new file mode 100644 index 0000000000000..42309004eaa93 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/integ-principal-with-conditions-and-tags.template.json @@ -0,0 +1,66 @@ +{ + "Resources": { + "TestRole25D98AB21": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole", + "sts:TagSession" + ], + "Condition": { + "StringLike": { + "aws:PrincipalTag/owner": "foo" + }, + "Bool": { + "aws:MultiFactorAuthPresent": "true" + } + }, + "Effect": "Allow", + "Principal": { + "AWS": "*" + } + } + ], + "Version": "2012-10-17" + } + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/integ.json new file mode 100644 index 0000000000000..8b1b2aa7b1f3c --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "34.0.0", + "testCases": { + "PrincipalWithConditionAndTags/DefaultTest": { + "stacks": [ + "integ-principal-with-conditions-and-tags" + ], + "assertionStack": "PrincipalWithConditionAndTags/DefaultTest/DeployAssert", + "assertionStackName": "PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/manifest.json new file mode 100644 index 0000000000000..b3bc149c3aea5 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/manifest.json @@ -0,0 +1,113 @@ +{ + "version": "34.0.0", + "artifacts": { + "integ-principal-with-conditions-and-tags.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "integ-principal-with-conditions-and-tags.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "integ-principal-with-conditions-and-tags": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "integ-principal-with-conditions-and-tags.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/b1be1c3b71795063ddb9f2ddecfacb8c43d85575e30ff877dca4d378e2f1a53a.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "integ-principal-with-conditions-and-tags.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "integ-principal-with-conditions-and-tags.assets" + ], + "metadata": { + "/integ-principal-with-conditions-and-tags/TestRole2/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "TestRole25D98AB21" + } + ], + "/integ-principal-with-conditions-and-tags/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/integ-principal-with-conditions-and-tags/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "integ-principal-with-conditions-and-tags" + }, + "PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "PrincipalWithConditionAndTagsDefaultTestDeployAssertA5074573.assets" + ], + "metadata": { + "/PrincipalWithConditionAndTags/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/PrincipalWithConditionAndTags/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "PrincipalWithConditionAndTags/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/tree.json new file mode 100644 index 0000000000000..b209ace2d8181 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.js.snapshot/tree.json @@ -0,0 +1,155 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "integ-principal-with-conditions-and-tags": { + "id": "integ-principal-with-conditions-and-tags", + "path": "integ-principal-with-conditions-and-tags", + "children": { + "TestRole2": { + "id": "TestRole2", + "path": "integ-principal-with-conditions-and-tags/TestRole2", + "children": { + "ImportTestRole2": { + "id": "ImportTestRole2", + "path": "integ-principal-with-conditions-and-tags/TestRole2/ImportTestRole2", + "constructInfo": { + "fqn": "aws-cdk-lib.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "integ-principal-with-conditions-and-tags/TestRole2/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": [ + "sts:AssumeRole", + "sts:TagSession" + ], + "Condition": { + "StringLike": { + "aws:PrincipalTag/owner": "foo" + }, + "Bool": { + "aws:MultiFactorAuthPresent": "true" + } + }, + "Effect": "Allow", + "Principal": { + "AWS": "*" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_iam.Role", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "integ-principal-with-conditions-and-tags/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "integ-principal-with-conditions-and-tags/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "PrincipalWithConditionAndTags": { + "id": "PrincipalWithConditionAndTags", + "path": "PrincipalWithConditionAndTags", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "PrincipalWithConditionAndTags/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "PrincipalWithConditionAndTags/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "PrincipalWithConditionAndTags/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "PrincipalWithConditionAndTags/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "PrincipalWithConditionAndTags/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.ts new file mode 100644 index 0000000000000..b1cac63253881 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-iam/test/integ.principal-with-conditions-and-tags.ts @@ -0,0 +1,23 @@ +import { App, Stack } from 'aws-cdk-lib'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; +import * as iam from 'aws-cdk-lib/aws-iam'; + +const app = new App(); +const stack = new Stack(app, 'integ-principal-with-conditions-and-tags'); + +const basePrincipal = new iam.AnyPrincipal() + .withConditions({ + StringLike: { 'aws:PrincipalTag/owner': 'foo' }, + Bool: { 'aws:MultiFactorAuthPresent': 'true' }, + }) + .withSessionTags(); + +new iam.Role(stack, 'TestRole2', { + assumedBy: basePrincipal, +}); + +new IntegTest(app, 'PrincipalWithConditionAndTags', { + testCases: [stack], +}); + +app.synth(); diff --git a/packages/aws-cdk-lib/aws-iam/lib/principals.ts b/packages/aws-cdk-lib/aws-iam/lib/principals.ts index c6e350f40192b..d940bc0f8541c 100644 --- a/packages/aws-cdk-lib/aws-iam/lib/principals.ts +++ b/packages/aws-cdk-lib/aws-iam/lib/principals.ts @@ -264,6 +264,18 @@ export class PrincipalWithConditions extends PrincipalAdapter { this.additionalConditions = conditions; } + public addToAssumeRolePolicy(doc: PolicyDocument) { + // 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) => { + // Avoid override of existing actions (see https://github.com/aws/aws-cdk/issues/28426) + statement.addActions(this.assumeRoleAction); + statement.addConditions(this.conditions); + return statement; + })); + } + /** * Add a condition to the principal */ diff --git a/packages/aws-cdk-lib/aws-iam/test/principals.test.ts b/packages/aws-cdk-lib/aws-iam/test/principals.test.ts index cc1d166845930..8b9532e0d17e1 100644 --- a/packages/aws-cdk-lib/aws-iam/test/principals.test.ts +++ b/packages/aws-cdk-lib/aws-iam/test/principals.test.ts @@ -441,4 +441,44 @@ test('Can enable session tags', () => { ], }, }); -}); \ No newline at end of file +}); + +test('Can enable session tags with conditions (order of calls is irrelevant)', () => { + // GIVEN + const stack = new Stack(); + + // WHEN + new iam.Role(stack, 'Role', { + assumedBy: new iam.ServicePrincipal( + 's3.amazonaws.com') + .withConditions({ + StringEquals: { hairColor: 'blond' }, + }) + .withSessionTags(), + }); + + new iam.Role(stack, 'Role2', { + assumedBy: new iam.ServicePrincipal( + 's3.amazonaws.com') + .withSessionTags() + .withConditions({ + StringEquals: { hairColor: 'blond' }, + }), + }); + + // THEN + Template.fromStack(stack).resourcePropertiesCountIs('AWS::IAM::Role', { + AssumeRolePolicyDocument: { + Statement: [ + { + Action: ['sts:AssumeRole', 'sts:TagSession'], + Condition: { + StringEquals: { hairColor: 'blond' }, + }, + Effect: 'Allow', + Principal: { Service: 's3.amazonaws.com' }, + }, + ], + }, + }, 2); +});