DEV Community

Srinivasaraju Tangella
Srinivasaraju Tangella

Posted on

Why Permission Boundary Didn’t Restrict AmazonEC2FullAccess — Complete AWS IAM Debugging Guide

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"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

]
}
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)