Skip to content

First Validation Tutorial

This tutorial walks you through validating IAM policies step by step, explaining what each check does and why it matters.

What You'll Learn

  • How validation checks work
  • Understanding error messages
  • Fixing common issues
  • Creating a configuration file

Setup

Ensure you have IAM Policy Validator installed:

pip install iam-policy-validator
iam-validator --version

Step 1: Create Sample Policies

Create a directory for this tutorial:

mkdir iam-tutorial
cd iam-tutorial

Policy 1: User Access Policy

Create user-policy.json:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "S3ReadAccess",
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": ["arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*"]
    },
    {
      "Sid": "PassRoleToLambda",
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resource": "arn:aws:iam::123456789012:role/lambda-execution-role"
    }
  ]
}

Policy 2: Admin Policy (Problematic)

Create admin-policy.json:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "FullAdmin",
      "Effect": "Allow",
      "Action": "*",
      "Resource": "*"
    }
  ]
}

Step 2: Run Basic Validation

Validate the user policy:

iam-validator validate --path user-policy.json --format enhanced

Expected Output:

❌ [1/1] user-policy.json • INVALID

Issues (1)
└── 🔴 High
    └── [Statement: PassRoleToLambda @L14] missing_required_condition
        └── Action `iam:PassRole` requires condition `iam:PassedToService`
            └── 💡 Restrict which AWS services can assume the passed role

Understanding the Issue

The iam:PassRole action is flagged because:

  1. What it does: Allows passing an IAM role to AWS services
  2. Why it's risky: Without conditions, any service could use this role
  3. The fix: Add iam:PassedToService condition to restrict which services can use the role

Step 3: Fix the Policy

Update user-policy.json to add the required condition:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "S3ReadAccess",
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": ["arn:aws:s3:::my-bucket", "arn:aws:s3:::my-bucket/*"]
    },
    {
      "Sid": "PassRoleToLambda",
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resource": "arn:aws:iam::123456789012:role/lambda-execution-role",
      "Condition": {
        "StringEquals": {
          "iam:PassedToService": "lambda.amazonaws.com"
        }
      }
    }
  ]
}

Re-run validation:

iam-validator validate --path user-policy.json --format enhanced

Expected Output:

✅ [1/1] user-policy.json • VALID
   0 issues found

Step 4: Validate the Admin Policy

Now check the admin policy:

iam-validator validate --path admin-policy.json --format enhanced

Expected Output:

❌ [1/1] admin-policy.json • INVALID

Issues (1)
└── 🔴 Critical
    └── [Statement: FullAdmin @L4] full_wildcard
        └── Statement allows all actions (*) on all resources (*)
            └── 💡 Replace wildcards with specific actions and resources needed

Why This is Critical

The Action: "*" with Resource: "*" combination:

  • Grants full administrator access to the entire AWS account
  • Equivalent to AdministratorAccess managed policy
  • Should almost never be in custom policies
  • Violates least-privilege principle

Step 5: Validate Multiple Policies

Validate all policies at once:

iam-validator validate --path . --format enhanced

This validates all .json files in the current directory.

Step 6: Create a Configuration File

Create iam-validator.yaml to customize validation:

# Fail on critical and high severity issues
settings:
  fail_on_severity: [error, critical, high]

# Customize check behavior
full_wildcard:
  severity: critical

sensitive_action:
  severity: high

# Require conditions for specific actions
action_condition_enforcement:
  enabled: true
  action_condition_requirements:
    - actions: ["iam:PassRole"]
      required_conditions:
        - condition_key: "iam:PassedToService"
          description: "Restrict which services can assume the role"

Run with configuration:

iam-validator validate --path . --config iam-validator.yaml --format enhanced

Step 7: Output as JSON

For CI/CD pipelines, output as JSON:

iam-validator validate --path user-policy.json --format json

Output:

{
  "summary": {
    "total_policies": 1,
    "valid_policies": 1,
    "invalid_policies": 0,
    "total_issues": 0
  },
  "results": [
    {
      "file": "user-policy.json",
      "is_valid": true,
      "issues": []
    }
  ]
}

Understanding Severity Levels

Severity Meaning Action
Critical Severe security risk Block deployment
High Security concern Fix before merge
Medium Best practice violation Address soon
Low Minor improvement Optional fix
Error AWS will reject Must fix
Warning Potential issue Review

What's Next?

Now that you understand the basics: