Policies

Within AWS IAM, Policies are objects that define permissions. When attached to an identity (a User, Group, or Role) or a resource, they determine what actions are allowed or denied on that specific asset.

AWS evaluates these policies as structured documents to enforce authorization boundaries across your entire infrastructure.


1. Types of IAM Policies

IAM policies are broken down into categories based on how they are managed and what they are attached to:

Identity-Based Policies

These policies are attached directly to an IAM User, Group, or Role. They specify what that identity can do. Identity-based policies are further split into two types:

  • Managed Policies: Standalone policies created and managed either by AWS (AWS Managed) or by your team (Customer Managed). You can attach a single managed policy to multiple users or roles simultaneously. If you edit a customer-managed policy, the changes instantly apply to every identity holding it.

  • Inline Policies: A policy that is embedded directly into a single specific IAM User, Group, or Role. It maintains a strict 1-to-1 relationship with that identity; if you delete the identity, the inline policy is permanently deleted with it.

Resource-Based Policies

These policies are attached directly to a physical resource (such as an S3 storage bucket, an SQS queue, or an encryption key) rather than an identity.

  • They specify who (which principal) has permission to access that specific resource.

  • Unlike identity-based policies, resource-based policies can allow cross-account access, letting an IAM user from an entirely different AWS account access a resource in your account.


2. The JSON Policy Document Structure

Every IAM policy is written as a structured JSON document. It contains a top-level Version element and an array of one or more Statement objects. Each statement is the core rule block and uses the following explicit parameters:

JSON
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadOnlyAccessToProductionLogs",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::company-production-logs",
        "arn:aws:s3:::company-production-logs/*"
      ],
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "192.0.2.0/24"
        }
      }
    }
  ]
}


Statement ID (Sid)

An optional, user-defined string block that acts as a human-readable label for the specific statement. It helps organize complex policy files containing multiple rules.

Effect

Determines whether the statement results in an explicit Allow or an explicit Deny.

Action

Specifies the exact API operation or list of operations being targeted. These match the service prefix followed by the API call name (e.g., ec2:RunInstances, dynamodb:GetItem, rds:CreateDBInstance). Wildcards can be used to target multiple actions (e.g., s3:* targets every single S3 action).


Resource

Identifies the precise AWS asset the actions are allowed or denied against, structured using an ARN (Amazon Resource Name) format.

  • Standard ARN Syntax: arn:partition:service:region:account-id:resource-id

  • S3 assets do not require a region or account ID in their ARN, which is why the example uses arn:aws:s3:::company-production-logs.


Condition

An optional block that defines the precise criteria or context under which the policy statement is active. It allows you to build advanced security logic, such as:

  • Restricting access to a specific corporate IP address range (aws:SourceIp).

  • Enforcing that the request must use Multi-Factor Authentication (aws:MultiFactorAuthPresent).

  • Validating that data transmission happens strictly over secure HTTPS connections (aws:SecureTransport).