AWS IAM Policy: What It Is and When to Use It

Definition

An AWS IAM policy is a JSON document that defines permissions in AWS. Each policy contains one or more statements — small blocks that specify whether an action is allowed or denied against a resource under optional conditions. Policies attach to identities (users, groups, roles) or to resources (S3 buckets, KMS keys, SNS topics) and are the language the IAM evaluation engine speaks when it authorizes every single AWS API call.

Because policies can be combined, inherited, and bounded (via SCPs, permission boundaries, and session policies), IAM policies are the single most important security surface in an AWS account — and also the single most common source of access-related misconfigurations.

How It Works

Every IAM policy statement has up to six fields:

  • Version — usually "2012-10-17" (the current policy language version; required for condition keys).
  • EffectAllow or Deny.
  • Action — the API operations the statement applies to, e.g., s3:GetObject, dynamodb:Query. Wildcards (s3:Get*, *) are supported.
  • Resource — one or more Amazon Resource Names (ARNs). Some actions require Resource: "*" because they are not resource-scoped (e.g., ec2:DescribeInstances).
  • Principal — required in resource-based policies to identify who the statement applies to. Omitted in identity-based policies.
  • Condition — a map of condition operators and keys (StringEquals, IpAddress, Bool, DateGreaterThan, ArnLike, etc.) that must evaluate to true for the statement to match.

IAM's evaluation logic combines all applicable policies for a request (identity-based, resource-based, Organizations SCPs, permissions boundaries, session policies) and applies a simple rule: an explicit Deny always wins. If no explicit Deny applies, there must be an Allow from both the identity side (or resource side, for cross-account) and no higher-level guardrail that restricts the action. Anything not explicitly allowed is implicitly denied.

Policy Types

  1. AWS managed policies — authored and maintained by AWS (e.g., AmazonS3ReadOnlyAccess). Versioned; usable across any account.
  2. Customer managed policies — authored by you; can be reused and attached to many identities; support up to 5 versions for rollback.
  3. Inline policies — embedded directly in a single user, group, or role. Cannot be reused; deleted when the identity is deleted.
  4. Identity-based policies — attached to an IAM identity; define what that identity can do.
  5. Resource-based policies — attached to a resource (S3 bucket policy, KMS key policy, Lambda resource policy, SNS topic policy); define who can access the resource, including cross-account principals.
  6. Permissions boundaries — a ceiling policy that limits the maximum effective permissions of a user or role.
  7. Service Control Policies (SCPs) — Organizations-level guardrails that apply to entire accounts or OUs.
  8. Session policies — passed inline to AssumeRole calls; further restrict a session beyond the role's attached policies.

