diff --git a/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-comprehensive.test-org-test-env-test-domain-test-dataops-project-comprehensive.baseline.json b/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-comprehensive.test-org-test-env-test-domain-test-dataops-project-comprehensive.baseline.json index f7b13c3c..17e792ee 100644 --- a/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-comprehensive.test-org-test-env-test-domain-test-dataops-project-comprehensive.baseline.json +++ b/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-comprehensive.test-org-test-env-test-domain-test-dataops-project-comprehensive.baseline.json @@ -3741,6 +3741,33 @@ }, "Sid": "/temp_ReadWrite" }, + { + "Action": "s3:GetObject*", + "Condition": { + "StringLike": { + "aws:PrincipalArn": "arn:aws:iam::test-account:role/datazone_usr_role_*" + } + }, + "Effect": "Allow", + "Principal": { + "AWS": "*" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "BucketprojectAACC6DD8", + "Arn" + ] + }, + "/deployment/*" + ] + ] + }, + "Sid": "SmusUserRoleDeploymentRead" + }, { "Action": [ "s3:PutObject*", @@ -3863,7 +3890,8 @@ "projectdeploymentrole542A1AAB", "Arn" ] - } + }, + "arn:aws:iam::test-account:role/datazone_usr_role_*" ] } }, diff --git a/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-datazone.test-org-test-env-test-domain-test-dataops-project-datazone.baseline.json b/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-datazone.test-org-test-env-test-domain-test-dataops-project-datazone.baseline.json index 8da3e133..0eb2e7dc 100644 --- a/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-datazone.test-org-test-env-test-domain-test-dataops-project-datazone.baseline.json +++ b/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-datazone.test-org-test-env-test-domain-test-dataops-project-datazone.baseline.json @@ -2312,6 +2312,33 @@ }, "Sid": "/temp_ReadWrite" }, + { + "Action": "s3:GetObject*", + "Condition": { + "StringLike": { + "aws:PrincipalArn": "arn:aws:iam::test-account:role/datazone_usr_role_*" + } + }, + "Effect": "Allow", + "Principal": { + "AWS": "*" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "BucketprojectAACC6DD8", + "Arn" + ] + }, + "/deployment/*" + ] + ] + }, + "Sid": "SmusUserRoleDeploymentRead" + }, { "Action": [ "s3:PutObject*", @@ -2398,7 +2425,8 @@ "projectdeploymentrole542A1AAB", "Arn" ] - } + }, + "arn:aws:iam::test-account:role/datazone_usr_role_*" ] } }, diff --git a/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-minimal.test-org-test-env-test-domain-test-dataops-project-minimal.baseline.json b/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-minimal.test-org-test-env-test-domain-test-dataops-project-minimal.baseline.json index dab357fc..e3c72623 100644 --- a/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-minimal.test-org-test-env-test-domain-test-dataops-project-minimal.baseline.json +++ b/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-minimal.test-org-test-env-test-domain-test-dataops-project-minimal.baseline.json @@ -1546,6 +1546,33 @@ }, "Sid": "/temp_ReadWrite" }, + { + "Action": "s3:GetObject*", + "Condition": { + "StringLike": { + "aws:PrincipalArn": "arn:aws:iam::test-account:role/datazone_usr_role_*" + } + }, + "Effect": "Allow", + "Principal": { + "AWS": "*" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "BucketprojectAACC6DD8", + "Arn" + ] + }, + "/deployment/*" + ] + ] + }, + "Sid": "SmusUserRoleDeploymentRead" + }, { "Action": [ "s3:PutObject*", @@ -1632,7 +1659,8 @@ "projectdeploymentrole542A1AAB", "Arn" ] - } + }, + "arn:aws:iam::test-account:role/datazone_usr_role_*" ] } }, diff --git a/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-sagemaker.test-org-test-env-test-domain-test-dataops-project-sagemaker.baseline.json b/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-sagemaker.test-org-test-env-test-domain-test-dataops-project-sagemaker.baseline.json index ae403cb5..00440d34 100644 --- a/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-sagemaker.test-org-test-env-test-domain-test-dataops-project-sagemaker.baseline.json +++ b/packages/apps/dataops/dataops-project-app/test/__snapshots__/sample-config-sagemaker.test-org-test-env-test-domain-test-dataops-project-sagemaker.baseline.json @@ -1815,6 +1815,33 @@ }, "Sid": "/temp_ReadWrite" }, + { + "Action": "s3:GetObject*", + "Condition": { + "StringLike": { + "aws:PrincipalArn": "arn:aws:iam::test-account:role/datazone_usr_role_*" + } + }, + "Effect": "Allow", + "Principal": { + "AWS": "*" + }, + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "BucketprojectAACC6DD8", + "Arn" + ] + }, + "/deployment/*" + ] + ] + }, + "Sid": "SmusUserRoleDeploymentRead" + }, { "Action": [ "s3:PutObject*", @@ -1901,7 +1928,8 @@ "projectdeploymentrole542A1AAB", "Arn" ] - } + }, + "arn:aws:iam::test-account:role/datazone_usr_role_*" ] } }, diff --git a/packages/constructs/L3/dataops/dataops-project-l3-construct/lib/dataops-project-l3-construct.ts b/packages/constructs/L3/dataops/dataops-project-l3-construct/lib/dataops-project-l3-construct.ts index ef1c5aad..ada8a6c8 100644 --- a/packages/constructs/L3/dataops/dataops-project-l3-construct/lib/dataops-project-l3-construct.ts +++ b/packages/constructs/L3/dataops/dataops-project-l3-construct/lib/dataops-project-l3-construct.ts @@ -1501,12 +1501,25 @@ export class DataOpsProjectL3Construct extends MdaaL3Construct { }); tempPolicy.statements().forEach(statement => projectBucket.addToResourcePolicy(statement)); + // SMUS creates per-user roles named datazone_usr_role__ at session time. + // These are not known to MDAA at deploy time so they cannot be added to roleExcludeIds. + const smusUserRoleArnPattern = `arn:aws:iam::${this.account}:role/datazone_usr_role_*`; + const smusUserRoleDeploymentRead = new PolicyStatement({ + sid: 'SmusUserRoleDeploymentRead', + effect: Effect.ALLOW, + actions: RestrictObjectPrefixToRoles.READ_ACTIONS, + resources: [projectBucket.arnForObjects('deployment/*')], + conditions: { StringLike: { 'aws:PrincipalArn': smusUserRoleArnPattern } }, + }); + smusUserRoleDeploymentRead.addAnyPrincipal(); + projectBucket.addToResourcePolicy(smusUserRoleDeploymentRead); + //Default Deny Policy //Any role not specified in props is explicitely denied access to the bucket const bucketRestrictPolicy = new RestrictBucketToRoles({ s3Bucket: projectBucket, roleExcludeIds: [...this.getAllRoleIds(), lakeFormationRole.roleId, datazoneUserRole.roleId], - principalExcludes: [projectDeploymentRole.roleArn], + principalExcludes: [projectDeploymentRole.roleArn, smusUserRoleArnPattern], }); projectBucket.addToResourcePolicy(bucketRestrictPolicy.denyStatement); projectBucket.addToResourcePolicy(bucketRestrictPolicy.allowStatement); diff --git a/packages/constructs/L3/dataops/dataops-project-l3-construct/test/project.compliance.test.ts b/packages/constructs/L3/dataops/dataops-project-l3-construct/test/project.compliance.test.ts index 5312c9b3..c80bf19b 100644 --- a/packages/constructs/L3/dataops/dataops-project-l3-construct/test/project.compliance.test.ts +++ b/packages/constructs/L3/dataops/dataops-project-l3-construct/test/project.compliance.test.ts @@ -432,6 +432,29 @@ describe('MDAA Compliance Stack Tests', () => { }); }); + test('SmusUserRoleDeploymentRead', () => { + template.hasResourceProperties('AWS::S3::BucketPolicy', { + PolicyDocument: { + Statement: Match.arrayWith([ + Match.objectLike({ + Sid: 'SmusUserRoleDeploymentRead', + Effect: 'Allow', + Action: 's3:GetObject*', + Principal: { AWS: '*' }, + Resource: { + 'Fn::Join': ['', [{ 'Fn::GetAtt': ['BucketprojectAACC6DD8', 'Arn'] }, '/deployment/*']], + }, + Condition: { + StringLike: { + 'aws:PrincipalArn': Match.stringLikeRegexp('datazone_usr_role_\\*$'), + }, + }, + }), + ]), + }, + }); + }); + test('DeploymentRoleReadWrite', () => { template.hasResourceProperties('AWS::S3::BucketPolicy', { PolicyDocument: {