feat(iam): allow frontend HCP apply to update exact CloudFront resources (PLAT-187)

Phase 2 ownership tags cannot apply while UpdateDistribution and UpdateFunction are denied on *. Allow those two actions only on the pinned distribution and function ARNs.
This commit is contained in:
Adam Moussa 2026-09-11 10:42:53 -04:00
parent a829854cd0
commit cb49670711
No known key found for this signature in database
2 changed files with 28 additions and 12 deletions

View file

@ -438,8 +438,9 @@ job:
ownership handoff for HCP roles/boundaries where applicable. Import the
existing site resources only after a no-replacement plan. Apply-role writes
are limited to ordinary tags, `PutRolePolicy` on the exact deploy role,
`PutBucketPolicy` on the exact bucket, and A/AAAA changes for the exact site
name with CREATE/DELETE/UPSERT conditions.
`PutBucketPolicy` on the exact bucket, `UpdateDistribution` on the exact
distribution, `UpdateFunction` on the exact CloudFront function, and A/AAAA
changes for the exact site name with CREATE/DELETE/UPSERT conditions.
5. For a future tf-poc, first provision and inventory the site outside these
adoption roles. Set all five `shocFrontendPoc*` identifiers from the
frontend shared creator outputs while its role gate remains false, deploy
@ -451,14 +452,17 @@ job:
a false gate as rollback after CloudFormation owns a role.
The apply roles explicitly deny role lifecycle/trust/boundary/managed-policy
changes, `PassRole`, secret and parameter reads, CloudFront/S3 infrastructure
mutation, and deletion of inline role or bucket policies. IAM does not expose a
condition key for an inline policy name, so `PutRolePolicy` is constrained to
the exact target-role ARN and requires the exact dedicated deploy boundary to
already be attached. The boundary limits effective permissions, and the SCP
requires the target role's locked `HcpTerraformWorkspace` tag to equal the
apply role's principal tag. The Terraform resource must retain the inventoried
inline policy name.
changes, `PassRole`, secret and parameter reads, CloudFront/S3 create and
delete (including OAC mutation and `PublishFunction`), and deletion of inline
role or bucket policies. `UpdateDistribution` and `UpdateFunction` are allowed
only on the exact pinned distribution and function ARNs so Phase 2 ownership
tags can apply; create, delete, and OAC updates stay denied. IAM does not
expose a condition key for an inline policy name, so `PutRolePolicy` is
constrained to the exact target-role ARN and requires the exact dedicated
deploy boundary to already be attached. The boundary limits effective
permissions, and the SCP requires the target role's locked
`HcpTerraformWorkspace` tag to equal the apply role's principal tag. The
Terraform resource must retain the inventoried inline policy name.
**HCP Terraform layout (org-level setup, console):** one org `seahaven`
(free tier: 500 managed resources, 1 concurrent run); one HCP **project per

View file

@ -271,8 +271,6 @@ const frontendApplyPolicy = (
"cloudfront:DeleteFunction",
"cloudfront:DeleteOriginAccessControl",
"cloudfront:PublishFunction",
"cloudfront:UpdateDistribution",
"cloudfront:UpdateFunction",
"cloudfront:UpdateOriginAccessControl",
"s3:CreateBucket",
"s3:DeleteBucket",
@ -331,6 +329,20 @@ const frontendApplyPolicy = (
functionArn(environment.functionName),
],
},
// TagResource is already allowed. Update* was denied on * so Phase 2
// in-place CloudFront updates could not apply. Scope both to exact ARNs.
{
Sid: "UpdateExactDistribution",
Effect: "Allow",
Action: "cloudfront:UpdateDistribution",
Resource: distributionArn(environment.distributionId),
},
{
Sid: "UpdateExactFunction",
Effect: "Allow",
Action: "cloudfront:UpdateFunction",
Resource: functionArn(environment.functionName),
},
{
Sid: "ReplaceExactDeployInlinePolicy",
Effect: "Allow",