Permission boundaries in practice
Delegate admin without handing over the kingdom.
In short. Permission boundaries let you delegate IAM administration without handing over the kingdom.
Permission boundaries let you delegate IAM administration without handing over the kingdom. A boundary is a managed policy that sets the maximum permissions an identity can ever have — even if someone attaches AdministratorAccess. Effective permissions are the intersection of identity policies and the boundary (and still subject to SCPs and resource policies).
Use boundaries when product teams may create roles for their apps but must not create roles that can touch production KMS keys, IAM, or billing. Pair with SCPs for org-wide floors.
Intersection mental model
# attach boundary when creating a roleaws iam create-role --role-name app-team-role \--assume-role-policy-document file://trust.json \--permissions-boundary arn:aws:iam::111122223333:policy/AppTeamBoundaryaws iam simulate-principal-policy \--policy-source-arn arn:aws:iam::111122223333:role/app-team-role \--action-names iam:CreateUser s3:ListBucket
… CreateUser → implicitDeny (boundary) …… ListBucket → allowed …
Common boundary contents
Allow app data plane actions (S3/SQS/RDS describe in team accounts), deny IAM mutations except scoped ones, deny org/account leaving, deny disabling CloudTrail/GuardDuty. Keep boundaries in Git and review like SCPs.
Going deeper
When creating pipelines that provision IAM roles for app teams, require a boundary ARN in the create-role call and deny CreateRole without it via SCP or permission boundary on the provisioner itself — otherwise the first action a delegated admin takes is creating an unbounded role.
Test with iam simulate-principal-policy and Access Analyzer policy validation in CI for your boundary JSON. Boundaries that accidentally allow iam:CreateRole without constraints recreate the escalation path.
Document the human break-glass that can operate without the boundary (or with a broader one) and alarm on its use. Boundaries without break-glass create shadow admin paths when people get stuck.
Boundaries do not replace code review of IAM JSON. A boundary that allows * on data services still permits wide lateral movement inside an account. Scope resources with ARNs and conditions.
Align boundary contents with SCP denials so humans get consistent errors. A boundary deny that SCPs would also deny is fine; a boundary allow that SCPs deny confuses debugging — document the layer that blocked.
Version boundary policies in Git with CODEOWNERS from security. Console edits to boundaries should be rare and alarmed via CloudTrail PutRolePermissionsBoundary events.
Try this
Attach a boundary that denies iam:* to a lab role that otherwise has AdministratorAccess; prove IAM calls fail while S3 still works.
aws iam put-role-permissions-boundary --role-name lab-admin --permissions-boundary-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccessaws iam create-user --user-name x || trueaws s3 ls || true
AccessDenied on IAM… s3 list may still work depending on identity policy ∩ boundary …
Takeaway
Boundaries cap delegated admins. Intersect with identity policies and SCPs; never confuse the three layers.
Next: Organizations and SCPs — the building rules no tenant can vote away.