docs(iam): clarify boundary rollback recovery

This commit is contained in:
Adam Moussa 2026-08-03 14:36:17 -04:00
parent 8d85b2c396
commit 5d68ab3507
No known key found for this signature in database

View file

@ -338,30 +338,17 @@ Resources:
StringEquals: StringEquals:
"iam:PermissionsBoundary": !Sub "arn:aws:iam::${AWS::AccountId}:policy/seahaven-lambda-execution-boundary" "iam:PermissionsBoundary": !Sub "arn:aws:iam::${AWS::AccountId}:policy/seahaven-lambda-execution-boundary"
# Boundary management — SET the boundary only. DELETE is NOT # Boundary management is SET-only. Granting delete would let this
# granted: for a delete, the iam:PermissionsBoundary condition key # role create a boundary-gated role, strip the boundary, then pass an
# reflects the boundary CURRENTLY attached to the target role, so # unconstrained role to Lambda. SAM creation and teardown need only
# a StringEquals condition on the boundary ARN MATCHES exactly the # PutRolePermissionsBoundary and DeleteRole.
# roles the gate protects. Granting delete under that condition
# lets this role create a boundary-gated role with an inline *:*
# policy, strip the boundary, and pass the now-unbounded role to
# Lambda — defeating the primary escalation control. Verified live
# against the mgmt copy 2026-07-27 (simulate-principal-policy:
# iam:DeleteRolePermissionsBoundary = allowed).
# #
# OPERATIONAL CONSEQUENCE — read before debugging a stuck stack. # Removing a boundary therefore fails by design. A failed rollback
# SAM does not need the delete for the common paths: it SETS the # reaches UPDATE_ROLLBACK_FAILED and needs admin recovery by skipping
# boundary on roles it creates, and stack teardown calls DeleteRole. # or replacing the role. A successful rollback reaches the stable
# But there IS one path that now fails by design: updating an # UPDATE_ROLLBACK_COMPLETE state and can accept a corrective update.
# existing AWS::IAM::Role to REMOVE its PermissionsBoundary property # Removing a SAM function boundary is a security regression, so
# makes CloudFormation call DeleteRolePermissionsBoundary, which is # failing loudly is intentional.
# denied. If rollback also fails, the stack reaches
# UPDATE_ROLLBACK_FAILED and needs out-of-band admin recovery (remove
# the boundary directly, skip the resource during rollback, or
# replace the role by renaming its logical id). A successful rollback
# reaches UPDATE_ROLLBACK_COMPLETE and can accept a corrective update.
# Removing the boundary from a SAM function is a security regression
# anyway, so failing loudly here is the intent.
- Sid: IAMPutPermissionsBoundary - Sid: IAMPutPermissionsBoundary
Effect: Allow Effect: Allow
Action: Action: