AWS for DevOps — IAM Access Analyzer

2 minute read

13.3 — IAM Access Analyzer

IAM Access Analyzer identifies resources that are shared with external entities — other accounts, public access, or cross-account roles. It answers: “What in my account is accessible from outside?”

Real-World Analogy

IAM Access Analyzer is like a home security audit. An inspector walks through your house checking every door and window: “This back door is unlocked (public S3 bucket), this window faces the neighbor’s yard (cross-account access), this safe has a simple combination (weak IAM policy).” You get a report of everything that needs fixing.

Supported Resource Types

Resource What It Checks
S3 Buckets Public access, cross-account policies
IAM Roles Trust policies allowing external access
KMS Keys Key policies granting external access
Lambda Functions Resource policies allowing external invocation
SQS Queues Queue policies allowing external access
Secrets Manager Resource policies for cross-account access

Creating an Analyzer

# Create an analyzer for the account
$ aws accessanalyzer create-analyzer \
    --analyzer-name account-analyzer \
    --type ACCOUNT
{
    "arn": "arn:aws:access-analyzer:ap-south-1:123456789012:analyzer/account-analyzer"
}

# For organization-wide analysis
$ aws accessanalyzer create-analyzer \
    --analyzer-name org-analyzer \
    --type ORGANIZATION

Viewing Findings

# List all findings
$ aws accessanalyzer list-findings \
    --analyzer-arn arn:aws:access-analyzer:ap-south-1:123456789012:analyzer/account-analyzer
{
    "findings": [
        {
            "id": "finding-123",
            "resourceType": "AWS::S3::Bucket",
            "resource": "arn:aws:s3:::my-public-bucket",
            "principal": {"AWS": "*"},
            "action": ["s3:GetObject"],
            "condition": {},
            "status": "ACTIVE",
            "isPublic": true
        },
        {
            "id": "finding-456",
            "resourceType": "AWS::IAM::Role",
            "resource": "arn:aws:iam::123456789012:role/cross-account-role",
            "principal": {"AWS": "987654321098"},
            "action": ["sts:AssumeRole"],
            "status": "ACTIVE",
            "isPublic": false
        }
    ]
}

Policy Validation

Access Analyzer can also validate IAM policies before you deploy them:

# Validate a policy
$ aws accessanalyzer validate-policy \
    --policy-document '{
      "Version": "2012-10-17",
      "Statement": [{
        "Effect": "Allow",
        "Action": "s3:*",
        "Resource": "*"
      }]
    }' \
    --policy-type IDENTITY_POLICY
{
    "findings": [
        {
            "findingType": "WARNING",
            "issueCode": "PASS_ROLE_WITH_STAR_IN_RESOURCE",
            "learnMoreLink": "https://docs.aws.amazon.com/...",
            "message": "Using wildcards (*) in the resource for iam:PassRole can be overly permissive..."
        }
    ]
}

Policy Generation

Generate least-privilege policies based on actual CloudTrail activity:

# Start policy generation based on last 90 days of activity
$ aws accessanalyzer start-policy-generation \
    --policy-generation-details '{
      "principalArn": "arn:aws:iam::123456789012:role/my-app-role"
    }'
{
    "jobId": "job-abc123"
}

# Get the generated policy
$ aws accessanalyzer get-generated-policy --job-id job-abc123

Common Mistakes

Mistake Why It Hurts Fix
Not creating an analyzer No visibility into external access Create one in every region
Ignoring findings Public resources stay public Triage findings weekly
Not validating policies Overly permissive policies deployed Validate in CI/CD pipeline
Account-level only Miss org-wide risks Use ORGANIZATION type analyzer

Quick Reference

Task Command
Create analyzer aws accessanalyzer create-analyzer --analyzer-name NAME --type ACCOUNT
List findings aws accessanalyzer list-findings --analyzer-arn ARN
Validate policy aws accessanalyzer validate-policy --policy-document '...' --policy-type IDENTITY_POLICY
Generate policy aws accessanalyzer start-policy-generation --policy-generation-details '...'
Archive finding aws accessanalyzer update-findings --analyzer-arn ARN --ids '["ID"]' --status ARCHIVED

Next → KMS Encryption

Updated: