AWS IAM Snippet Pack
Intro: IAM programs become maintainable when repeated patterns are turned into reviewed snippets instead of re-invented in every project. This page is a dense pack of reusable examples for federation, role trust, boundaries, ABAC, and analysis.
What this page includes
- practical JSON and Terraform snippets for common IAM controls
- command examples for validation and access analysis
- commentary on when each pattern is useful and what it protects
Working assumptions
- prefer federation and short-lived credentials over long-lived keys
- trust policies deserve the same review depth as permission policies
1. Trust policy for GitLab OIDC to assume a deployment role
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/gitlab.example.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"gitlab.example.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"gitlab.example.com:sub": "project_path:platform/product-api:ref_type:branch:ref:main"
}
}
}
]
}
Why it helps:
- ties deployment rights to a specific CI identity pattern;
- avoids distributing static AWS access keys into the pipeline;
- keeps the trust boundary readable and reviewable.
2. Permission policy for one deployment role
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EcrPushPull",
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:CompleteLayerUpload",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:UploadLayerPart"
],
"Resource": "*"
},
{
"Sid": "EksReadOnlyDescribe",
"Effect": "Allow",
"Action": [
"eks:DescribeCluster"
],
"Resource": "arn:aws:eks:us-east-1:123456789012:cluster/prod-platform"
}
]
}
3. Permissions boundary for team-created roles
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": [
"iam:*",
"organizations:*",
"account:*"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"logs:*",
"cloudwatch:*",
"s3:GetObject",
"s3:PutObject"
],
"Resource": "*"
}
]
}
Use a permissions boundary when product teams are allowed to create roles but must remain inside a maximum permission envelope.
4. ABAC with principal tags and resource tags
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::team-data-*/*",
"Condition": {
"StringEquals": {
"aws:PrincipalTag/team": "${aws:ResourceTag/team}"
}
}
}
]
}
Use this when you want the same policy logic to scale across many teams or services.
5. STS assume-role with session tags
aws sts assume-role --role-arn arn:aws:iam::123456789012:role/app-deployer --role-session-name product-api-main --tags team=payments env=prod --transitive-tag-keys team env
Session tags are useful when you want access decisions or CloudTrail records to carry workload or team context.
6. IAM Access Analyzer commands
# Create an account analyzer.
aws accessanalyzer create-analyzer --analyzer-name org-security --type ACCOUNT
# List current findings.
aws accessanalyzer list-findings --analyzer-name org-security
Use this to detect unintended external or cross-account access and to validate policy changes before they become normal.
7. IRSA trust policy for EKS workloads
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks.us-east-1.amazonaws.com/id/EXAMPLED539D4633E53DE1B716D3041E:sub": "system:serviceaccount:payments:api"
}
}
}
]
}
Kubernetes service account annotation:
apiVersion: v1
kind: ServiceAccount
metadata:
name: api
namespace: payments
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::123456789012:role/payments-api-irsa
8. Terraform for an IAM role with boundary
resource "aws_iam_role" "app_deployer" {
name = "app-deployer"
permissions_boundary = aws_iam_policy.team_boundary.arn
assume_role_policy = data.aws_iam_policy_document.gitlab_oidc_trust.json
tags = {
owner = "product-security-kb"
env = "prod"
}
}
resource "aws_iam_role_policy_attachment" "deploy_attach" {
role = aws_iam_role.app_deployer.name
policy_arn = aws_iam_policy.app_deployer.arn
}
9. Detect broad policies during review
# Search for wildcard actions before merge.
jq -r '.. | objects | select(.Action? == "*" or (.Action? | type == "array" and index("*") != null))' policy.json
10. Quick design checklist
- Does the trust policy restrict who can assume the role?
- Do you prefer federation or workload identity over static keys?
- Is a permissions boundary needed for delegated role creation?
- Can principal or session tags simplify authorization logic?
- Are external and cross-account paths reviewed with Access Analyzer?
Related pages
Author attribution: Ivan Piskunov, 2026 - Educational and defensive-engineering use.