[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EXCNTNMYFWTTFPKCV24NSW":3,"skill-same:01M6EXCNTNMYFWTTFPKCV24NSW":73},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":44,"commitSha":45,"skillDirectory":46,"forksCount":47,"repositoryHtmlUrl":48,"repositoryHomepageUrl":49,"ownerHtmlUrl":50,"ownerBlogUrl":6,"ownerDescription":51,"updatedAt":52,"install":53,"resources":66},"01M6EXCNTNMYFWTTFPKCV24NSW","aws-iam-best-practices",null,"IAM policy review, hardening, and least privilege implementation","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Faws-iam-best-practices\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"aws iam best practices","best practices","aws","iam","aws iam","least-privilege","kiro-cli","control","kiro","community","implementation","access","hardening","review","access-control","policy","security","safe","cli","2026-11-10 10:12:30",false,"---\nname: aws-iam-best-practices\ndescription: IAM policy review, hardening, and least privilege implementation\nrisk: safe\nsource: community\ncategory: security\ntags: [aws, iam, security, access-control, kiro-cli, least-privilege]\n---\n\n# AWS IAM Best Practices\n\nReview and harden IAM policies following AWS security best practices and least privilege principles.\n\n## When to Use\n\nUse this skill when you need to review IAM policies, implement least privilege access, or harden IAM security.\n\n## Core Principles\n\n**Least Privilege**\n- Grant minimum permissions needed\n- Use managed policies when possible\n- Avoid wildcard (*) permissions\n- Regular access reviews\n\n**Defense in Depth**\n- Enable MFA for all users\n- Use IAM roles instead of access keys\n- Implement service control policies (SCPs)\n- Enable CloudTrail for audit\n\n**Separation of Duties**\n- Separate admin and user roles\n- Use different roles for different environments\n- Implement approval workflows\n- Regular permission audits\n\n## IAM Security Checks\n\n### Find Overly Permissive Policies\n\n```bash\n# List policies with full admin access\naws iam list-policies --scope Local \\\n  --query 'Policies[*].[PolicyName,Arn]' --output table | \\\n  grep -i admin\n\n# Find policies with wildcard actions\naws iam list-policies --scope Local --query 'Policies[*].Arn' --output text | \\\nwhile read arn; do\n  version=$(aws iam get-policy --policy-arn \"$arn\" \\\n    --query 'Policy.DefaultVersionId' --output text)\n  doc=$(aws iam get-policy-version --policy-arn \"$arn\" \\\n    --version-id \"$version\" --query 'PolicyVersion.Document')\n  if echo \"$doc\" | grep -q '\"Action\": \"\\*\"'; then\n    echo \"Wildcard action in: $arn\"\n  fi\ndone\n\n# Find inline policies (should use managed policies)\naws iam list-users --query 'Users[*].UserName' --output text | \\\nwhile read user; do\n  policies=$(aws iam list-user-policies --user-name \"$user\" \\\n    --query 'PolicyNames' --output text)\n  if [ -n \"$policies\" ]; then\n    echo \"Inline policies on user $user: $policies\"\n  fi\ndone\n```\n\n### MFA Enforcement\n\n```bash\n# List users without MFA\naws iam get-credential-report --output text | \\\n  awk -F, 'NR>1 && $4==\"false\" {print $1}'\n\n# Check if MFA is required in policies\naws iam list-policies --scope Local --query 'Policies[*].Arn' --output text | \\\nwhile read arn; do\n  version=$(aws iam get-policy --policy-arn \"$arn\" \\\n    --query 'Policy.DefaultVersionId' --output text)\n  doc=$(aws iam get-policy-version --policy-arn \"$arn\" \\\n    --version-id \"$version\" --query 'PolicyVersion.Document')\n  if echo \"$doc\" | grep -q \"aws:MultiFactorAuthPresent\"; then\n    echo \"MFA enforced in: $arn\"\n  fi\ndone\n\n# Enable MFA for a user (returns QR code)\naws iam create-virtual-mfa-device \\\n  --virtual-mfa-device-name user-mfa \\\n  --outfile \u002Ftmp\u002Fqr.png \\\n  --bootstrap-method QRCodePNG\n```\n\n### Access Key Management\n\n```bash\n# Find old access keys (>90 days)\naws iam list-users --query 'Users[*].UserName' --output text | \\\nwhile read user; do\n  aws iam list-access-keys --user-name \"$user\" \\\n    --query 'AccessKeyMetadata[*].[AccessKeyId,CreateDate,Status]' \\\n    --output text | \\\n  while read key_id create_date status; do\n    age_days=$(( ($(date +%s) - $(date -d \"$create_date\" +%s)) \u002F 86400 ))\n    if [ $age_days -gt 90 ]; then\n      echo \"$user: Key $key_id is $age_days days old\"\n    fi\n  done\ndone\n\n# Rotate access key\nOLD_KEY=\"AKIAIOSFODNN7EXAMPLE\"\nUSER=\"myuser\"\n\n# Create new key\nNEW_KEY=$(aws iam create-access-key --user-name \"$USER\")\necho \"New key created. Update applications, then run:\"\necho \"aws iam delete-access-key --user-name $USER --access-key-id $OLD_KEY\"\n\n# Deactivate old key (test first)\naws iam update-access-key \\\n  --user-name \"$USER\" \\\n  --access-key-id \"$OLD_KEY\" \\\n  --status Inactive\n```\n\n### Role and Policy Analysis\n\n```bash\n# List unused roles (no activity in 90 days)\naws iam list-roles --query 'Roles[*].[RoleName,RoleLastUsed.LastUsedDate]' \\\n  --output text | \\\nwhile read role last_used; do\n  if [ \"$last_used\" = \"None\" ]; then\n    echo \"Never used: $role\"\n  fi\ndone\n\n# Find roles with trust relationships to external accounts\naws iam list-roles --query 'Roles[*].RoleName' --output text | \\\nwhile read role; do\n  trust=$(aws iam get-role --role-name \"$role\" \\\n    --query 'Role.AssumeRolePolicyDocument')\n  if echo \"$trust\" | grep -q '\"AWS\":'; then\n    echo \"External trust: $role\"\n  fi\ndone\n\n# Analyze policy permissions\naws iam simulate-principal-policy \\\n  --policy-source-arn arn:aws:iam::123456789012:user\u002Fmyuser \\\n  --action-names s3:GetObject s3:PutObject \\\n  --resource-arns arn:aws:s3:::mybucket\u002F*\n```\n\n## IAM Policy Templates\n\n### Least Privilege S3 Access\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"s3:GetObject\",\n        \"s3:PutObject\"\n      ],\n      \"Resource\": \"arn:aws:s3:::my-bucket\u002Fuser-data\u002F${aws:username}\u002F*\"\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": \"s3:ListBucket\",\n      \"Resource\": \"arn:aws:s3:::my-bucket\",\n      \"Condition\": {\n        \"StringLike\": {\n          \"s3:prefix\": \"user-data\u002F${aws:username}\u002F*\"\n        }\n      }\n    }\n  ]\n}\n```\n\n### MFA-Required Policy\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Deny\",\n      \"Action\": \"*\",\n      \"Resource\": \"*\",\n      \"Condition\": {\n        \"BoolIfExists\": {\n          \"aws:MultiFactorAuthPresent\": \"false\"\n        }\n      }\n    }\n  ]\n}\n```\n\n### Time-Based Access\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": \"ec2:*\",\n      \"Resource\": \"*\",\n      \"Condition\": {\n        \"DateGreaterThan\": {\n          \"aws:CurrentTime\": \"2026-01-01T00:00:00Z\"\n        },\n        \"DateLessThan\": {\n          \"aws:CurrentTime\": \"2026-12-31T23:59:59Z\"\n        }\n      }\n    }\n  ]\n}\n```\n\n### IP-Restricted Access\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Deny\",\n      \"Action\": \"*\",\n      \"Resource\": \"*\",\n      \"Condition\": {\n        \"NotIpAddress\": {\n          \"aws:SourceIp\": [\n            \"203.0.113.0\u002F24\",\n            \"198.51.100.0\u002F24\"\n          ]\n        }\n      }\n    }\n  ]\n}\n```\n\n## IAM Hardening Checklist\n\n**User Management**\n- [ ] Enable MFA for all users\n- [ ] Remove unused IAM users\n- [ ] Rotate access keys every 90 days\n- [ ] Use IAM roles instead of long-term credentials\n- [ ] Implement password policy (length, complexity, rotation)\n\n**Policy Management**\n- [ ] Replace inline policies with managed policies\n- [ ] Remove wildcard (*) permissions\n- [ ] Implement least privilege\n- [ ] Use policy conditions (MFA, IP, time)\n- [ ] Regular policy reviews\n\n**Role Management**\n- [ ] Use roles for EC2 instances\n- [ ] Implement cross-account roles properly\n- [ ] Review trust relationships\n- [ ] Remove unused roles\n- [ ] Use session tags for fine-grained access\n\n**Monitoring**\n- [ ] Enable CloudTrail for IAM events\n- [ ] Set up CloudWatch alarms for IAM changes\n- [ ] Use AWS IAM Access Analyzer\n- [ ] Regular access reviews\n- [ ] Monitor for privilege escalation\n\n## Automated IAM Hardening\n\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python3\n# iam-hardening.py\n\nimport boto3\nfrom datetime import datetime, timedelta\n\niam = boto3.client('iam')\n\ndef enforce_mfa():\n    \"\"\"Identify users without MFA\"\"\"\n    users = iam.list_users()['Users']\n    no_mfa = []\n    \n    for user in users:\n        mfa_devices = iam.list_mfa_devices(\n            UserName=user['UserName']\n        )['MFADevices']\n        \n        if not mfa_devices:\n            no_mfa.append(user['UserName'])\n    \n    return no_mfa\n\ndef rotate_old_keys():\n    \"\"\"Find access keys older than 90 days\"\"\"\n    users = iam.list_users()['Users']\n    old_keys = []\n    \n    for user in users:\n        keys = iam.list_access_keys(\n            UserName=user['UserName']\n        )['AccessKeyMetadata']\n        \n        for key in keys:\n            age = datetime.now(key['CreateDate'].tzinfo) - key['CreateDate']\n            if age.days > 90:\n                old_keys.append({\n                    'user': user['UserName'],\n                    'key_id': key['AccessKeyId'],\n                    'age_days': age.days\n                })\n    \n    return old_keys\n\ndef find_overpermissive_policies():\n    \"\"\"Find policies with wildcard actions\"\"\"\n    policies = iam.list_policies(Scope='Local')['Policies']\n    overpermissive = []\n    \n    for policy in policies:\n        version = iam.get_policy_version(\n            PolicyArn=policy['Arn'],\n            VersionId=policy['DefaultVersionId']\n        )\n        \n        doc = version['PolicyVersion']['Document']\n        for statement in doc.get('Statement', []):\n            if statement.get('Action') == '*':\n                overpermissive.append(policy['PolicyName'])\n                break\n    \n    return overpermissive\n\nif __name__ == \"__main__\":\n    print(\"IAM Hardening Report\")\n    print(\"=\" * 50)\n    \n    print(\"\\nUsers without MFA:\")\n    for user in enforce_mfa():\n        print(f\"  - {user}\")\n    \n    print(\"\\nOld access keys (>90 days):\")\n    for key in rotate_old_keys():\n        print(f\"  - {key['user']}: {key['age_days']} days\")\n    \n    print(\"\\nOverpermissive policies:\")\n    for policy in find_overpermissive_policies():\n        print(f\"  - {policy}\")\n```\n\n## Example Prompts\n\n- \"Review my IAM policies for security issues\"\n- \"Find users without MFA enabled\"\n- \"Create a least privilege policy for S3 access\"\n- \"Identify overly permissive IAM roles\"\n- \"Generate an IAM hardening report\"\n\n## Best Practices\n\n- Use AWS managed policies when possible\n- Implement policy versioning\n- Test policies in non-production first\n- Document policy purposes\n- Regular access reviews (quarterly)\n- Use IAM Access Analyzer\n- Implement SCPs for organization-wide controls\n\n## Kiro CLI Integration\n\n```bash\nkiro-cli chat \"Use aws-iam-best-practices to review my IAM setup\"\nkiro-cli chat \"Create a least privilege policy with aws-iam-best-practices\"\n```\n\n## Additional Resources\n\n- [IAM Best Practices](https:\u002F\u002Fdocs.aws.amazon.com\u002FIAM\u002Flatest\u002FUserGuide\u002Fbest-practices.html)\n- [IAM Policy Simulator](https:\u002F\u002Fpolicysim.aws.amazon.com\u002F)\n- [IAM Access Analyzer](https:\u002F\u002Faws.amazon.com\u002Fiam\u002Ffeatures\u002Fanalyze-access\u002F)\n","# AWS IAM Best Practices\n\nReview and harden IAM policies following AWS security best practices and least privilege principles.\n\n## When to Use\n\nUse this skill when you need to review IAM policies, implement least privilege access, or harden IAM security.\n\n## Core Principles\n\n**Least Privilege**\n- Grant minimum permissions needed\n- Use managed policies when possible\n- Avoid wildcard (*) permissions\n- Regular access reviews\n\n**Defense in Depth**\n- Enable MFA for all users\n- Use IAM roles instead of access keys\n- Implement service control policies (SCPs)\n- Enable CloudTrail for audit\n\n**Separation of Duties**\n- Separate admin and user roles\n- Use different roles for different environments\n- Implement approval workflows\n- Regular permission audits\n\n## IAM Security Checks\n\n### Find Overly Permissive Policies\n\n```bash\n# List policies with full admin access\naws iam list-policies --scope Local \\\n  --query 'Policies[*].[PolicyName,Arn]' --output table | \\\n  grep -i admin\n\n# Find policies with wildcard actions\naws iam list-policies --scope Local --query 'Policies[*].Arn' --output text | \\\nwhile read arn; do\n  version=$(aws iam get-policy --policy-arn \"$arn\" \\\n    --query 'Policy.DefaultVersionId' --output text)\n  doc=$(aws iam get-policy-version --policy-arn \"$arn\" \\\n    --version-id \"$version\" --query 'PolicyVersion.Document')\n  if echo \"$doc\" | grep -q '\"Action\": \"\\*\"'; then\n    echo \"Wildcard action in: $arn\"\n  fi\ndone\n\n# Find inline policies (should use managed policies)\naws iam list-users --query 'Users[*].UserName' --output text | \\\nwhile read user; do\n  policies=$(aws iam list-user-policies --user-name \"$user\" \\\n    --query 'PolicyNames' --output text)\n  if [ -n \"$policies\" ]; then\n    echo \"Inline policies on user $user: $policies\"\n  fi\ndone\n```\n\n### MFA Enforcement\n\n```bash\n# List users without MFA\naws iam get-credential-report --output text | \\\n  awk -F, 'NR>1 && $4==\"false\" {print $1}'\n\n# Check if MFA is required in policies\naws iam list-policies --scope Local --query 'Policies[*].Arn' --output text | \\\nwhile read arn; do\n  version=$(aws iam get-policy --policy-arn \"$arn\" \\\n    --query 'Policy.DefaultVersionId' --output text)\n  doc=$(aws iam get-policy-version --policy-arn \"$arn\" \\\n    --version-id \"$version\" --query 'PolicyVersion.Document')\n  if echo \"$doc\" | grep -q \"aws:MultiFactorAuthPresent\"; then\n    echo \"MFA enforced in: $arn\"\n  fi\ndone\n\n# Enable MFA for a user (returns QR code)\naws iam create-virtual-mfa-device \\\n  --virtual-mfa-device-name user-mfa \\\n  --outfile \u002Ftmp\u002Fqr.png \\\n  --bootstrap-method QRCodePNG\n```\n\n### Access Key Management\n\n```bash\n# Find old access keys (>90 days)\naws iam list-users --query 'Users[*].UserName' --output text | \\\nwhile read user; do\n  aws iam list-access-keys --user-name \"$user\" \\\n    --query 'AccessKeyMetadata[*].[AccessKeyId,CreateDate,Status]' \\\n    --output text | \\\n  while read key_id create_date status; do\n    age_days=$(( ($(date +%s) - $(date -d \"$create_date\" +%s)) \u002F 86400 ))\n    if [ $age_days -gt 90 ]; then\n      echo \"$user: Key $key_id is $age_days days old\"\n    fi\n  done\ndone\n\n# Rotate access key\nOLD_KEY=\"AKIAIOSFODNN7EXAMPLE\"\nUSER=\"myuser\"\n\n# Create new key\nNEW_KEY=$(aws iam create-access-key --user-name \"$USER\")\necho \"New key created. Update applications, then run:\"\necho \"aws iam delete-access-key --user-name $USER --access-key-id $OLD_KEY\"\n\n# Deactivate old key (test first)\naws iam update-access-key \\\n  --user-name \"$USER\" \\\n  --access-key-id \"$OLD_KEY\" \\\n  --status Inactive\n```\n\n### Role and Policy Analysis\n\n```bash\n# List unused roles (no activity in 90 days)\naws iam list-roles --query 'Roles[*].[RoleName,RoleLastUsed.LastUsedDate]' \\\n  --output text | \\\nwhile read role last_used; do\n  if [ \"$last_used\" = \"None\" ]; then\n    echo \"Never used: $role\"\n  fi\ndone\n\n# Find roles with trust relationships to external accounts\naws iam list-roles --query 'Roles[*].RoleName' --output text | \\\nwhile read role; do\n  trust=$(aws iam get-role --role-name \"$role\" \\\n    --query 'Role.AssumeRolePolicyDocument')\n  if echo \"$trust\" | grep -q '\"AWS\":'; then\n    echo \"External trust: $role\"\n  fi\ndone\n\n# Analyze policy permissions\naws iam simulate-principal-policy \\\n  --policy-source-arn arn:aws:iam::123456789012:user\u002Fmyuser \\\n  --action-names s3:GetObject s3:PutObject \\\n  --resource-arns arn:aws:s3:::mybucket\u002F*\n```\n\n## IAM Policy Templates\n\n### Least Privilege S3 Access\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": [\n        \"s3:GetObject\",\n        \"s3:PutObject\"\n      ],\n      \"Resource\": \"arn:aws:s3:::my-bucket\u002Fuser-data\u002F${aws:username}\u002F*\"\n    },\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": \"s3:ListBucket\",\n      \"Resource\": \"arn:aws:s3:::my-bucket\",\n      \"Condition\": {\n        \"StringLike\": {\n          \"s3:prefix\": \"user-data\u002F${aws:username}\u002F*\"\n        }\n      }\n    }\n  ]\n}\n```\n\n### MFA-Required Policy\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Deny\",\n      \"Action\": \"*\",\n      \"Resource\": \"*\",\n      \"Condition\": {\n        \"BoolIfExists\": {\n          \"aws:MultiFactorAuthPresent\": \"false\"\n        }\n      }\n    }\n  ]\n}\n```\n\n### Time-Based Access\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Allow\",\n      \"Action\": \"ec2:*\",\n      \"Resource\": \"*\",\n      \"Condition\": {\n        \"DateGreaterThan\": {\n          \"aws:CurrentTime\": \"2026-01-01T00:00:00Z\"\n        },\n        \"DateLessThan\": {\n          \"aws:CurrentTime\": \"2026-12-31T23:59:59Z\"\n        }\n      }\n    }\n  ]\n}\n```\n\n### IP-Restricted Access\n\n```json\n{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": [\n    {\n      \"Effect\": \"Deny\",\n      \"Action\": \"*\",\n      \"Resource\": \"*\",\n      \"Condition\": {\n        \"NotIpAddress\": {\n          \"aws:SourceIp\": [\n            \"203.0.113.0\u002F24\",\n            \"198.51.100.0\u002F24\"\n          ]\n        }\n      }\n    }\n  ]\n}\n```\n\n## IAM Hardening Checklist\n\n**User Management**\n- [ ] Enable MFA for all users\n- [ ] Remove unused IAM users\n- [ ] Rotate access keys every 90 days\n- [ ] Use IAM roles instead of long-term credentials\n- [ ] Implement password policy (length, complexity, rotation)\n\n**Policy Management**\n- [ ] Replace inline policies with managed policies\n- [ ] Remove wildcard (*) permissions\n- [ ] Implement least privilege\n- [ ] Use policy conditions (MFA, IP, time)\n- [ ] Regular policy reviews\n\n**Role Management**\n- [ ] Use roles for EC2 instances\n- [ ] Implement cross-account roles properly\n- [ ] Review trust relationships\n- [ ] Remove unused roles\n- [ ] Use session tags for fine-grained access\n\n**Monitoring**\n- [ ] Enable CloudTrail for IAM events\n- [ ] Set up CloudWatch alarms for IAM changes\n- [ ] Use AWS IAM Access Analyzer\n- [ ] Regular access reviews\n- [ ] Monitor for privilege escalation\n\n## Automated IAM Hardening\n\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python3\n# iam-hardening.py\n\nimport boto3\nfrom datetime import datetime, timedelta\n\niam = boto3.client('iam')\n\ndef enforce_mfa():\n    \"\"\"Identify users without MFA\"\"\"\n    users = iam.list_users()['Users']\n    no_mfa = []\n    \n    for user in users:\n        mfa_devices = iam.list_mfa_devices(\n            UserName=user['UserName']\n        )['MFADevices']\n        \n        if not mfa_devices:\n            no_mfa.append(user['UserName'])\n    \n    return no_mfa\n\ndef rotate_old_keys():\n    \"\"\"Find access keys older than 90 days\"\"\"\n    users = iam.list_users()['Users']\n    old_keys = []\n    \n    for user in users:\n        keys = iam.list_access_keys(\n            UserName=user['UserName']\n        )['AccessKeyMetadata']\n        \n        for key in keys:\n            age = datetime.now(key['CreateDate'].tzinfo) - key['CreateDate']\n            if age.days > 90:\n                old_keys.append({\n                    'user': user['UserName'],\n                    'key_id': key['AccessKeyId'],\n                    'age_days': age.days\n                })\n    \n    return old_keys\n\ndef find_overpermissive_policies():\n    \"\"\"Find policies with wildcard actions\"\"\"\n    policies = iam.list_policies(Scope='Local')['Policies']\n    overpermissive = []\n    \n    for policy in policies:\n        version = iam.get_policy_version(\n            PolicyArn=policy['Arn'],\n            VersionId=policy['DefaultVersionId']\n        )\n        \n        doc = version['PolicyVersion']['Document']\n        for statement in doc.get('Statement', []):\n            if statement.get('Action') == '*':\n                overpermissive.append(policy['PolicyName'])\n                break\n    \n    return overpermissive\n\nif __name__ == \"__main__\":\n    print(\"IAM Hardening Report\")\n    print(\"=\" * 50)\n    \n    print(\"\\nUsers without MFA:\")\n    for user in enforce_mfa():\n        print(f\"  - {user}\")\n    \n    print(\"\\nOld access keys (>90 days):\")\n    for key in rotate_old_keys():\n        print(f\"  - {key['user']}: {key['age_days']} days\")\n    \n    print(\"\\nOverpermissive policies:\")\n    for policy in find_overpermissive_policies():\n        print(f\"  - {policy}\")\n```\n\n## Example Prompts\n\n- \"Review my IAM policies for security issues\"\n- \"Find users without MFA enabled\"\n- \"Create a least privilege policy for S3 access\"\n- \"Identify overly permissive IAM roles\"\n- \"Generate an IAM hardening report\"\n\n## Best Practices\n\n- Use AWS managed policies when possible\n- Implement policy versioning\n- Test policies in non-production first\n- Document policy purposes\n- Regular access reviews (quarterly)\n- Use IAM Access Analyzer\n- Implement SCPs for organization-wide controls\n\n## Kiro CLI Integration\n\n```bash\nkiro-cli chat \"Use aws-iam-best-practices to review my IAM setup\"\nkiro-cli chat \"Create a least privilege policy with aws-iam-best-practices\"\n```\n\n## Additional Resources\n\n- [IAM Best Practices](https:\u002F\u002Fdocs.aws.amazon.com\u002FIAM\u002Flatest\u002FUserGuide\u002Fbest-practices.html)\n- [IAM Policy Simulator](https:\u002F\u002Fpolicysim.aws.amazon.com\u002F)\n- [IAM Access Analyzer](https:\u002F\u002Faws.amazon.com\u002Fiam\u002Ffeatures\u002Fanalyze-access\u002F)\n",{"name":5,"risk":36,"tags":43,"source":28,"category":35,"description":7},[21,22,35,33,25,24],"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Faws-iam-best-practices",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":54,"prompt":64,"zipAvailable":65},[55,58,61],{"tool":56,"command":57},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill aws-iam-best-practices",{"tool":59,"command":60},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill aws-iam-best-practices",{"tool":62,"command":63},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill aws-iam-best-practices","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Faws-iam-best-practices\u002FSKILL.md",true,[67],{"path":68,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":71,"sourceHtmlUrl":72},"skill-report.json","REFERENCE","参考文档",10208,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fsickn33\u002Faws-iam-best-practices\u002Fskill-report.json",[74,88,98,107,113,120],{"skillNo":75,"name":76,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":77,"categories":78,"keywords":84,"publishedAt":38},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[79],{"categoryNo":80,"categoryName":81,"taxonomyType":82,"taxonomyTypeDesc":83},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[85,86,87],"model","model hierarchy","model hierarchy skill",{"skillNo":89,"name":90,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":91,"categories":92,"keywords":94,"publishedAt":38},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[93],{"categoryNo":80,"categoryName":81,"taxonomyType":82,"taxonomyTypeDesc":83},[95,96,97],"MCP","zoom","zoom mcp",{"skillNo":99,"name":100,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":101,"categories":102,"keywords":103,"publishedAt":38},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[104,105,106,96],"sdk","zoom apps sdk","apps",{"skillNo":108,"name":109,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":112,"publishedAt":38},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[109],{"skillNo":114,"name":115,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":116,"categories":117,"keywords":119,"publishedAt":38},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[118],{"categoryNo":80,"categoryName":81,"taxonomyType":82,"taxonomyTypeDesc":83},[115],{"skillNo":121,"name":122,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":123,"categories":124,"keywords":125,"publishedAt":38},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[122]]