An AWS permission boundary is an IAM policy that sets the maximum permissions an IAM user or role can ever be granted, no matter how permissive its attached policies are. It does not grant access on its own. It is a ceiling: effective permissions are the intersection of what the identity's policies allow and what the boundary allows. Understanding that intersection is the whole game.
This distinction trips people up constantly. Attaching a boundary that allows s3:* does not give a role S3 access. If the role's own identity policy grants nothing, the role has nothing. The boundary only ever removes; it can never add. Both the identity policy and the boundary must allow an action for it to succeed.
Why Permission Boundaries Exist
The problem they solve is delegated administration. Imagine you want your developers to create their own IAM roles for Lambda functions and EC2 instances, so they are not blocked waiting on the security team. But you cannot hand out iam:CreateRole and iam:AttachRolePolicy freely, because a developer could then create a role with AdministratorAccess and escalate privileges.
A permission boundary breaks that deadlock. You grant developers the ability to create roles, but with a condition: any role they create must have a specific boundary attached. That boundary caps whatever the new role can do. Developers get autonomy, and the blast radius stays contained.
How the Evaluation Logic Works
When an IAM principal makes a request, AWS evaluates several policy types together. For an action to be allowed, it must pass every applicable check: identity-based policies, the permission boundary (if one is attached), any service control policies (SCPs) at the organization level, and session policies for temporary credentials. An explicit Deny anywhere overrides everything.
Think of it as a series of gates. The identity policy opens a gate; the boundary must also open the same gate; the SCP above it must not have closed that gate. Only actions that clear all of them succeed. This is why a role with AdministratorAccess attached can still be nearly powerless if its boundary allows only a narrow set of services.
Enforcing Boundaries on Role Creation
The powerful pattern is a condition that forces the boundary onto newly created principals. A delegated-admin policy for developers looks roughly like this:
{
"Effect": "Allow",
"Action": ["iam:CreateRole", "iam:PutRolePolicy", "iam:AttachRolePolicy"],
"Resource": "*",
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::123456789012:policy/DevBoundary"
}
}
}
The iam:PermissionsBoundary condition key means the developer can only create a role if they attach the DevBoundary policy as that role's boundary. Without it, the CreateRole call is denied. You also want to deny iam:DeleteRolePermissionsBoundary and iam:PutRolePermissionsBoundary so a developer cannot strip or swap the boundary afterward.
Common Mistakes That Defeat the Boundary
Boundaries fail quietly, which is dangerous. Watch for these:
- Forgetting the self-modification denies. If a role can call
iam:DeleteRolePermissionsBoundaryon itself, the ceiling is optional. Always deny boundary modification within the boundary itself. - Confusing the boundary with a grant. Teams add services to the boundary and expect access to appear. Nothing changes until the identity policy also allows those actions.
- Ignoring resource-based policies. A permission boundary limits what the principal can do, but a resource policy on an S3 bucket or KMS key can still grant a different principal access. Boundaries govern the identity, not every path to the resource.
- Leaving the escalation gap open. If developers can attach policies but you never deny
iam:CreatePolicyVersionon the boundary policy itself, they can rewrite the ceiling.
Auditing these across hundreds of roles by hand is error-prone. Configuration scanning and infrastructure-as-code review catch drift before it ships, and pairing IAM review with dependency scanning through an SCA workflow gives you a fuller picture of your cloud risk than IAM analysis alone.
Boundaries Versus Service Control Policies
People ask whether they need SCPs or permission boundaries. They operate at different levels and complement each other. SCPs apply to entire AWS accounts within an organization and set guardrails no principal in that account can exceed, including the root user. Permission boundaries apply to individual IAM users and roles within an account. Use SCPs for account-wide guardrails and boundaries for delegated, per-principal caps. Layer both for defense in depth.
Putting It Into Practice
Start small. Define one boundary policy that reflects the widest set of permissions any delegated role should ever hold, attach it via a CreateRole condition, and deny boundary tampering. Test by creating a role with an over-broad identity policy and confirming the actions outside the boundary are denied. If you can prove the ceiling holds against an intentionally over-permissioned role, your delegation model is sound. Our security academy covers the broader least-privilege patterns that boundaries fit into.
FAQ
Does a permission boundary grant permissions?
No. It only sets the maximum permissions an identity can have. Effective access is the intersection of the identity's policies and the boundary. If the identity policy grants nothing, the identity has no access regardless of what the boundary allows.
What is the difference between a permission boundary and an SCP?
A service control policy applies to a whole AWS account in an organization and caps every principal including root. A permission boundary applies to a single IAM user or role. Use SCPs for account-wide guardrails and boundaries for per-principal delegation.
Can a user with a permission boundary escalate their own privileges?
Not if the boundary is configured correctly. You must deny actions like iam:PutRolePermissionsBoundary, iam:DeleteRolePermissionsBoundary, and policy-version changes within the boundary itself; otherwise the user could remove or rewrite the ceiling.
Do permission boundaries apply to the root user?
No. Permission boundaries apply only to IAM users and roles. To constrain the account root user you need a service control policy at the AWS Organizations level.