[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CVKGC4SY4DPEHN36TNHQGS":3,"skill-same:01M6CVKGC4SY4DPEHN36TNHQGS":86},{"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":36,"linkOnly":37,"markdownContent":38,"markdownBody":39,"frontMatter":40,"refName":42,"commitSha":43,"skillDirectory":44,"forksCount":45,"repositoryHtmlUrl":46,"repositoryHomepageUrl":46,"ownerHtmlUrl":47,"ownerBlogUrl":6,"ownerDescription":48,"updatedAt":49,"install":50,"resources":63},"01M6CVKGC4SY4DPEHN36TNHQGS","aws-iam-best-practices",null,"IAM policy review, hardening, and least privilege implementation","Sam-06060\u002Fjarvis-assistant","Sam-06060","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F208600848?v=4","01M6CRKT7C7FXD21V6HXF293S0","Samson Frank Ganta","01M6CRKTBEKYFD8YX5Z1GT99EE",6,"Apache-2.0","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fsecurity\u002Faws-iam-best-practices\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35],"iam","aws iam best practices","aws iam","aws","best practices","policy","security","access-control","review","least-privilege","hardening","access","safe","implementation","community","[aws, iam, security, access-control, kiro-cli, least-privilege]","cli","2026-11-10 10:12:30",false,"---\nname: aws-iam-best-practices\ndescription: \"IAM policy review, hardening, and least privilege implementation\"\ncategory: security\nrisk: safe\nsource: community\ntags: \"[aws, iam, security, access-control, kiro-cli, least-privilege]\"\ndate_added: \"2026-02-27\"\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\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\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":31,"tags":34,"source":33,"category":25,"date_added":41,"description":7},"2026-02-27","main","a50a3aa6b39fb0e1b7db88bef1bfc9c93606e126","modules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fsecurity\u002Faws-iam-best-practices",0,"https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant","https:\u002F\u002Fgithub.com\u002FSam-06060","Mobile Application Developer | Kotlin | Flutter, KMP, Swfit, Android,Swift UI | Building at Saar It Resources | Creator of Jarvis (AI Assistant)","2026-06-23 05:13:38",{"source":8,"skillName":5,"commands":51,"prompt":61,"zipAvailable":62},[52,55,58],{"tool":53,"command":54},"npx","npx skills add Sam-06060\u002Fjarvis-assistant --skill aws-iam-best-practices",{"tool":56,"command":57},"bunx","bunx skills add Sam-06060\u002Fjarvis-assistant --skill aws-iam-best-practices",{"tool":59,"command":60},"pnpm","pnpm dlx skills add Sam-06060\u002Fjarvis-assistant --skill aws-iam-best-practices","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fsecurity\u002Faws-iam-best-practices\u002FSKILL.md",true,[64,70,74,78,82],{"path":65,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":68,"sourceHtmlUrl":69},"CouncilMembers.md","REFERENCE","参考文档",1497,"https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002FPersonal_AI_Infrastructure\u002FReleases\u002Fv4.0.1\u002F.claude\u002Fskills\u002FThinking\u002FCouncil\u002FCouncilMembers.md",{"path":71,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":72,"sourceHtmlUrl":73},"OutputFormat.md",1551,"https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002FPersonal_AI_Infrastructure\u002FReleases\u002Fv4.0.1\u002F.claude\u002Fskills\u002FThinking\u002FCouncil\u002FOutputFormat.md",{"path":75,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":76,"sourceHtmlUrl":77},"RoundStructure.md",1384,"https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002FPersonal_AI_Infrastructure\u002FReleases\u002Fv4.0.1\u002F.claude\u002Fskills\u002FThinking\u002FCouncil\u002FRoundStructure.md",{"path":79,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":80,"sourceHtmlUrl":81},"Workflows\u002FDebate.md",5492,"https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002FPersonal_AI_Infrastructure\u002FReleases\u002Fv4.0.1\u002F.claude\u002Fskills\u002FThinking\u002FCouncil\u002FWorkflows\u002FDebate.md",{"path":83,"resourceType":66,"resourceTypeDesc":67,"sizeBytes":84,"sourceHtmlUrl":85},"Workflows\u002FQuick.md",1902,"https:\u002F\u002Fgithub.com\u002Ffadrienne\u002FMyGitHub\u002Fblob\u002Fmain\u002FPersonal_AI_Infrastructure\u002FReleases\u002Fv4.0.1\u002F.claude\u002Fskills\u002FThinking\u002FCouncil\u002FWorkflows\u002FQuick.md",[87,100,116,143,162,188],{"skillNo":88,"name":89,"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":90,"categories":91,"keywords":97,"publishedAt":36},"01M6GDRVS6FXX3ESH0C9DW01C0","test_skill","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fscratch\u002Ftest_skill\u002FSKILL.md",[92],{"categoryNo":93,"categoryName":94,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[98,99],"Test Skill","test",{"skillNo":101,"name":102,"nameZh":6,"description":103,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":104,"categories":105,"keywords":106,"publishedAt":36},"01M6GDRQ40HX22MA6XWC31RHHK","zustand-store-ts","Create Zustand stores following established patterns with proper TypeScript types and middleware.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzustand-store-ts\u002FSKILL.md",[],[107,108,109,110,111,112,113,33,114,115],"zustand store ts","zustand","store","with","types","middleware","patterns","create","typescript",{"skillNo":117,"name":118,"nameZh":6,"description":119,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":120,"categories":121,"keywords":125,"publishedAt":36},"01M6GDRKEA0WE670SPFWX5GKCN","zoom-automation","Automate Zoom meeting creation, management, recordings, webinars, and participant tracking via Rube MCP (Composio). Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzoom-automation\u002FSKILL.md",[122],{"categoryNo":123,"categoryName":124,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000023","Skill与智能体开发",[126,127,128,129,130,131,132,133,134,135,136,137,138,139,33,140,141,142],"automation","zoom automation","zoom","first","Tools","search","MCP","via","meeting","automate","critical","creation","webinars","composio","recordings","management","tracking",{"skillNo":144,"name":145,"nameZh":6,"description":146,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":147,"categories":148,"keywords":150,"publishedAt":36},"01M6GDRFS1452PC71JQ38S24HR","zoho-crm-automation","Automate Zoho CRM tasks via Rube MCP (Composio): create\u002Fupdate records, search contacts, manage leads, and convert leads. Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzoho-crm-automation\u002FSKILL.md",[149],{"categoryNo":123,"categoryName":124,"taxonomyType":95,"taxonomyTypeDesc":96},[151,126,152,153,154,155,156,33,131,157,139,158,136,135,130,159,114,160,132,161],"crm automation","zoho crm","crm","zoho crm automation","zoho","leads","contacts","records","update","tasks","manage",{"skillNo":163,"name":164,"nameZh":6,"description":165,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":166,"categories":167,"keywords":171,"publishedAt":36},"01M6GDRCKQBAVTGHX5XBH26KPZ","zod-validation-expert","Expert in Zod — TypeScript-first schema validation. Covers parsing, custom errors, refinements, type inference, and integration with React Hook Form, Next.js, and tRPC.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzod-validation-expert\u002FSKILL.md",[168],{"categoryNo":169,"categoryName":170,"taxonomyType":95,"taxonomyTypeDesc":96},"01JBSEEDCAT000000000000009","前端开发",[172,173,174,175,176,115,31,177,178,179,180,181,110,182,183,184,185,33,186,187],"expert","zod","zod validation expert","validation","react","parsing","errors","schema validation","react hook form","hook","trpc","form","type","next","schema","Next.js",{"skillNo":189,"name":190,"nameZh":6,"description":191,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":192,"categories":193,"keywords":195,"publishedAt":36},"01M6GDR658B08K4MY0RWD4A6EH","zeroize-audit","Detects missing zeroization of sensitive data in source code and identifies zeroization removed by compiler optimizations, with assembly-level analysis, and control-flow verification. Use for auditing C\u002FC++\u002FRust code handling secrets, keys, passwords, or other sensitive data.","https:\u002F\u002Fgithub.com\u002FSam-06060\u002Fjarvis-assistant\u002Fblob\u002Fmain\u002Fmodules\u002Fagent_skills\u002Fawesome-skills\u002Fplaybooks\u002Fzeroize-audit\u002FSKILL.md",[194],{"categoryNo":123,"categoryName":124,"taxonomyType":95,"taxonomyTypeDesc":96},[196,197,198,199,200,201,202,203,33,204,205,206,207,208,209,210,211,212,213,132],"zeroize audit","audit","write","passwords","get","project","c++","activate","assembly","read","Bash","secrets","analysis","data","flow","verification","code","rust"]