
IAM : Identity & Access Management
Today, We'll break down how AWS controls IAM in a nutshell. ๐ชช
In IAM, you manage Principals.
IAM User: A persistent identity for a specific person or service. (Avoid these for services; they use static Access Keys which are a security nightmare).
IAM Group: A collection of users. Use these to apply policies to multiple people at once (e.g., "Dev-Team-Group").
IAM Role: A temporary identity. It doesn't have passwords or keys. Instead, it uses STS (Security Token Service) to get short-lived credentials.d
| Elements | Description | Metaphor |
|---|---|---|
| User | Real Humans | A Employee |
| Group | a set of humans | A Department |
| Role | temporary Privelige | A Visitor Card |
DevOps Tip: Always use Roles for EC2 instances, Lambda functions, and CI/CD pipelines (like GitHub Actions).
Policy = Principal + Permissions (Act)
- Permission : the act of drinking water
- Policy : Jinhyuk is allowed to drink water at 7pm
Action: What to do? (Permissions -> s3:ListBucket)
Resource: To Whom? (always ARN)
Condition: When?
Effect: (Allow / Deny)
Action: What to do? (Permissions -> s3:ListBucket)
Resource: To Whom? (always ARN)
Condition: When?
Policies are JSON documents that define permissions.
Identity-based Policies: Attached to Users, Groups, or Roles.
Rreesource-based Policies: Attached directly to a resource (e.g., S3 Bucket Policy, KMS Key Policy).
- Trust Policy: For Roles, there is a special policy called a Trust Policy. It defines who is allowed to assume this role.
Permissions Boundaries: A "maximum limit" you set for a user so they can't escalate their own privileges.
SCPs (Service Control Policies): Applied at the AWS Organizations level. They act as a guardrail for the entire account.
As a security expert, youโll spend a lot of time auditing these blocks:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSpecificS3Access",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::my-secure-bucket/*",
"Condition": {
"IpAddress": { "aws:SourceIp": "203.0.113.0/24" },
"Bool": { "aws:MultiFactorAuthPresent": "true" }
}
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/BossName"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-boss-bucket/*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
! Tip
There are two ways to allow cross-account users to S3
1. Role as a Proxy
2. S3 Bucket-Policy

Priorities :
"Explicit Deny" rule : If there is a Deny anywhere, the request is rejected, regardless of any Allow.
"Condition": {
"<ConditionOperator>": {
"<ConditionKey>": "<Value | [Values]>"
}
}
everyting is evaluated using & operator within a condition block execpt for value arrays
if you want to express OR operator, use multiple statements instead
{
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "*",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
},
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "*",
"Condition": {
"IpAddress": {
"aws:SourceIp": "10.0.0.0/16"
}
}
}
]
}
10.0.0.0/16 OR MFA

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyAllOutsideSeoul",
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": "ap-northeast-2"
}
}
}
]
}