Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help


title: “IAM Policy Structure” created: 2026-07-22 updated: 2026-07-22 type: knowledge tags:

  • aws
  • iam
  • security
  • certification

IAM Policy Structure

What It Is

An IAM Policy is a JSON document that defines permissions. It specifies what actions are allowed or denied on which AWS resources. Policies are the core mechanism for authorization in AWS.

Why It Matters

Every permission decision in AWS goes through policy evaluation. Understanding the JSON structure is critical for writing custom policies, debugging access issues, and passing certification exams.

Key Concepts

Basic Structure

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["service:ActionName"],
      "Resource": ["arn:aws:service:region:account:resource"]
    }
  ]
}

Statement Elements

ElementDescriptionRequiredExample
EffectAllow or DenyYes"Allow"
ActionAPI operations permitted/deniedYes"ec2:DescribeInstances", "s3:GetObject"
ResourceAWS resources the statement applies toYes"arn:aws:s3:::mybucket/*", "*"
ConditionConditions for when the statement appliesNoIP range, time, MFA requirement
PrincipalWho the statement applies to (resource-based policies only)Depends"AWS": "arn:aws:iam::123456789012:root"

Action Format

Actions follow the pattern: service:ActionName

  • ec2:DescribeInstances — describe EC2 instances
  • s3:GetObject — retrieve an object from S3
  • cloudwatch:ListMetrics — list CloudWatch metrics
  • ec2:* — all EC2 actions (wildcard)

Resource Scope

  • "*" — any resource (broad, use carefully)
  • Specific ARN — targets a precise resource (e.g., arn:aws:s3:::mybucket/reports/*)

Multiple Statements

A policy can contain multiple statements. AWS evaluates all applicable policies and statements:

  1. By default, everything is denied (implicit deny)
  2. An explicit Allow overrides the implicit deny
  3. An explicit Deny always wins over any Allow

Real-World Examples

Read-only EC2 (support role):

{
  "Effect": "Allow",
  "Action": [
    "ec2:Describe*",
    "elasticloadbalancing:Describe*",
    "cloudwatch:ListMetrics",
    "cloudwatch:GetMetricStatistics",
    "autoscaling:Describe*"
  ],
  "Resource": "*"
}

EC2 Admin (start/stop):

{
  "Effect": "Allow",
  "Action": [
    "ec2:Describe*",
    "ec2:StartInstances",
    "ec2:StopInstances"
  ],
  "Resource": "*"
}

Gotchas

  • "Version": "2012-10-17" is the current policy language version — always include it
  • An explicit Deny always overrides an Allow (deny wins)
  • Wildcards in Actions (ec2:Describe*) match any action starting with that prefix
  • "Resource": "*" means all resources — fine for Describe actions, dangerous for write actions
  • Identity-based policies (attached to users/groups/roles) don’t have a Principal element — the principal is the entity the policy is attached to

See Also

  • [[iam-managed-vs-inline-policies]]
  • [[iam-groups]]
  • [[iam-users]]
  • [[aws-arns]]
  • [[s3-bucket-policies]]