Key Features and Limits

  • Managed policy document size — 6,144 characters (whitespace not counted).
  • Inline policy size — 2,048 chars per user, 5,120 chars per group, 10,240 chars per role.
  • Policy versions — managed policies keep up to 5 versions; older versions must be deleted to publish a new one.
  • Managed policies attached per identity — up to 10 (raised from 10 via quota to higher limits on request).
  • Policy evaluation quotas — SCPs max out at 5 per OU/account attachment point, 5 MB document size per SCP.
  • Condition keys — global (aws:SourceIp, aws:SourceVpc, aws:PrincipalOrgID, aws:MultiFactorAuthPresent, aws:CurrentTime, aws:ResourceTag/*, aws:RequestedRegion) and service-specific (s3:prefix, ec2:InstanceType, etc.).
  • NotAction / NotResource / NotPrincipal — advanced negation elements; powerful but easy to misuse (prefer explicit allows).
  • IAM Access Analyzer policy validation — lints policies for syntax errors, security warnings, and suggestions; also validates against AWS best practices.
  • Policy simulator (IAM Policy Simulator) — lets you test whether a principal can perform specific actions under current policies before deploying them.

Common Use Cases

  1. Least-privilege developer access — scope a developer role to read-only on production and read-write only on sandbox accounts.
  2. S3 bucket policies — grant a specific account, CloudFront OAC, or VPC endpoint access to objects while denying all others.
  3. KMS key policies — the authoritative policy on a KMS key, controlling who can encrypt, decrypt, and manage the key independently of IAM.
  4. Tag-based (ABAC) access — use aws:PrincipalTag and aws:ResourceTag conditions to authorize access based on matching tags instead of writing dozens of role-specific policies.
  5. Cross-account resource sharing — resource-based policy on an S3 bucket or SNS topic that trusts a principal in another account.
  6. Guardrails with SCPs — deny disabling CloudTrail, deny resource creation outside approved Regions, enforce encryption with aws:SecureTransport.

Pricing Model

IAM policies are free to create, attach, evaluate, and store. There is no per-policy, per-statement, or per-evaluation charge.

Optional adjacent services have costs: IAM Access Analyzer external-access findings are free, while unused-access analysis and custom policy checks are priced per analyzed IAM role/user or per policy check. These are inexpensive but not free — budget accordingly when rolling them out org-wide.

Pros and Cons

Pros

  • Extremely expressive: conditions on tags, IP, MFA, org ID, time, VPC endpoint, and hundreds of service-specific keys.
  • Combinable: identity-based + resource-based + SCP + boundary lets you build layered least-privilege with guardrails.
  • Versioning on managed policies enables quick rollback.
  • IAM Access Analyzer and Policy Simulator reduce the cost of writing correct policies.

Cons

  • Easy to over-grant — wildcard actions and resources are tempting when prototyping and often survive to production.
  • Policy evaluation across SCPs, boundaries, resource policies, and sessions is hard to reason about without tooling.
  • Managed policy character limits force complex environments into multiple policies, which can exceed the attachment-per-identity cap.
  • Changes are eventually consistent and can take seconds to propagate, occasionally breaking CI/CD.

Comparison with Alternatives

| Feature | Identity-based Policy | Resource-based Policy | SCP | | --- | --- | --- | --- | | Attached to | User / Group / Role | Resource (S3, KMS, SNS, Lambda, ...) | OU / Account | | Uses Principal? | No | Yes | No | | Cross-account access | Only with STS role chain | Directly grants | Cannot grant — guardrail only | | Primary purpose | What an identity can do | Who can access a resource | Org-wide maximum permissions |

Exam Relevance

IAM policies appear prominently on:

  • Cloud Practitioner (CLF-C02) — basic policy structure and least-privilege principle.
  • Solutions Architect Associate (SAA-C03) — identity vs resource-based policies, cross-account bucket access, KMS key policies.
  • Developer Associate (DVA-C02) — writing Lambda resource policies, S3 presigned URL permissions, parameter-store/secrets access scoping.
  • Security Specialty (SCS-C02) — condition key deep dives, policy evaluation order, permissions boundaries, SCP design.

Frequent exam trap: a scenario gives an identity policy that allows s3:GetObject but the request is still denied. The correct answer is usually that an explicit Deny exists in an SCP, a permissions boundary, or a resource policy — remember explicit deny always wins, regardless of how permissive the identity policy is.

Frequently Asked Questions

Q: What is the difference between a managed policy and an inline policy?

A: A managed policy is a standalone, reusable policy object — either AWS-managed (maintained by AWS) or customer-managed (authored by you) — that can be attached to many identities and supports up to 5 versions for rollback. An inline policy is embedded directly in one user, group, or role, cannot be reused, and is deleted along with the identity. AWS recommends managed policies for most use cases because they're auditable and reusable; inline policies suit one-off tight bindings.

Q: How do identity-based and resource-based policies interact?

A: Identity-based policies are attached to a user, group, or role and say what that identity can do. Resource-based policies are attached to a resource (S3 bucket, KMS key, Lambda function, SNS topic) and say who can access this resource. For same-account access, either an identity-based allow or a resource-based allow is sufficient. For cross-account access, both the caller's identity policy AND the resource policy (or a resource policy + role trust) must allow the action.

Q: What are the size limits for IAM policies?

A: Customer-managed policies are limited to 6,144 characters (not counting whitespace), which is the most common constraint. Inline policies have size caps based on where they're attached: 2,048 characters on a user, 5,120 on a group, and 10,240 on a role. SCPs can be up to 5 MB. When you hit these limits, split the policy into multiple managed policies (up to 10 attachable per identity by default) or use permissions boundaries to enforce ceilings separately from grants.


This article reflects AWS features and pricing as of 2026. AWS services evolve rapidly — always verify against the official AWS IAM Policies documentation before making production decisions.

Published: 4/17/2026 / Updated: 4/17/2026

This article is for informational purposes only. AWS services, pricing, and features change frequently — always verify details against the official AWS documentation before making production decisions.

More in Security