feat(scp): deny iam changes on role/platform unless the platform principal (PLAT-233)

Adds ProtectPlatformPath beside the existing name denies in the
prod/nonprod SCP and the security OU copy. New hcptf-bootstrap
creates use /platform/. Existing roles are not recreated.

Co-authored-by: Adam Moussa <amoussa1229@users.noreply.github.com>
This commit is contained in:
Cursor Agent 2026-09-28 00:49:48 +00:00
parent d80295c005
commit e3adfc3cdc
No known key found for this signature in database
3 changed files with 56 additions and 2 deletions

View file

@ -260,7 +260,7 @@ export class OrgGovernanceStack extends cdk.Stack {
name: "protect-privileged-roles",
type: "SERVICE_CONTROL_POLICY",
description:
"prod/nonprod: protect break-glass, CDK exec, githubdeploy, and hcptf-bootstrap roles",
"prod/nonprod: protect break-glass, CDK exec, githubdeploy, hcptf-bootstrap, and /platform/ roles",
targetIds: [prodOu.attrId, nonprodOu.attrId],
content: scpContent("protect-privileged-roles"),
});
@ -338,6 +338,31 @@ export class OrgGovernanceStack extends cdk.Stack {
},
},
},
{
Sid: "ProtectPlatformPath",
Effect: "Deny",
Action: [
"iam:CreateRole",
"iam:UpdateAssumeRolePolicy",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy",
"iam:PutRolePolicy",
"iam:DeleteRolePolicy",
"iam:DeleteRole",
"iam:UpdateRole",
"iam:TagRole",
"iam:UntagRole",
],
Resource: "arn:aws:iam::*:role/platform/*",
Condition: {
ArnNotLike: {
"aws:PrincipalArn": [
"arn:aws:iam::*:role/OrganizationAccountAccessRole",
"arn:aws:iam::*:role/aws-reserved/sso.amazonaws.com/*/AWSReservedSSO_Platform_*",
],
},
},
},
{
Sid: "ProtectDelegatedAdminMembership",
Effect: "Deny",

View file

@ -31,6 +31,31 @@
]
}
}
},
{
"Sid": "ProtectPlatformPath",
"Effect": "Deny",
"Action": [
"iam:CreateRole",
"iam:UpdateAssumeRolePolicy",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy",
"iam:PutRolePolicy",
"iam:DeleteRolePolicy",
"iam:DeleteRole",
"iam:UpdateRole",
"iam:TagRole",
"iam:UntagRole"
],
"Resource": "arn:aws:iam::*:role/platform/*",
"Condition": {
"ArnNotLike": {
"aws:PrincipalArn": [
"arn:aws:iam::*:role/OrganizationAccountAccessRole",
"arn:aws:iam::*:role/aws-reserved/sso.amazonaws.com/*/AWSReservedSSO_Platform_*"
]
}
}
}
]
}

View file

@ -239,10 +239,14 @@ create_or_update_role() {
aws iam update-assume-role-policy --role-name "$name" --policy-document "file://${trust_file}"
fi
else
echo " $name: create"
echo " $name: create on /platform/"
# Path is create-only. IAM cannot move an existing role onto /platform/.
# Prod and dev already have hcptf-bootstrap and hcptf-bootstrap-plan, so
# this branch does not run for them. Do not delete and recreate to set a path.
if [[ "$DRY_RUN" -eq 0 ]]; then
aws iam create-role \
--role-name "$name" \
--path /platform/ \
--assume-role-policy-document "file://${trust_file}" \
--description "HCP Terraform ${name} (PLAT-145). Console/CLI owned. Manual apply only." \
--tags Key=Project,Value=hcp-bootstrap Key=Owner,Value=adam@seahavenind.com Key=ManagedBy,Value=cli