AgentSkillsCN

aws-iam

以最小权限原则创建并调试 AWS IAM 策略。适用于“IAM 策略”、“权限被拒绝”、“访问被拒”、“未获授权”、“创建角色”等场景。

SKILL.md
--- frontmatter
name: aws-iam
description: "Create and debug AWS IAM policies with least-privilege. Use on 'IAM policy', 'permission denied', 'access denied', 'not authorized', 'create role'."

AWS IAM Skill

Create least-privilege IAM policies and debug access issues.

When to Use

  • Create IAM roles/policies
  • Debug "Access Denied" errors
  • Audit existing permissions
  • Set up cross-account access
  • Configure service roles

Policy Principles

Least Privilege

  • Specific actions, not *
  • Specific resources, not *
  • Add Condition blocks when possible
  • Use managed policies over inline

Policy Structure

json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "DescriptiveName",
    "Effect": "Allow",
    "Action": ["s3:GetObject"],
    "Resource": "arn:aws:s3:::bucket/path/*",
    "Condition": {
      "StringEquals": {"aws:PrincipalTag/team": "myteam"}
    }
  }]
}

Debug Access Denied

1. Identify the Error

bash
# Check CloudTrail for denied requests
aws cloudtrail lookup-events \
  --lookup-attributes AttributeKey=EventName,AttributeValue=<operation> \
  --query 'Events[?contains(CloudTrailEvent, `AccessDenied`)]'

2. Simulate Policy

bash
# Test if policy allows action
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789:role/MyRole \
  --action-names s3:GetObject \
  --resource-arns arn:aws:s3:::mybucket/mykey

3. Common Causes

ErrorCheckFix
Explicit denyCheck SCPs, permission boundariesRemove deny statement
Missing actionPolicy doesn't include actionAdd specific action
Wrong resourceARN doesn't matchFix resource ARN pattern
Condition failedCondition block not metCheck tags, VPC, etc.

Common Patterns

S3 Read-Only

json
{
  "Effect": "Allow",
  "Action": ["s3:GetObject", "s3:ListBucket"],
  "Resource": [
    "arn:aws:s3:::bucket",
    "arn:aws:s3:::bucket/*"
  ]
}

Lambda Execution Role

json
{
  "Effect": "Allow",
  "Action": [
    "logs:CreateLogGroup",
    "logs:CreateLogStream",
    "logs:PutLogEvents"
  ],
  "Resource": "arn:aws:logs:*:*:log-group:/aws/lambda/*"
}

EKS Pod Role (IRSA)

json
{
  "Effect": "Allow",
  "Principal": {"Federated": "arn:aws:iam::ACCOUNT:oidc-provider/OIDC"},
  "Action": "sts:AssumeRoleWithWebIdentity",
  "Condition": {
    "StringEquals": {
      "OIDC:sub": "system:serviceaccount:NAMESPACE:SA_NAME"
    }
  }
}

Cross-Account Access

json
{
  "Effect": "Allow",
  "Principal": {"AWS": "arn:aws:iam::OTHER_ACCOUNT:root"},
  "Action": "sts:AssumeRole",
  "Condition": {
    "StringEquals": {"sts:ExternalId": "UNIQUE_ID"}
  }
}

Quick Commands

bash
# List attached policies
aws iam list-attached-role-policies --role-name MyRole

# Get policy document
aws iam get-role-policy --role-name MyRole --policy-name MyPolicy

# Who can assume this role?
aws iam get-role --role-name MyRole --query 'Role.AssumeRolePolicyDocument'

# Test credentials
aws sts get-caller-identity

Red Flags

  • "Action": "*" -> Too broad
  • "Resource": "*" -> Too broad
  • No Condition -> Consider adding
  • Inline policies -> Use managed policies
  • Long-lived access keys -> Use IAM roles