From 5d68ab350706f63e98361c9c24a882ad075ed8cb Mon Sep 17 00:00:00 2001 From: Adam Moussa Date: Mon, 3 Aug 2026 14:36:17 -0400 Subject: [PATCH] docs(iam): clarify boundary rollback recovery --- oidc-deploy-roles.yaml | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/oidc-deploy-roles.yaml b/oidc-deploy-roles.yaml index e84ed33..038a849 100644 --- a/oidc-deploy-roles.yaml +++ b/oidc-deploy-roles.yaml @@ -338,30 +338,17 @@ Resources: StringEquals: "iam:PermissionsBoundary": !Sub "arn:aws:iam::${AWS::AccountId}:policy/seahaven-lambda-execution-boundary" - # Boundary management — SET the boundary only. DELETE is NOT - # granted: for a delete, the iam:PermissionsBoundary condition key - # reflects the boundary CURRENTLY attached to the target role, so - # a StringEquals condition on the boundary ARN MATCHES exactly the - # 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). + # Boundary management is SET-only. Granting delete would let this + # role create a boundary-gated role, strip the boundary, then pass an + # unconstrained role to Lambda. SAM creation and teardown need only + # PutRolePermissionsBoundary and DeleteRole. # - # OPERATIONAL CONSEQUENCE — read before debugging a stuck stack. - # SAM does not need the delete for the common paths: it SETS the - # boundary on roles it creates, and stack teardown calls DeleteRole. - # But there IS one path that now fails by design: updating an - # existing AWS::IAM::Role to REMOVE its PermissionsBoundary property - # makes CloudFormation call DeleteRolePermissionsBoundary, which is - # 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. + # Removing a boundary therefore fails by design. A failed rollback + # reaches UPDATE_ROLLBACK_FAILED and needs admin recovery by skipping + # or replacing the role. A successful rollback reaches the stable + # UPDATE_ROLLBACK_COMPLETE state and can accept a corrective update. + # Removing a SAM function boundary is a security regression, so + # failing loudly is intentional. - Sid: IAMPutPermissionsBoundary Effect: Allow Action: