← All glossary terms
AWS IAM5 min read

What is an AWS IAM Policy?

An AWS IAM Policy is a JSON document that defines permissions in AWS. Learn the policy types, evaluation order, and how to write least-privilege policies.

What is an AWS IAM Policy?

Definition

An AWS IAM Policy is a JSON document that defines permissions in AWS. Policies state what actions are allowed or denied on which resources, optionally under specific conditions.

Policies are attached to identities (users, groups, roles), resources, or scopes (organization-level SCPs), and AWS evaluates them on every API call to authorize the request.

In simple terms:

A policy is a JSON contract: under conditions X, principal Y can/cannot do action Z on resource W.


Why Policies Matter

  • They are the language of AWS authorization.
  • Almost every AWS API call is authorized by policy evaluation.
  • Misconfigured policies are the #1 cause of AWS data exposure.
  • Policies must be carefully written to avoid over-permissioning, privilege escalation, and unintended public exposure.

Anatomy of an IAM Policy

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowS3ReadWithMFA",
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": [
        "arn:aws:s3:::my-bucket",
        "arn:aws:s3:::my-bucket/*"
      ],
      "Condition": {
        "Bool": { "aws:MultiFactorAuthPresent": "true" },
        "IpAddress": { "aws:SourceIp": "203.0.113.0/24" }
      }
    }
  ]
}

Key Elements

  • Version — always 2012-10-17 for current policy language.
  • Statement — array of statements.
  • Sid — optional statement ID.
  • EffectAllow or Deny.
  • Action — API operations (e.g., s3:GetObject).
  • NotAction — opposite of Action; matches everything except.
  • Resource — ARNs the statement applies to.
  • NotResource — opposite of Resource.
  • Principal — used in resource-based and trust policies (who).
  • Condition — context-based restrictions (MFA, IP, time, tags, etc.).

Policy Types

1. Identity-Based Policies

Attached to IAM identities (users, groups, roles).

  • AWS managed — created/maintained by AWS.
  • Customer managed — your reusable policies.
  • Inline — embedded in a specific identity.

2. Resource-Based Policies

Attached to AWS resources (S3 buckets, KMS keys, SNS topics, Lambda, etc.). Define who from where can do what to the resource.

  • Always include Principal.
  • Can grant cross-account access without identity-based policy in source account.

3. Permission Boundaries

A policy attached to a user or role that caps the maximum permissions the principal can have. Even if identity-based policy says Allow, boundary must also allow.

Used to safely delegate IAM administration.

4. Service Control Policies (SCPs)

At the AWS Organizations level. Apply to entire accounts/OUs. SCPs only deny or allow (limit) — they never grant new permissions.

5. Session Policies

Passed during AssumeRole / GetFederationToken to further restrict the resulting session.

6. Resource Control Policies (RCPs)

Newer addition — limit permissions on resources at Organization level (similar to SCPs but resource-side).


Policy Evaluation Logic

For each request, AWS evaluates all applicable policies:

  1. Explicit Deny anywhere → Deny.
  2. Service Control Policies / Resource Control Policies must permit (or be absent).
  3. Permission Boundary must permit (if attached).
  4. Session policy must permit (if assumed role).
  5. Identity-based or resource-based Allow required.
  6. Implicit Deny if no Allow.

A request is allowed only if all relevant scopes allow and none denies.


Common Patterns

Read-Only Auditor

{ "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow", "Action": ["*:Describe*","*:Get*","*:List*"], "Resource": "*"
  }]
}

S3 Bucket Restricted to Single Role

{ "Version": "2012-10-17", "Statement": [
  { "Effect": "Allow",
    "Principal": { "AWS": "arn:aws:iam::111111111111:role/MyAppRole" },
    "Action": ["s3:GetObject"],
    "Resource": "arn:aws:s3:::my-data/*" }
]}

Deny Without MFA (SCP/Identity)

{ "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Deny",
    "Action": "*",
    "Resource": "*",
    "Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" } }
  }]
}

Tag-Based Access

{ "Effect": "Allow",
  "Action": ["ec2:StartInstances", "ec2:StopInstances"],
  "Resource": "*",
  "Condition": {
    "StringEquals": { "ec2:ResourceTag/Owner": "${aws:username}" }
}}

Common Pitfalls

  • Action: "*" and Resource: "*" — admin-equivalent.
  • Wildcards in IAM actions (iam:*) — combined with iam:PassRole, classic escalation.
  • No condition on sensitive permissions.
  • Inline policies sprinkled across identities — hard to audit.
  • Resource-based policies granting cross-account Principal: "*" — accidental public access.
  • Forgotten public S3 bucket policies.
  • Policies allowing iam:CreatePolicyVersion — privilege escalation by replacing policy content.
  • Trust policies trusting Principal: "*" — anyone can assume.
  • Conditions written incorrectly (e.g., aws:MultiFactorAuthPresent: false instead of true).

Real-World Examples

1. Public S3 Bucket via Bucket Policy

Resource-based policy with Principal: "*" and s3:GetObject exposed sensitive data publicly. Common pattern in many breaches.

2. iam:PassRole Privilege Escalation

User has iam:PassRole on a high-privilege role and lambda:CreateFunction. They create a Lambda with the high-privilege role and execute it — escalating to admin.

3. AdministratorAccess Attached "Just for Now"

Developer attaches AdministratorAccess to debug. Never removes. Becomes attack surface.

4. Cross-Account Confused Deputy

Trust policy lets arn:aws:iam::partner-account:root assume the role with no external ID. A different customer of partner could assume your role.


Best Practices

  1. Least privilege — explicit actions and resource ARNs.
  2. Use customer-managed policies with version control (Git).
  3. Avoid *:* policies in production.
  4. Review with IAM Access Analyzer — public/cross-account / unused permission detection.
  5. Use permission boundaries for delegated admin.
  6. Use SCPs for organization-wide guardrails (deny outside region, deny root usage, deny MFA bypass).
  7. MFA conditions on sensitive actions.
  8. External ID in cross-account trust policies.
  9. Tag-based access control where appropriate.
  10. Monitor IAM events in CloudTrail with detections.
  11. Periodic dead-policy cleanup.

Checklist

  • Policies in version control with peer review?
  • No *:* policies in production?
  • IAM Access Analyzer enabled and findings actioned?
  • Permission boundaries on delegated admins?
  • SCPs enforce baseline guardrails?
  • MFA / IP conditions on sensitive actions?
  • External IDs for third-party trust?
  • Quarterly cleanup of unused policies and stale ones?
  • CloudTrail monitoring on policy changes?

How Forestall Helps

Forestall analyzes every policy across every account:

  • Effective permissions per principal.
  • Privilege escalation paths via dangerous IAM patterns.
  • Public/cross-account exposure via resource policies.
  • Stale and unused permissions.
  • Policy-change blast radius prediction.

Frequently Asked Questions

What's the difference between Allow and Deny?

Allow grants permission; Deny overrides any Allow. AWS resolves in favor of Deny.

Can I have multiple statements in one policy?

Yes — each policy can contain many statements; each evaluated independently.

What's the size limit?

Managed policies up to 6,144 characters; inline up to similar; users have aggregate limits. Policy size is a real constraint at scale.

What's iam:PassRole?

Permission to pass a role to an AWS service (so it can assume it). Powerful — must be scoped to specific roles.

How do conditions work?

Condition operators (StringEquals, IpAddress, Bool, etc.) check context keys (aws:SourceIp, aws:MultiFactorAuthPresent, etc.) at request time.


Conclusion

IAM policies are the language of AWS access control. Used carelessly, they create the over-permissioning and escalation paths that drive most AWS breaches. Used carefully — with least privilege, conditions, boundaries, SCPs, version control, peer review, and continuous analysis — they become the rigorous, auditable control surface AWS intends them to be.

AWS IAMIAM PolicyPolicy EvaluationSCPPermission Boundary

Find your overly permissive IAM policies.

Forestall analyzes IAM policies for over-permissioning, escalation paths, and dangerous patterns.

We respect your privacy

We use cookies to keep this site secure and working properly. With your permission, we also use optional cookies to understand usage and improve the experience. Cookie Policy

You can change your choice at any time.

What is an AWS IAM Policy? Definition, Types, and Examples | Forestall