The Security Blueprint: Master IAM Before Everything Breaks
Building systems that don’t wake you at 2 AM
The Security Blueprint: Master IAM Before Everything Breaks

Building systems that don’t wake you at 2 AM
The Plot Twist You Didn’t See Coming
In Post #1, we mapped your AWS journey. Today we answer the question that stops most architects in their tracks:
“Who’s responsible for what?”
You just provisioned an S3 bucket. Congratulations — you also own 80% of its security. AWS manages the infrastructure. You manage literally everything else. This is called the Shared Responsibility Model, and it’s where most AWS breaches happen.
Not in AWS infrastructure. In your stuff.
Let’s fix that.
Part 1: The Foundation — Shared Responsibility Model
What AWS Owns (Don’t Worry About This)
AWS is responsible for:
- Physical security of data centers
- Hypervisor & virtualization infrastructure
- Network infrastructure (mostly)
- Storage infrastructure (mostly)
- Database engines & operating systems (for managed services like RDS, DynamoDB, Lambda)
This is their “security of the cloud.”
What You Own (This Is Where You Sleep)
You are responsible for:
- Identity & Access Management (who can do what)
- Application code & data (including data encryption, if you want it encrypted)
- OS patching (for EC2)
- Firewall rules (Security Groups, NACLs)
- Data classification & compliance (you decide what’s sensitive)
- Access credentials (don’t check them into GitHub)
This is “security in the cloud.”
The Gray Zone (Shared Responsibility)
Some things are shared:
Service AWS Owns You Own EC2 Hypervisor, physical security OS patching, app security, network config RDS Database engine, backups Access credentials, network access rules S3 Infrastructure Bucket policy, object permissions, encryption keys Lambda Runtime, patches Code security, IAM permissions, environment variables
Mental model: If you can’t click a toggle to change it in AWS, AWS owns it. Otherwise, it’s yours.
Part 2: The Onion Model — Defense in Depth
Imagine security like an onion. Each layer protects what’s inside. Attack one layer, and six others stand guard.
Layer 1: Physical & Facilities (AWS)
- Data center access controls
- 24/7 monitoring, biometrics, cameras
- You can’t control this, so stop worrying about it
Layer 2: Network Perimeter (Mostly AWS, Some You)
- DDoS protection via AWS Shield
- WAF (Web Application Firewall) rules
- VPC isolation and routing
- Your piece: Security Groups & NACLs
Layer 3: Identity & Access (YOU)
- Who can access what?
- IAM Users, Roles, Policies
- Multi-factor authentication
- This is where 90% of breaches happen
Layer 4: Encryption & Data Protection (Shared)
- Encryption at rest (in storage)
- Encryption in transit (over networks)
- Key management
- AWS provides the tools; you decide to use them
Layer 5: Application Security (YOU)
- Input validation
- SQL injection prevention
- Secure coding practices
- API security
Layer 6: Data & Compliance (YOU)
- Data classification
- Audit logging
- Compliance frameworks
- Incident response
The key insight: If an attacker gets past layer 3 (IAM), all other layers become decorative. So let’s build layer 3 bulletproof.
Part 3: IAM Fundamentals — The Five Building Blocks
IAM is AWS’s identity service. It controls who (identity), does what (action), on which resource (resource).
1. IAM Users: The Humans & Apps
An IAM User is a person or application that needs AWS access.
User: jack.harmon@company.com
├── Can login to Console (Password + MFA)
├── Can use AWS CLI (Access Key ID + Secret Access Key)
└── Can authenticate via SSH key (CodeCommit)
Critical: Don’t share IAM Users. Create one per person. Delete them when they leave.
Root User is NOT an IAM User. It’s the AWS account owner. Treat it like a nuclear launch codes:
- Enable MFA
- Don’t create Access Keys
- Don’t use it daily
- Lock it in a safe
2. IAM Groups: The Shortcut
Groups are just… containers. You add Users to a Group, then attach Policies to the Group. Now all Users inherit those permissions.
Group: Engineers
├── john.smith (EC2, RDS full access)
├── jane.doe (EC2, RDS full access)
└── bob.jones (EC2, RDS full access)
Benefits:
- Change permissions once, affects 20 people
- Cleaner governance
- Easier audits
3. IAM Roles: The Delegation Token
A Role is an identity you can assume — it’s not a person, it’s a set of permissions.
Unlike Users, Roles have a Trust Policy that defines who can assume them.
{
"Principal": "arn:aws:iam::123456789012:role/LambdaExecutionRole",
"Action": "sts:AssumeRole",
"Effect": "Allow"
}
Use Roles for:
- EC2 instances accessing S3
- Lambda functions accessing DynamoDB
- Cross-account access (Account A accessing Account B)
- Third-party integrations
4. IAM Policies: The Permission Slip
A Policy is a JSON document that says “User/Role X can do Action Y on Resource Z.”
Example: Allow Lambda to read from S3
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::my-bucket/*"]
}
]
}
Breaking it down:
Effect: Allow or DenyAction: What they can do (s3:GetObject, ec2:DescribeInstances, etc.)Resource: What they can do it on (specific bucket, all buckets, etc.)
Two types:
- Inline Policies — Attached directly to a User/Role (not reusable)
- Managed Policies — Separate entities you can attach to multiple Users/Roles
Pro tip: Use Managed Policies. They’re versioned, shareable, and easier to debug.
5. IAM Service Principals: AWS Services Acting on Your Behalf
AWS services need permission to act in your account.
For example, Lambda needs permission to write logs to CloudWatch. Instead of creating a User for Lambda, you create a Role and let Lambda assume it.
EC2 Instance Profile → Assumes IAM Role → Gets temporary credentials
The instance calls AWS STS (Secure Token Service) and gets short-lived credentials. No Access Keys on the instance = much safer.
Part 4: Principle of Least Privilege — The One Rule That Saves You
Principle of Least Privilege (PoLP): Give users only the permissions they need to do their job. Nothing more.
Why This Matters
Scenario: A developer gets their laptop stolen. Attacker has their AWS credentials.
Bad PoLP:
- Developer has
AdministratorAccess(AWS managed policy) - Attacker now controls your entire AWS account
- Cost: Remediation, compliance breach, careers
Good PoLP:
- Developer has
s3:GetObjectonarn:aws:s3:::dev-bucket/* - Attacker can only read files from a dev bucket
- Cost: A few dev files, problem contained
How to Implement PoLP
Step 1: Ask “What’s the minimum they need?”
- Analyst needs to read logs →
logs:GetLogEventsonly - Data engineer needs to write to staging DB →
rds-db:connectonly - Not:
AdministratorAccess
Step 2: Be specific with Resources
// ❌ Bad: all S3 buckets
"Resource": "arn:aws:s3:::*"
// ✅ Good: specific bucket and prefix
"Resource": "arn:aws:s3:::my-app-logs/2026/*"
Step 3: Audit quarterly
Who has what? Do they still need it? Remove it.
Real-World Example
Your data team needs to run Athena queries on S3 data.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"athena:StartQueryExecution",
"athena:GetQueryExecution",
"athena:GetQueryResults"
],
"Resource": "arn:aws:athena:us-east-1:123456789012:workgroup/analytics"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::data-warehouse",
"arn:aws:s3:::data-warehouse/*"
]
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject"
],
"Resource": "arn:aws:s3:::athena-results/*"
}
]
}
They can:
- Run Athena queries
- Read data warehouse files
- Write query results
They cannot:
- Delete anything
- Access other buckets
- Modify IAM policies
- Provision EC2 instances
Part 5: Cross-Account Access — When You Need to Share
Scenario: You have two AWS accounts.
- Account A: Production
- Account B: Disaster Recovery
Your backup Lambda in Account B needs to copy snapshots from Account A.
Old way: Share credentials (bad, bad, bad)
AWS way: Roles + Trust Policies
How It Works
- In Account A: Create a Role with S3/EBS permissions
- Trust Policy: Allow Account B to assume this role
- In Account B: Create a Role that assumes Account A’s role
- Lambda in Account B: Uses STS to assume Account A’s role, gets credentials, copies snapshots
// Account A's Role Trust Policy
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::ACCOUNT-B:root"
},
"Action": "sts:AssumeRole"
}
Benefits:
- No shared credentials
- Fully auditable (CloudTrail logs who assumed what)
- Time-limited (credentials expire)
- Can add conditions (only from specific IP, only during business hours, etc.)
Part 6: Service Control Policies — The Account-Level Guardrail
Imagine you have 50 AWS accounts under your Organization.
You want to prevent anyone from deleting RDS databases. No policy in the world can help — someone will attach AdministratorAccess and bypass it.
Enter: Service Control Policies (SCPs)
An SCP is a Policy attached to your Organization (not individual users) that acts as a ceiling. No IAM policy can override it.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "rds:DeleteDBInstance",
"Resource": "*"
}
]
}
Now, even if someone has AdministratorAccess, they can't delete RDS instances.
Use Cases for SCPs
- Prevent deletion of backups
- Restrict EC2 instance types (prevent expensive instances)
- Enforce encryption on S3 buckets
- Block public S3 access
- Restrict regions (only us-east-1, us-west-2)
Pro tip: Use Deny statements in SCPs. Denies always win.
Part 7: Encryption — At Rest and In Transit
Encryption at Rest
Data is stored. It’s sitting on a hard drive. Someone could steal the drive. Encrypt it.
S3 Example:
- AWS S3 Server-Side Encryption (SSE-S3): AWS manages keys
- AWS KMS (SSE-KMS): You manage keys (better)
- Client-Side Encryption: You encrypt before uploading (best, most control)
EBS Example:
EC2 Instance → (encrypted) → EBS Volume → (encrypted) → Disk
When you read a file, AWS automatically decrypts it. You don’t see the encryption.
KMS (Key Management Service):
- Centralized key management
- Keys never leave AWS (except CloudHSM)
- Audit every key usage
- Rotate keys annually
Encryption in Transit
Data is moving. Over the network. An attacker with network access could intercept it.
TLS/SSL:
- HTTPS for web traffic
- TLS for databases (RDS, DynamoDB)
- VPN for office-to-AWS connections
Examples:
- ALB → EC2: Configure TLS on your security group
- EC2 → RDS: Use RDS with SSL enabled
- Your laptop → AWS API: All AWS API calls are TLS encrypted by default
Rule of Thumb
Encrypt sensitive data:
- Customer data (emails, credit cards, SSNs)
- Database credentials
- API keys
- Proprietary algorithms
Encrypt non-sensitive data too if:
- Compliance requires it (HIPAA, PCI-DSS, SOC 2)
- You have time to implement it
- Performance hit is acceptable
Part 8: Security Audit Checklist for Domain 1
Copy this. Use it every month.
Identity & Access
- Root user has MFA enabled
- No root user Access Keys exist
- All active Users have MFA enabled (Console users)
- IAM Users with CLI access have Access Keys rotated every 90 days
- Unused IAM Users are deleted (checked last 90 days)
- Groups are used for permission management (not inline policies)
- EC2 instances use Instance Profiles (Roles), not Access Keys on instances
- Cross-account access uses Roles with Trust Policies
Policies
- No Policies with
"Action": "*"on principal accounts - No Policies with
"Resource": "*"except for read-only actions - Managed Policies are used instead of inline policies
- AWS managed policies are used as a starting point, then tightened
- PoLP is documented and enforced in code reviews
Encryption
- S3 buckets have default encryption enabled
- EBS volumes are encrypted
- RDS databases use encryption at rest
- TLS is enforced for RDS connections
- Sensitive environment variables are encrypted (Secrets Manager, Parameter Store)
- Key rotation is configured for KMS keys
Network
- VPC has public and private subnets
- Security Groups deny all inbound by default
- Security Groups allow only required ports (443, 80, 3306, etc.)
- NACLs are only modified if you have a specific security reason
- VPC Flow Logs are enabled (for troubleshooting)
Governance
- CloudTrail is enabled for all regions
- CloudTrail logs are stored in an immutable S3 bucket
- AWS Config is enabled (if you care about compliance)
- CloudWatch alarms are set for suspicious activity (root login, key creation, etc.)
Part 9: The SOA-C03 Connection
Domain 1 (Design Secure Architectures) in SAA becomes Part of Domain 4 in SOA-C03 (Security & Compliance Operations).
In SOA, you’ll go deeper:
- Automated compliance: Use AWS Config Rules to enforce policies
- Logging at scale: Parse CloudTrail logs with Athena
- Incident response: Detect and respond in minutes, not hours
- Operational security: Monitoring, alerting, automation
If you’ve built solid IAM practices here, SOA becomes a walk in the park.
Part 10: Leadership Principle — Earn Trust
This entire post is about earning trust. Your team trusts you with credentials. Your company trusts you with data. Your customers trust you with their information.
How you earn it:
- You don’t share Access Keys
- You rotate credentials on schedule
- You audit permissions quarterly
- You encrypt sensitive data
- You own your mistakes and fix them quickly
Security isn’t a box to check. It’s a promise.
What’s Next?
You’ve locked down identity and access. But that only protects what’s inside your doors.
Post #3 is about resilience. What happens when things break? How do you keep the lights on?
Read it in one week. See you there.
Book your session for more details — https://topmate.io/gaurav_upadhyay18
References & Deep Dives
- AWS Shared Responsibility Model: https://aws.amazon.com/compliance/shared-responsibility-model/
- AWS IAM Best Practices: https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html
- AWS KMS Key Management: https://docs.aws.amazon.com/kms/latest/developerguide/
메타데이터
- post_id
- 3f6d508de566
- slug
- the-security-blueprint-master-iam-before-everything-breaks-3f6d508de566
- url
- https://aws.plainenglish.io/the-security-blueprint-master-iam-before-everything-breaks-3f6d508de566
- canonical_url
- https://aws.plainenglish.io/the-security-blueprint-master-iam-before-everything-breaks-3f6d508de566
- author_url
- https://medium.com/@gaurav-cloud
- status
- ok
- fetched_at
- 2026-06-21 12:17:11