Introduction
Permission Boundaries in AWS IAM are one of the most misunderstood security features—even among experienced DevOps engineers.
A very common real-world scenario:
You attach AmazonEC2FullAccess managed policy to a user
You create a custom policy
allowing only:
StartInstances
StopInstances
Specific region
Specific instance
You set that custom policy as Permission Boundary
But the user still has broader access than expected.
Why?
This article explains:
What Permission Boundaries really do
Why your restriction didn’t work
AWS internal permission evaluation logic
Exact root cause
Step-by-step working solution
Real production best practices
What is Permission Boundary (Simple Definition)
Permission Boundary defines the maximum permissions a user or role can have.
It does NOT grant permissions.
It only LIMITS permissions.
Final effective permission =
Identity Policy
INTERSECT
Permission Boundary
Both must allow.
Real-World Scenario
You created:
Managed Policy attached to user
AmazonEC2FullAccess
This allows:
ec2:*
All regions
All instances
Custom Policy used as Permission Boundary
Allow:
ec2:StartInstances
ec2:StopInstances
ec2:DescribeInstances
Only:
Region: ap-south-1
Instance: i-0fec564a20ed664ff
Expected Result:
User should only:
Start that instance
Stop that instance
Only in ap-south-1
Everything else should be denied.
But it didn’t work as expected.
Root Cause (Critical AWS IAM Internal Behavior)
Some EC2 actions REQUIRE:
Resource: ""
Example:
ec2:DescribeInstances
AWS does not evaluate DescribeInstances using specific instance ARN.
It internally requires:
Resource: ""
If you restrict DescribeInstances to specific ARN, permission evaluation becomes inconsistent.
This causes unexpected access behavior.
This is NOT a bug.
This is AWS design.
AWS Permission Evaluation Flow (Actual Engine Logic)
AWS evaluates in this order:
Step 1: Check Identity Policy (AmazonEC2FullAccess)
Step 2: Check Permission Boundary
Step 3: Check SCP (if exists)
Step 4: Final allow or deny
Final permission must be allowed by ALL.
Incorrect Permission Boundary (Problematic Version)
This version causes issues:
{
"Effect": "Allow",
"Action": "ec2:DescribeInstances",
"Resource": "arn:aws:ec2:ap-south-1:account-id:instance/i-xxxx"
}
Because DescribeInstances needs:
Resource: "*"
Correct Working Permission Boundary (Production-Ready Solution)
Use this:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowDescribeInstances",
"Effect": "Allow",
"Action": "ec2:DescribeInstances",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "ap-south-1"
}
}
},
{
"Sid": "AllowStartStopSpecificInstance",
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:StopInstances"
],
"Resource": "arn:aws:ec2:ap-south-1:useaccountID:instance/i-0fec564a20ed664ff",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "ap-south-1"
}
}
}
]
}
This is the correct and secure implementation.
Step-by-Step Implementation Guide
Step 1: Create Permission Boundary Policy
Navigate:
AWS Console
→ IAM
→ Policies
→ Create Policy
→ JSON tab
Paste the corrected policy.
Click:
Next
Name: EC2StartStopBoundary
Create Policy
Step 2: Attach Permission Boundary to User
Navigate:
IAM
→ Users
→ Select User
→ Permissions tab
→ Permissions boundary
→ Set permissions boundary
Select:
EC2StartStopBoundary
Click Save.
Step 3: Attach AmazonEC2FullAccess Managed Policy
Navigate:
IAM
→ Users
→ Select User
→ Add Permissions
→ Attach policies directly
Select:
AmazonEC2FullAccess
Save.
Final Permission Result
User can:
Start instance i-0fec564a20ed664ff
Stop instance i-0fec564a20ed664ff
Describe instances in ap-south-1
User cannot:
Terminate instance
Create instance
Modify instance
Start other instances
Access other regions
Everything else is denied.
Architecture Visualization
Think like this:
AmazonEC2FullAccess = Large circle
Permission Boundary = Smaller circle inside
Final permission = Overlap area only
Boundary limits maximum allowed permissions.
Real DevOps Production Use Cases
Permission boundaries are used in:
Enterprise environments
To allow developers:
Create EC2
BUT only in specific region
Platform engineering teams
Allow teams to:
Deploy infrastructure
BUT prevent security violations
Multi-tenant environments
Allow customers to:
Manage their resources
BUT not exceed allowed limits
Common Mistakes DevOps Engineers Make
Mistake 1
Restricting DescribeInstances to specific ARN
*Mistake 2"
Not attaching boundary properly
Mistake 3
Using boundary with Deny incorrectly
Mistake 4
Testing with root account
Mistake 5
Not understanding IAM evaluation logic
Best Practice Recommendation (Enterprise Level)
Always:
Allow Describe* actions with Resource "*"
Restrict sensitive actions using specific ARN
Use region conditions
Use permission boundaries for delegation
Summary
Permission Boundary is NOT a replacement for identity policies.
It is a maximum permission guardrail.
Key lesson:
Identity Policy grants permissions
Permission Boundary limits permissions
Final permission = intersection
Understanding this concept is critical for DevOps, Cloud Security, and Platform Engineering roles.
Final Thoughts
Permission Boundaries are heavily used in:
Enterprise AWS environments
Platform engineering
DevSecOps
Secure multi-team architectures
Mastering this concept gives you strong cloud security expertise.
If you're a DevOps engineer, understanding IAM deeply is not optional—it is mandatory.
Top comments (0)