AWS IAM & S3 Policies Cheat Sheet
Quick reference for AWS IAM and S3 policies: JSON policy structure, actions, conditions, resource ARNs, and least-privilege patterns.
Security Tools
aws
iam
s3
AWS IAM policies are JSON documents that grant or deny actions on resources. Every request is checked against the union of the caller's policies; an explicit Deny always wins over Allow.
Policy Structure
json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadOwnBucket",
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"StringEquals": { "aws:PrincipalAccount": "${aws:username}" }
}
}
]
}
Table
| Field | Purpose | Example |
|---|---|---|
Version | Policy language version | "2012-10-17" |
Statement[] | One or more statements | — |
Effect | Allow or Deny | "Deny" |
Action | API operations | "s3:GetObject", "ec2:*" |
Resource | ARN(s) the actions apply to | "arn:aws:s3:::bucket/*" |
Condition | Context-based restrictions | "IpAddress", "StringEquals" |
Sid | Optional statement identifier | "DenyDeleteLogs" |
Common Action Patterns
json
{ "Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::my-bucket" }
{ "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::my-bucket/*" }
Table
| Service | Common actions |
|---|---|
| S3 | s3:ListBucket, s3:GetObject, s3:PutObject, s3:DeleteObject |
| EC2 | ec2:DescribeInstances, ec2:RunInstances, ec2:StopInstances |
| IAM | iam:CreateUser, iam:AttachUserPolicy |
| Lambda | lambda:InvokeFunction, lambda:CreateFunction |
| DynamoDB | dynamodb:GetItem, dynamodb:Query, dynamodb:PutItem |
| CloudWatch | logs:CreateLogGroup, logs:PutLogEvents |
S3 Bucket Policy
A bucket policy attaches to the bucket itself and can grant access to other accounts or public principals:
json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadForWebsite",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/public/*"
}
]
}
Table
| Key difference from IAM policy | Explanation |
|---|---|
Principal | Who the policy applies to (IAM policies omit it) |
Action / Resource | Same grammar |
| Bucket vs object ARN | :::bucket (list) vs :::bucket/* (objects) |
Least-Privilege Conditions
json
{
"Effect": "Deny",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"Bool": { "aws:SecureTransport": "false" }
}
}
Table
| Condition operator | Use |
|---|---|
StringEquals / StringLike | Exact or wildcard string match |
IpAddress / NotIpAddress | Source IP restrictions |
Bool | Boolean context keys (aws:SecureTransport) |
NumericLessThanEquals | Numeric context keys (s3:MaxKeys) |
ArnEquals / ArnLike | ARN comparisons |
Common Pitfalls
[!WARNING] An explicit
Denystatement overrides allAllows. Use deny-first for global protections like "no S3 delete outside the org".
[!TIP] Attach policies to roles/groups, not users; grant the narrowest
Actionlist possible, and always restrict theResourceARN — never"*"unless truly needed.