diff --git a/README.md b/README.md index 386abb11..6f86bae4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# 🌌 Antigravity Awesome Skills: 883+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Kiro & More +# 🌌 Antigravity Awesome Skills: 887+ Agentic Skills for Claude Code, Gemini CLI, Cursor, Copilot & More -> **The Ultimate Collection of 883+ Universal Agentic Skills for AI Coding Assistants — Claude Code, Gemini CLI, Codex CLI, Kiro CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode, AdaL** +> **The Ultimate Collection of 887+ Universal Agentic Skills for AI Coding Assistants — Claude Code, Gemini CLI, Codex CLI, Antigravity IDE, GitHub Copilot, Cursor, OpenCode, AdaL** [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Claude Code](https://img.shields.io/badge/Claude%20Code-Anthropic-purple)](https://claude.ai) @@ -17,7 +17,7 @@ If this project helps you, you can [support it here](https://buymeacoffee.com/sickn33) or simply ⭐ the repo. -**Antigravity Awesome Skills** is a curated, battle-tested library of **883 high-performance agentic skills** designed to work seamlessly across all major AI coding assistants: +**Antigravity Awesome Skills** is a curated, battle-tested library of **887 high-performance agentic skills** designed to work seamlessly across all major AI coding assistants: - 🟣 **Claude Code** (Anthropic CLI) - 🔵 **Gemini CLI** (Google DeepMind) @@ -41,7 +41,7 @@ This repository provides essential skills to transform your AI assistant into a - [🎁 Curated Collections (Bundles)](#curated-collections) - [🧭 Antigravity Workflows](#antigravity-workflows) - [📦 Features & Categories](#features--categories) -- [📚 Browse 883+ Skills](#browse-883-skills) +- [📚 Browse 887+ Skills](#browse-887-skills) - [🤝 How to Contribute](#how-to-contribute) - [🤝 Community](#community) - [☕ Support the Project](#support-the-project) @@ -318,7 +318,7 @@ The repository is organized into specialized domains to transform your AI into a Counts change as new skills are added. For the current full registry, see [CATALOG.md](CATALOG.md). -## Browse 883+ Skills +## Browse 887+ Skills We have moved the full skill registry to a dedicated catalog to keep this README clean. diff --git a/skills/security/aws-compliance-checker/SKILL.md b/skills/security/aws-compliance-checker/SKILL.md new file mode 100644 index 00000000..b15bea11 --- /dev/null +++ b/skills/security/aws-compliance-checker/SKILL.md @@ -0,0 +1,516 @@ +--- +name: aws-compliance-checker +description: Automated compliance checking against CIS, PCI-DSS, HIPAA, and SOC 2 benchmarks +risk: safe +source: community +category: security +tags: [aws, compliance, audit, cis, pci-dss, hipaa, kiro-cli] +--- + +# AWS Compliance Checker + +Automated compliance validation against industry standards including CIS AWS Foundations, PCI-DSS, HIPAA, and SOC 2. + +## When to Use + +Use this skill when you need to validate AWS compliance against industry standards, prepare for audits, or maintain continuous compliance monitoring. + +## Supported Frameworks + +**CIS AWS Foundations Benchmark** +- Identity and Access Management +- Logging and Monitoring +- Networking +- Data Protection + +**PCI-DSS (Payment Card Industry)** +- Network security +- Access controls +- Encryption +- Monitoring and logging + +**HIPAA (Healthcare)** +- Access controls +- Audit controls +- Data encryption +- Transmission security + +**SOC 2** +- Security +- Availability +- Confidentiality +- Privacy + +## CIS AWS Foundations Checks + +### Identity & Access Management (1.x) + +```bash +#!/bin/bash +# cis-iam-checks.sh + +echo "=== CIS IAM Compliance Checks ===" + +# 1.1: Root account usage +echo "1.1: Checking root account usage..." +root_usage=$(aws iam get-credential-report --output text | \ + awk -F, 'NR==2 {print $5,$11}') +echo " Root password last used: $root_usage" + +# 1.2: MFA on root account +echo "1.2: Checking root MFA..." +root_mfa=$(aws iam get-account-summary \ + --query 'SummaryMap.AccountMFAEnabled' --output text) +echo " Root MFA enabled: $root_mfa" + +# 1.3: Unused credentials +echo "1.3: Checking for unused credentials (>90 days)..." +aws iam get-credential-report --output text | \ + awk -F, 'NR>1 { + if ($5 != "N/A" && $5 != "no_information") { + cmd = "date -d \"" $5 "\" +%s" + cmd | getline last_used + close(cmd) + now = systime() + days = (now - last_used) / 86400 + if (days > 90) print " ⚠️ " $1 ": " int(days) " days inactive" + } + }' + +# 1.4: Access keys rotated +echo "1.4: Checking access key age..." +aws iam list-users --query 'Users[*].UserName' --output text | \ +while read user; do + aws iam list-access-keys --user-name "$user" \ + --query 'AccessKeyMetadata[*].[AccessKeyId,CreateDate]' \ + --output text | \ + while read key_id create_date; do + age_days=$(( ($(date +%s) - $(date -d "$create_date" +%s)) / 86400 )) + if [ $age_days -gt 90 ]; then + echo " ⚠️ $user: Key $key_id is $age_days days old" + fi + done +done + +# 1.5-1.11: Password policy +echo "1.5-1.11: Checking password policy..." +policy=$(aws iam get-account-password-policy 2>&1) +if echo "$policy" | grep -q "NoSuchEntity"; then + echo " ❌ No password policy configured" +else + echo " ✓ Password policy exists" + echo "$policy" | jq '.PasswordPolicy | { + MinimumPasswordLength, + RequireSymbols, + RequireNumbers, + RequireUppercaseCharacters, + RequireLowercaseCharacters, + MaxPasswordAge, + PasswordReusePrevention + }' +fi + +# 1.12-1.14: MFA for IAM users +echo "1.12-1.14: Checking IAM user MFA..." +aws iam get-credential-report --output text | \ + awk -F, 'NR>1 && $4=="false" {print " ⚠️ " $1 ": No MFA"}' +``` + +### Logging (2.x) + +```bash +#!/bin/bash +# cis-logging-checks.sh + +echo "=== CIS Logging Compliance Checks ===" + +# 2.1: CloudTrail enabled +echo "2.1: Checking CloudTrail..." +trails=$(aws cloudtrail describe-trails \ + --query 'trailList[*].[Name,IsMultiRegionTrail,LogFileValidationEnabled]' \ + --output text) + +if [ -z "$trails" ]; then + echo " ❌ No CloudTrail configured" +else + echo "$trails" | while read name multi_region validation; do + echo " Trail: $name" + echo " Multi-region: $multi_region" + echo " Log validation: $validation" + + # Check if logging + status=$(aws cloudtrail get-trail-status --name "$name" \ + --query 'IsLogging' --output text) + echo " Is logging: $status" + done +fi + +# 2.2: CloudTrail log file validation +echo "2.2: Checking log file validation..." +aws cloudtrail describe-trails \ + --query 'trailList[?LogFileValidationEnabled==`false`].Name' \ + --output text | \ +while read trail; do + echo " ⚠️ $trail: Log validation disabled" +done + +# 2.3: S3 bucket for CloudTrail +echo "2.3: Checking CloudTrail S3 bucket access..." +aws cloudtrail describe-trails \ + --query 'trailList[*].S3BucketName' --output text | \ +while read bucket; do + public=$(aws s3api get-bucket-acl --bucket "$bucket" 2>&1 | \ + grep -c "AllUsers") + if [ "$public" -gt 0 ]; then + echo " ❌ $bucket: Publicly accessible" + else + echo " ✓ $bucket: Not public" + fi +done + +# 2.4: CloudTrail integrated with CloudWatch Logs +echo "2.4: Checking CloudWatch Logs integration..." +aws cloudtrail describe-trails \ + --query 'trailList[*].[Name,CloudWatchLogsLogGroupArn]' \ + --output text | \ +while read name log_group; do + if [ "$log_group" = "None" ]; then + echo " ⚠️ $name: Not integrated with CloudWatch Logs" + else + echo " ✓ $name: Integrated with CloudWatch" + fi +done + +# 2.5: AWS Config enabled +echo "2.5: Checking AWS Config..." +recorders=$(aws configservice describe-configuration-recorders \ + --query 'ConfigurationRecorders[*].name' --output text) + +if [ -z "$recorders" ]; then + echo " ❌ AWS Config not enabled" +else + echo " ✓ AWS Config enabled: $recorders" +fi + +# 2.6: S3 bucket logging +echo "2.6: Checking S3 bucket logging..." +aws s3api list-buckets --query 'Buckets[*].Name' --output text | \ +while read bucket; do + logging=$(aws s3api get-bucket-logging --bucket "$bucket" 2>&1) + if ! echo "$logging" | grep -q "LoggingEnabled"; then + echo " ⚠️ $bucket: Access logging disabled" + fi +done + +# 2.7: VPC Flow Logs +echo "2.7: Checking VPC Flow Logs..." +aws ec2 describe-vpcs --query 'Vpcs[*].VpcId' --output text | \ +while read vpc; do + flow_logs=$(aws ec2 describe-flow-logs \ + --filter "Name=resource-id,Values=$vpc" \ + --query 'FlowLogs[*].FlowLogId' --output text) + if [ -z "$flow_logs" ]; then + echo " ⚠️ $vpc: No flow logs enabled" + else + echo " ✓ $vpc: Flow logs enabled" + fi +done +``` + +### Monitoring (3.x) + +```bash +#!/bin/bash +# cis-monitoring-checks.sh + +echo "=== CIS Monitoring Compliance Checks ===" + +# Check for required CloudWatch metric filters and alarms +required_filters=( + "unauthorized-api-calls" + "no-mfa-console-signin" + "root-usage" + "iam-changes" + "cloudtrail-changes" + "console-signin-failures" + "cmk-changes" + "s3-bucket-policy-changes" + "aws-config-changes" + "security-group-changes" + "nacl-changes" + "network-gateway-changes" + "route-table-changes" + "vpc-changes" +) + +log_group=$(aws cloudtrail describe-trails \ + --query 'trailList[0].CloudWatchLogsLogGroupArn' \ + --output text | cut -d: -f7) + +if [ -z "$log_group" ] || [ "$log_group" = "None" ]; then + echo " ❌ CloudTrail not integrated with CloudWatch Logs" +else + echo "Checking metric filters for log group: $log_group" + + existing_filters=$(aws logs describe-metric-filters \ + --log-group-name "$log_group" \ + --query 'metricFilters[*].filterName' --output text) + + for filter in "${required_filters[@]}"; do + if echo "$existing_filters" | grep -q "$filter"; then + echo " ✓ $filter: Configured" + else + echo " ⚠️ $filter: Missing" + fi + done +fi +``` + +### Networking (4.x) + +```bash +#!/bin/bash +# cis-networking-checks.sh + +echo "=== CIS Networking Compliance Checks ===" + +# 4.1: No security groups allow 0.0.0.0/0 ingress to port 22 +echo "4.1: Checking SSH access (port 22)..." +aws ec2 describe-security-groups \ + --query 'SecurityGroups[*].[GroupId,GroupName,IpPermissions]' \ + --output json | \ +jq -r '.[] | select(.[2][]? | + select(.FromPort == 22 and .IpRanges[]?.CidrIp == "0.0.0.0/0")) | + " ⚠️ \(.[0]): \(.[1]) allows SSH from 0.0.0.0/0"' + +# 4.2: No security groups allow 0.0.0.0/0 ingress to port 3389 +echo "4.2: Checking RDP access (port 3389)..." +aws ec2 describe-security-groups \ + --query 'SecurityGroups[*].[GroupId,GroupName,IpPermissions]' \ + --output json | \ +jq -r '.[] | select(.[2][]? | + select(.FromPort == 3389 and .IpRanges[]?.CidrIp == "0.0.0.0/0")) | + " ⚠️ \(.[0]): \(.[1]) allows RDP from 0.0.0.0/0"' + +# 4.3: Default security group restricts all traffic +echo "4.3: Checking default security groups..." +aws ec2 describe-security-groups \ + --filters Name=group-name,Values=default \ + --query 'SecurityGroups[*].[GroupId,IpPermissions,IpPermissionsEgress]' \ + --output json | \ +jq -r '.[] | select((.[1] | length) > 0 or (.[2] | length) > 1) | + " ⚠️ \(.[0]): Default SG has rules"' +``` + +## PCI-DSS Compliance Checks + +```python +#!/usr/bin/env python3 +# pci-dss-checker.py + +import boto3 + +def check_pci_compliance(): + """Check PCI-DSS requirements""" + + ec2 = boto3.client('ec2') + rds = boto3.client('rds') + s3 = boto3.client('s3') + + issues = [] + + # Requirement 1: Network security + sgs = ec2.describe_security_groups() + for sg in sgs['SecurityGroups']: + for perm in sg.get('IpPermissions', []): + for ip_range in perm.get('IpRanges', []): + if ip_range.get('CidrIp') == '0.0.0.0/0': + issues.append(f"PCI 1.2: {sg['GroupId']} open to internet") + + # Requirement 2: Secure configurations + # Check for default passwords, etc. + + # Requirement 3: Protect cardholder data + volumes = ec2.describe_volumes() + for vol in volumes['Volumes']: + if not vol['Encrypted']: + issues.append(f"PCI 3.4: Volume {vol['VolumeId']} not encrypted") + + # Requirement 4: Encrypt transmission + # Check for SSL/TLS on load balancers + + # Requirement 8: Access controls + iam = boto3.client('iam') + users = iam.list_users() + for user in users['Users']: + mfa = iam.list_mfa_devices(UserName=user['UserName']) + if not mfa['MFADevices']: + issues.append(f"PCI 8.3: {user['UserName']} no MFA") + + # Requirement 10: Logging + cloudtrail = boto3.client('cloudtrail') + trails = cloudtrail.describe_trails() + if not trails['trailList']: + issues.append("PCI 10.1: No CloudTrail enabled") + + return issues + +if __name__ == "__main__": + print("PCI-DSS Compliance Check") + print("=" * 50) + + issues = check_pci_compliance() + + if not issues: + print("✓ No PCI-DSS issues found") + else: + print(f"Found {len(issues)} issues:\n") + for issue in issues: + print(f" ⚠️ {issue}") +``` + +## HIPAA Compliance Checks + +```bash +#!/bin/bash +# hipaa-checker.sh + +echo "=== HIPAA Compliance Checks ===" + +# Access Controls (164.308(a)(3)) +echo "Access Controls:" +aws iam get-credential-report --output text | \ + awk -F, 'NR>1 && $4=="false" {print " ⚠️ " $1 ": No MFA (164.312(a)(2)(i))"}' + +# Audit Controls (164.312(b)) +echo "" +echo "Audit Controls:" +trails=$(aws cloudtrail describe-trails --query 'trailList[*].Name' --output text) +if [ -z "$trails" ]; then + echo " ❌ No CloudTrail (164.312(b))" +else + echo " ✓ CloudTrail enabled" +fi + +# Encryption (164.312(a)(2)(iv)) +echo "" +echo "Encryption at Rest:" +aws ec2 describe-volumes \ + --query 'Volumes[?Encrypted==`false`].VolumeId' \ + --output text | \ +while read vol; do + echo " ⚠️ $vol: Not encrypted (164.312(a)(2)(iv))" +done + +aws rds describe-db-instances \ + --query 'DBInstances[?StorageEncrypted==`false`].DBInstanceIdentifier' \ + --output text | \ +while read db; do + echo " ⚠️ $db: Not encrypted (164.312(a)(2)(iv))" +done + +# Transmission Security (164.312(e)(1)) +echo "" +echo "Transmission Security:" +echo " Check: All data in transit uses TLS 1.2+" +``` + +## Automated Compliance Reporting + +```python +#!/usr/bin/env python3 +# compliance-report.py + +import boto3 +import json +from datetime import datetime + +def generate_compliance_report(framework='cis'): + """Generate comprehensive compliance report""" + + report = { + 'framework': framework, + 'generated': datetime.now().isoformat(), + 'checks': [], + 'summary': { + 'total': 0, + 'passed': 0, + 'failed': 0, + 'score': 0 + } + } + + # Run all checks based on framework + if framework == 'cis': + checks = run_cis_checks() + elif framework == 'pci': + checks = run_pci_checks() + elif framework == 'hipaa': + checks = run_hipaa_checks() + + report['checks'] = checks + report['summary']['total'] = len(checks) + report['summary']['passed'] = sum(1 for c in checks if c['status'] == 'PASS') + report['summary']['failed'] = report['summary']['total'] - report['summary']['passed'] + report['summary']['score'] = (report['summary']['passed'] / report['summary']['total']) * 100 + + return report + +def run_cis_checks(): + # Implement CIS checks + return [] + +def run_pci_checks(): + # Implement PCI checks + return [] + +def run_hipaa_checks(): + # Implement HIPAA checks + return [] + +if __name__ == "__main__": + import sys + framework = sys.argv[1] if len(sys.argv) > 1 else 'cis' + + report = generate_compliance_report(framework) + + print(f"\n{framework.upper()} Compliance Report") + print("=" * 50) + print(f"Score: {report['summary']['score']:.1f}%") + print(f"Passed: {report['summary']['passed']}/{report['summary']['total']}") + print(f"Failed: {report['summary']['failed']}/{report['summary']['total']}") + + # Save to file + with open(f'compliance-{framework}-{datetime.now().strftime("%Y%m%d")}.json', 'w') as f: + json.dump(report, f, indent=2) +``` + +## Example Prompts + +- "Run CIS AWS Foundations compliance check" +- "Generate a PCI-DSS compliance report" +- "Check HIPAA compliance for my AWS account" +- "Audit against SOC 2 requirements" +- "Create a compliance dashboard" + +## Best Practices + +- Run compliance checks weekly +- Automate with Lambda/EventBridge +- Track compliance trends over time +- Document exceptions with justification +- Integrate with AWS Security Hub +- Use AWS Config Rules for continuous monitoring + +## Kiro CLI Integration + +```bash +kiro-cli chat "Use aws-compliance-checker to run CIS benchmark" +kiro-cli chat "Generate PCI-DSS report with aws-compliance-checker" +``` + +## Additional Resources + +- [CIS AWS Foundations Benchmark](https://www.cisecurity.org/benchmark/amazon_web_services) +- [AWS Security Hub](https://aws.amazon.com/security-hub/) +- [AWS Compliance Programs](https://aws.amazon.com/compliance/programs/) diff --git a/skills/security/aws-iam-best-practices/SKILL.md b/skills/security/aws-iam-best-practices/SKILL.md new file mode 100644 index 00000000..381c8fa0 --- /dev/null +++ b/skills/security/aws-iam-best-practices/SKILL.md @@ -0,0 +1,397 @@ +--- +name: aws-iam-best-practices +description: IAM policy review, hardening, and least privilege implementation +risk: safe +source: community +category: security +tags: [aws, iam, security, access-control, kiro-cli, least-privilege] +--- + +# AWS IAM Best Practices + +Review and harden IAM policies following AWS security best practices and least privilege principles. + +## When to Use + +Use this skill when you need to review IAM policies, implement least privilege access, or harden IAM security. + +## Core Principles + +**Least Privilege** +- Grant minimum permissions needed +- Use managed policies when possible +- Avoid wildcard (*) permissions +- Regular access reviews + +**Defense in Depth** +- Enable MFA for all users +- Use IAM roles instead of access keys +- Implement service control policies (SCPs) +- Enable CloudTrail for audit + +**Separation of Duties** +- Separate admin and user roles +- Use different roles for different environments +- Implement approval workflows +- Regular permission audits + +## IAM Security Checks + +### Find Overly Permissive Policies + +```bash +# List policies with full admin access +aws iam list-policies --scope Local \ + --query 'Policies[*].[PolicyName,Arn]' --output table | \ + grep -i admin + +# Find policies with wildcard actions +aws iam list-policies --scope Local --query 'Policies[*].Arn' --output text | \ +while read arn; do + version=$(aws iam get-policy --policy-arn "$arn" \ + --query 'Policy.DefaultVersionId' --output text) + doc=$(aws iam get-policy-version --policy-arn "$arn" \ + --version-id "$version" --query 'PolicyVersion.Document') + if echo "$doc" | grep -q '"Action": "\*"'; then + echo "Wildcard action in: $arn" + fi +done + +# Find inline policies (should use managed policies) +aws iam list-users --query 'Users[*].UserName' --output text | \ +while read user; do + policies=$(aws iam list-user-policies --user-name "$user" \ + --query 'PolicyNames' --output text) + if [ -n "$policies" ]; then + echo "Inline policies on user $user: $policies" + fi +done +``` + +### MFA Enforcement + +```bash +# List users without MFA +aws iam get-credential-report --output text | \ + awk -F, 'NR>1 && $4=="false" {print $1}' + +# Check if MFA is required in policies +aws iam list-policies --scope Local --query 'Policies[*].Arn' --output text | \ +while read arn; do + version=$(aws iam get-policy --policy-arn "$arn" \ + --query 'Policy.DefaultVersionId' --output text) + doc=$(aws iam get-policy-version --policy-arn "$arn" \ + --version-id "$version" --query 'PolicyVersion.Document') + if echo "$doc" | grep -q "aws:MultiFactorAuthPresent"; then + echo "MFA enforced in: $arn" + fi +done + +# Enable MFA for a user (returns QR code) +aws iam create-virtual-mfa-device \ + --virtual-mfa-device-name user-mfa \ + --outfile /tmp/qr.png \ + --bootstrap-method QRCodePNG +``` + +### Access Key Management + +```bash +# Find old access keys (>90 days) +aws iam list-users --query 'Users[*].UserName' --output text | \ +while read user; do + aws iam list-access-keys --user-name "$user" \ + --query 'AccessKeyMetadata[*].[AccessKeyId,CreateDate,Status]' \ + --output text | \ + while read key_id create_date status; do + age_days=$(( ($(date +%s) - $(date -d "$create_date" +%s)) / 86400 )) + if [ $age_days -gt 90 ]; then + echo "$user: Key $key_id is $age_days days old" + fi + done +done + +# Rotate access key +OLD_KEY="AKIAIOSFODNN7EXAMPLE" +USER="myuser" + +# Create new key +NEW_KEY=$(aws iam create-access-key --user-name "$USER") +echo "New key created. Update applications, then run:" +echo "aws iam delete-access-key --user-name $USER --access-key-id $OLD_KEY" + +# Deactivate old key (test first) +aws iam update-access-key \ + --user-name "$USER" \ + --access-key-id "$OLD_KEY" \ + --status Inactive +``` + +### Role and Policy Analysis + +```bash +# List unused roles (no activity in 90 days) +aws iam list-roles --query 'Roles[*].[RoleName,RoleLastUsed.LastUsedDate]' \ + --output text | \ +while read role last_used; do + if [ "$last_used" = "None" ]; then + echo "Never used: $role" + fi +done + +# Find roles with trust relationships to external accounts +aws iam list-roles --query 'Roles[*].RoleName' --output text | \ +while read role; do + trust=$(aws iam get-role --role-name "$role" \ + --query 'Role.AssumeRolePolicyDocument') + if echo "$trust" | grep -q '"AWS":'; then + echo "External trust: $role" + fi +done + +# Analyze policy permissions +aws iam simulate-principal-policy \ + --policy-source-arn arn:aws:iam::123456789012:user/myuser \ + --action-names s3:GetObject s3:PutObject \ + --resource-arns arn:aws:s3:::mybucket/* +``` + +## IAM Policy Templates + +### Least Privilege S3 Access + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "s3:GetObject", + "s3:PutObject" + ], + "Resource": "arn:aws:s3:::my-bucket/user-data/${aws:username}/*" + }, + { + "Effect": "Allow", + "Action": "s3:ListBucket", + "Resource": "arn:aws:s3:::my-bucket", + "Condition": { + "StringLike": { + "s3:prefix": "user-data/${aws:username}/*" + } + } + } + ] +} +``` + +### MFA-Required Policy + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Deny", + "Action": "*", + "Resource": "*", + "Condition": { + "BoolIfExists": { + "aws:MultiFactorAuthPresent": "false" + } + } + } + ] +} +``` + +### Time-Based Access + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "ec2:*", + "Resource": "*", + "Condition": { + "DateGreaterThan": { + "aws:CurrentTime": "2026-01-01T00:00:00Z" + }, + "DateLessThan": { + "aws:CurrentTime": "2026-12-31T23:59:59Z" + } + } + } + ] +} +``` + +### IP-Restricted Access + +```json +{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Deny", + "Action": "*", + "Resource": "*", + "Condition": { + "NotIpAddress": { + "aws:SourceIp": [ + "203.0.113.0/24", + "198.51.100.0/24" + ] + } + } + } + ] +} +``` + +## IAM Hardening Checklist + +**User Management** +- [ ] Enable MFA for all users +- [ ] Remove unused IAM users +- [ ] Rotate access keys every 90 days +- [ ] Use IAM roles instead of long-term credentials +- [ ] Implement password policy (length, complexity, rotation) + +**Policy Management** +- [ ] Replace inline policies with managed policies +- [ ] Remove wildcard (*) permissions +- [ ] Implement least privilege +- [ ] Use policy conditions (MFA, IP, time) +- [ ] Regular policy reviews + +**Role Management** +- [ ] Use roles for EC2 instances +- [ ] Implement cross-account roles properly +- [ ] Review trust relationships +- [ ] Remove unused roles +- [ ] Use session tags for fine-grained access + +**Monitoring** +- [ ] Enable CloudTrail for IAM events +- [ ] Set up CloudWatch alarms for IAM changes +- [ ] Use AWS IAM Access Analyzer +- [ ] Regular access reviews +- [ ] Monitor for privilege escalation + +## Automated IAM Hardening + +```python +#!/usr/bin/env python3 +# iam-hardening.py + +import boto3 +from datetime import datetime, timedelta + +iam = boto3.client('iam') + +def enforce_mfa(): + """Identify users without MFA""" + users = iam.list_users()['Users'] + no_mfa = [] + + for user in users: + mfa_devices = iam.list_mfa_devices( + UserName=user['UserName'] + )['MFADevices'] + + if not mfa_devices: + no_mfa.append(user['UserName']) + + return no_mfa + +def rotate_old_keys(): + """Find access keys older than 90 days""" + users = iam.list_users()['Users'] + old_keys = [] + + for user in users: + keys = iam.list_access_keys( + UserName=user['UserName'] + )['AccessKeyMetadata'] + + for key in keys: + age = datetime.now(key['CreateDate'].tzinfo) - key['CreateDate'] + if age.days > 90: + old_keys.append({ + 'user': user['UserName'], + 'key_id': key['AccessKeyId'], + 'age_days': age.days + }) + + return old_keys + +def find_overpermissive_policies(): + """Find policies with wildcard actions""" + policies = iam.list_policies(Scope='Local')['Policies'] + overpermissive = [] + + for policy in policies: + version = iam.get_policy_version( + PolicyArn=policy['Arn'], + VersionId=policy['DefaultVersionId'] + ) + + doc = version['PolicyVersion']['Document'] + for statement in doc.get('Statement', []): + if statement.get('Action') == '*': + overpermissive.append(policy['PolicyName']) + break + + return overpermissive + +if __name__ == "__main__": + print("IAM Hardening Report") + print("=" * 50) + + print("\nUsers without MFA:") + for user in enforce_mfa(): + print(f" - {user}") + + print("\nOld access keys (>90 days):") + for key in rotate_old_keys(): + print(f" - {key['user']}: {key['age_days']} days") + + print("\nOverpermissive policies:") + for policy in find_overpermissive_policies(): + print(f" - {policy}") +``` + +## Example Prompts + +- "Review my IAM policies for security issues" +- "Find users without MFA enabled" +- "Create a least privilege policy for S3 access" +- "Identify overly permissive IAM roles" +- "Generate an IAM hardening report" + +## Best Practices + +- Use AWS managed policies when possible +- Implement policy versioning +- Test policies in non-production first +- Document policy purposes +- Regular access reviews (quarterly) +- Use IAM Access Analyzer +- Implement SCPs for organization-wide controls + +## Kiro CLI Integration + +```bash +kiro-cli chat "Use aws-iam-best-practices to review my IAM setup" +kiro-cli chat "Create a least privilege policy with aws-iam-best-practices" +``` + +## Additional Resources + +- [IAM Best Practices](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html) +- [IAM Policy Simulator](https://policysim.aws.amazon.com/) +- [IAM Access Analyzer](https://aws.amazon.com/iam/features/analyze-access/) diff --git a/skills/security/aws-secrets-rotation/SKILL.md b/skills/security/aws-secrets-rotation/SKILL.md new file mode 100644 index 00000000..663dfb73 --- /dev/null +++ b/skills/security/aws-secrets-rotation/SKILL.md @@ -0,0 +1,465 @@ +--- +name: aws-secrets-rotation +description: Automate AWS secrets rotation for RDS, API keys, and credentials +risk: safe +source: community +category: security +tags: [aws, secrets-manager, security, automation, kiro-cli, credentials] +--- + +# AWS Secrets Rotation + +Automate rotation of secrets, credentials, and API keys using AWS Secrets Manager and Lambda. + +## When to Use + +Use this skill when you need to implement automated secrets rotation, manage credentials securely, or comply with security policies requiring regular key rotation. + +## Supported Secret Types + +**AWS Services** +- RDS database credentials +- DocumentDB credentials +- Redshift credentials +- ElastiCache credentials + +**Third-Party Services** +- API keys +- OAuth tokens +- SSH keys +- Custom credentials + +## Secrets Manager Setup + +### Create a Secret + +```bash +# Create RDS secret +aws secretsmanager create-secret \ + --name prod/db/mysql \ + --description "Production MySQL credentials" \ + --secret-string '{ + "username": "admin", + "password": "CHANGE_ME", + "engine": "mysql", + "host": "mydb.cluster-abc.us-east-1.rds.amazonaws.com", + "port": 3306, + "dbname": "myapp" + }' + +# Create API key secret +aws secretsmanager create-secret \ + --name prod/api/stripe \ + --secret-string '{ + "api_key": "sk_live_xxxxx", + "webhook_secret": "whsec_xxxxx" + }' + +# Create secret from file +aws secretsmanager create-secret \ + --name prod/ssh/private-key \ + --secret-binary fileb://~/.ssh/id_rsa +``` + +### Retrieve Secrets + +```bash +# Get secret value +aws secretsmanager get-secret-value \ + --secret-id prod/db/mysql \ + --query 'SecretString' --output text + +# Get specific field +aws secretsmanager get-secret-value \ + --secret-id prod/db/mysql \ + --query 'SecretString' --output text | \ + jq -r '.password' + +# Get binary secret +aws secretsmanager get-secret-value \ + --secret-id prod/ssh/private-key \ + --query 'SecretBinary' --output text | \ + base64 -d > private-key.pem +``` + +## Automatic Rotation Setup + +### Enable RDS Rotation + +```bash +# Enable automatic rotation (30 days) +aws secretsmanager rotate-secret \ + --secret-id prod/db/mysql \ + --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:SecretsManagerRDSMySQLRotation \ + --rotation-rules AutomaticallyAfterDays=30 + +# Rotate immediately +aws secretsmanager rotate-secret \ + --secret-id prod/db/mysql + +# Check rotation status +aws secretsmanager describe-secret \ + --secret-id prod/db/mysql \ + --query 'RotationEnabled' +``` + +### Lambda Rotation Function + +```python +# lambda_rotation.py +import boto3 +import json +import os + +secrets_client = boto3.client('secretsmanager') +rds_client = boto3.client('rds') + +def lambda_handler(event, context): + """Rotate RDS MySQL password""" + + secret_arn = event['SecretId'] + token = event['ClientRequestToken'] + step = event['Step'] + + # Get current secret + current = secrets_client.get_secret_value(SecretId=secret_arn) + secret = json.loads(current['SecretString']) + + if step == "createSecret": + # Generate new password + new_password = generate_password() + secret['password'] = new_password + + # Store as pending + secrets_client.put_secret_value( + SecretId=secret_arn, + ClientRequestToken=token, + SecretString=json.dumps(secret), + VersionStages=['AWSPENDING'] + ) + + elif step == "setSecret": + # Update RDS password + rds_client.modify_db_instance( + DBInstanceIdentifier=secret['dbInstanceIdentifier'], + MasterUserPassword=secret['password'], + ApplyImmediately=True + ) + + elif step == "testSecret": + # Test new credentials + import pymysql + conn = pymysql.connect( + host=secret['host'], + user=secret['username'], + password=secret['password'], + database=secret['dbname'] + ) + conn.close() + + elif step == "finishSecret": + # Mark as current + secrets_client.update_secret_version_stage( + SecretId=secret_arn, + VersionStage='AWSCURRENT', + MoveToVersionId=token, + RemoveFromVersionId=current['VersionId'] + ) + + return {'statusCode': 200} + +def generate_password(length=32): + import secrets + import string + alphabet = string.ascii_letters + string.digits + "!@#$%^&*()" + return ''.join(secrets.choice(alphabet) for _ in range(length)) +``` + +### Custom Rotation for API Keys + +```python +# api_key_rotation.py +import boto3 +import requests +import json + +secrets_client = boto3.client('secretsmanager') + +def rotate_stripe_key(secret_arn, token, step): + """Rotate Stripe API key""" + + current = secrets_client.get_secret_value(SecretId=secret_arn) + secret = json.loads(current['SecretString']) + + if step == "createSecret": + # Create new Stripe key via API + response = requests.post( + 'https://api.stripe.com/v1/api_keys', + auth=(secret['api_key'], ''), + data={'name': f'rotated-{token[:8]}'} + ) + new_key = response.json()['secret'] + + secret['api_key'] = new_key + secrets_client.put_secret_value( + SecretId=secret_arn, + ClientRequestToken=token, + SecretString=json.dumps(secret), + VersionStages=['AWSPENDING'] + ) + + elif step == "testSecret": + # Test new key + response = requests.get( + 'https://api.stripe.com/v1/balance', + auth=(secret['api_key'], '') + ) + if response.status_code != 200: + raise Exception("New key failed validation") + + elif step == "finishSecret": + # Revoke old key + old_key = json.loads(current['SecretString'])['api_key'] + requests.delete( + f'https://api.stripe.com/v1/api_keys/{old_key}', + auth=(secret['api_key'], '') + ) + + # Promote to current + secrets_client.update_secret_version_stage( + SecretId=secret_arn, + VersionStage='AWSCURRENT', + MoveToVersionId=token + ) +``` + +## Rotation Monitoring + +### CloudWatch Alarms + +```bash +# Create alarm for rotation failures +aws cloudwatch put-metric-alarm \ + --alarm-name secrets-rotation-failures \ + --alarm-description "Alert on secrets rotation failures" \ + --metric-name RotationFailed \ + --namespace AWS/SecretsManager \ + --statistic Sum \ + --period 300 \ + --evaluation-periods 1 \ + --threshold 1 \ + --comparison-operator GreaterThanThreshold \ + --alarm-actions arn:aws:sns:us-east-1:123456789012:alerts +``` + +### Rotation Audit Script + +```bash +#!/bin/bash +# audit-rotations.sh + +echo "Secrets Rotation Audit" +echo "=====================" + +aws secretsmanager list-secrets --query 'SecretList[*].[Name,RotationEnabled,LastRotatedDate]' \ + --output text | \ +while read name enabled last_rotated; do + echo "" + echo "Secret: $name" + echo " Rotation Enabled: $enabled" + echo " Last Rotated: $last_rotated" + + if [ "$enabled" = "True" ]; then + # Check rotation schedule + rules=$(aws secretsmanager describe-secret --secret-id "$name" \ + --query 'RotationRules.AutomaticallyAfterDays' --output text) + echo " Rotation Schedule: Every $rules days" + + # Calculate days since last rotation + if [ "$last_rotated" != "None" ]; then + days_ago=$(( ($(date +%s) - $(date -d "$last_rotated" +%s)) / 86400 )) + echo " Days Since Rotation: $days_ago" + + if [ $days_ago -gt $rules ]; then + echo " ⚠️ OVERDUE for rotation!" + fi + fi + fi +done +``` + +## Application Integration + +### Python SDK + +```python +import boto3 +import json + +def get_secret(secret_name): + """Retrieve secret from Secrets Manager""" + client = boto3.client('secretsmanager') + + try: + response = client.get_secret_value(SecretId=secret_name) + return json.loads(response['SecretString']) + except Exception as e: + print(f"Error retrieving secret: {e}") + raise + +# Usage +db_creds = get_secret('prod/db/mysql') +connection = pymysql.connect( + host=db_creds['host'], + user=db_creds['username'], + password=db_creds['password'], + database=db_creds['dbname'] +) +``` + +### Node.js SDK + +```javascript +const AWS = require('aws-sdk'); +const secretsManager = new AWS.SecretsManager(); + +async function getSecret(secretName) { + try { + const data = await secretsManager.getSecretValue({ + SecretId: secretName + }).promise(); + + return JSON.parse(data.SecretString); + } catch (err) { + console.error('Error retrieving secret:', err); + throw err; + } +} + +// Usage +const dbCreds = await getSecret('prod/db/mysql'); +const connection = mysql.createConnection({ + host: dbCreds.host, + user: dbCreds.username, + password: dbCreds.password, + database: dbCreds.dbname +}); +``` + +## Rotation Best Practices + +**Planning** +- [ ] Identify all secrets requiring rotation +- [ ] Define rotation schedules (30, 60, 90 days) +- [ ] Test rotation in non-production first +- [ ] Document rotation procedures +- [ ] Plan for emergency rotation + +**Implementation** +- [ ] Use AWS managed rotation when possible +- [ ] Implement proper error handling +- [ ] Add CloudWatch monitoring +- [ ] Test application compatibility +- [ ] Implement gradual rollout + +**Operations** +- [ ] Monitor rotation success/failure +- [ ] Set up alerts for failures +- [ ] Regular rotation audits +- [ ] Document troubleshooting steps +- [ ] Maintain rotation runbooks + +## Emergency Rotation + +```bash +# Immediate rotation (compromise detected) +aws secretsmanager rotate-secret \ + --secret-id prod/db/mysql \ + --rotate-immediately + +# Force rotation even if recently rotated +aws secretsmanager rotate-secret \ + --secret-id prod/api/stripe \ + --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:RotateStripeKey \ + --rotate-immediately + +# Verify rotation completed +aws secretsmanager describe-secret \ + --secret-id prod/db/mysql \ + --query 'LastRotatedDate' +``` + +## Compliance Tracking + +```python +#!/usr/bin/env python3 +# compliance-report.py + +import boto3 +from datetime import datetime, timedelta + +client = boto3.client('secretsmanager') + +def generate_compliance_report(): + secrets = client.list_secrets()['SecretList'] + + compliant = [] + non_compliant = [] + + for secret in secrets: + name = secret['Name'] + rotation_enabled = secret.get('RotationEnabled', False) + last_rotated = secret.get('LastRotatedDate') + + if not rotation_enabled: + non_compliant.append({ + 'name': name, + 'issue': 'Rotation not enabled' + }) + continue + + if last_rotated: + days_ago = (datetime.now(last_rotated.tzinfo) - last_rotated).days + if days_ago > 90: + non_compliant.append({ + 'name': name, + 'issue': f'Not rotated in {days_ago} days' + }) + else: + compliant.append(name) + else: + non_compliant.append({ + 'name': name, + 'issue': 'Never rotated' + }) + + print(f"Compliant Secrets: {len(compliant)}") + print(f"Non-Compliant Secrets: {len(non_compliant)}") + print("\nNon-Compliant Details:") + for item in non_compliant: + print(f" - {item['name']}: {item['issue']}") + +if __name__ == "__main__": + generate_compliance_report() +``` + +## Example Prompts + +- "Set up automatic rotation for my RDS credentials" +- "Create a Lambda function to rotate API keys" +- "Audit all secrets for rotation compliance" +- "Implement emergency rotation for compromised credentials" +- "Generate a secrets rotation report" + +## Kiro CLI Integration + +```bash +kiro-cli chat "Use aws-secrets-rotation to set up RDS credential rotation" +kiro-cli chat "Create a rotation audit report with aws-secrets-rotation" +``` + +## Additional Resources + +- [AWS Secrets Manager Rotation](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html) +- [Rotation Lambda Templates](https://github.com/aws-samples/aws-secrets-manager-rotation-lambdas) +- [Best Practices for Secrets](https://docs.aws.amazon.com/secretsmanager/latest/userguide/best-practices.html) diff --git a/skills/security/aws-security-audit/SKILL.md b/skills/security/aws-security-audit/SKILL.md new file mode 100644 index 00000000..350d976f --- /dev/null +++ b/skills/security/aws-security-audit/SKILL.md @@ -0,0 +1,369 @@ +--- +name: aws-security-audit +description: Comprehensive AWS security posture assessment using AWS CLI and security best practices +risk: safe +source: community +category: security +tags: [aws, security, audit, compliance, kiro-cli, security-assessment] +--- + +# AWS Security Audit + +Perform comprehensive security assessments of AWS environments to identify vulnerabilities and misconfigurations. + +## When to Use + +Use this skill when you need to audit AWS security posture, identify vulnerabilities, or prepare for compliance assessments. + +## Audit Categories + +**Identity & Access Management** +- Overly permissive IAM policies +- Unused IAM users and roles +- MFA enforcement gaps +- Root account usage +- Access key rotation + +**Network Security** +- Open security groups (0.0.0.0/0) +- Public S3 buckets +- Unencrypted data in transit +- VPC flow logs disabled +- Network ACL misconfigurations + +**Data Protection** +- Unencrypted EBS volumes +- Unencrypted RDS instances +- S3 bucket encryption disabled +- Backup policies missing +- KMS key rotation disabled + +**Logging & Monitoring** +- CloudTrail disabled +- CloudWatch alarms missing +- VPC Flow Logs disabled +- S3 access logging disabled +- Config recording disabled + +## Security Audit Commands + +### IAM Security Checks + +```bash +# List users without MFA +aws iam get-credential-report --output text | \ + awk -F, '$4=="false" && $1!="" {print $1}' + +# Find unused IAM users (no activity in 90 days) +aws iam list-users --query 'Users[*].[UserName]' --output text | \ +while read user; do + last_used=$(aws iam get-user --user-name "$user" \ + --query 'User.PasswordLastUsed' --output text) + echo "$user: $last_used" +done + +# List overly permissive policies (AdministratorAccess) +aws iam list-policies --scope Local \ + --query 'Policies[?PolicyName==`AdministratorAccess`]' + +# Find access keys older than 90 days +aws iam list-users --query 'Users[*].UserName' --output text | \ +while read user; do + aws iam list-access-keys --user-name "$user" \ + --query 'AccessKeyMetadata[*].[AccessKeyId,CreateDate]' \ + --output text +done + +# Check root account access keys +aws iam get-account-summary \ + --query 'SummaryMap.AccountAccessKeysPresent' +``` + +### Network Security Checks + +```bash +# Find security groups open to the world +aws ec2 describe-security-groups \ + --query 'SecurityGroups[?IpPermissions[?IpRanges[?CidrIp==`0.0.0.0/0`]]].[GroupId,GroupName]' \ + --output table + +# List public S3 buckets +aws s3api list-buckets --query 'Buckets[*].Name' --output text | \ +while read bucket; do + acl=$(aws s3api get-bucket-acl --bucket "$bucket" 2>/dev/null) + if echo "$acl" | grep -q "AllUsers"; then + echo "PUBLIC: $bucket" + fi +done + +# Check VPC Flow Logs status +aws ec2 describe-vpcs --query 'Vpcs[*].VpcId' --output text | \ +while read vpc; do + flow_logs=$(aws ec2 describe-flow-logs \ + --filter "Name=resource-id,Values=$vpc" \ + --query 'FlowLogs[*].FlowLogId' --output text) + if [ -z "$flow_logs" ]; then + echo "No flow logs: $vpc" + fi +done + +# Find RDS instances without encryption +aws rds describe-db-instances \ + --query 'DBInstances[?StorageEncrypted==`false`].[DBInstanceIdentifier]' \ + --output table +``` + +### Data Protection Checks + +```bash +# Find unencrypted EBS volumes +aws ec2 describe-volumes \ + --query 'Volumes[?Encrypted==`false`].[VolumeId,Size,State]' \ + --output table + +# Check S3 bucket encryption +aws s3api list-buckets --query 'Buckets[*].Name' --output text | \ +while read bucket; do + encryption=$(aws s3api get-bucket-encryption \ + --bucket "$bucket" 2>&1) + if echo "$encryption" | grep -q "ServerSideEncryptionConfigurationNotFoundError"; then + echo "No encryption: $bucket" + fi +done + +# Find RDS snapshots that are public +aws rds describe-db-snapshots \ + --query 'DBSnapshots[*].[DBSnapshotIdentifier]' --output text | \ +while read snapshot; do + attrs=$(aws rds describe-db-snapshot-attributes \ + --db-snapshot-identifier "$snapshot" \ + --query 'DBSnapshotAttributesResult.DBSnapshotAttributes[?AttributeName==`restore`].AttributeValues' \ + --output text) + if echo "$attrs" | grep -q "all"; then + echo "PUBLIC SNAPSHOT: $snapshot" + fi +done + +# Check KMS key rotation +aws kms list-keys --query 'Keys[*].KeyId' --output text | \ +while read key; do + rotation=$(aws kms get-key-rotation-status --key-id "$key" \ + --query 'KeyRotationEnabled' --output text 2>/dev/null) + if [ "$rotation" = "False" ]; then + echo "Rotation disabled: $key" + fi +done +``` + +### Logging & Monitoring Checks + +```bash +# Check CloudTrail status +aws cloudtrail describe-trails \ + --query 'trailList[*].[Name,IsMultiRegionTrail,LogFileValidationEnabled]' \ + --output table + +# Verify CloudTrail is logging +aws cloudtrail get-trail-status --name my-trail \ + --query 'IsLogging' + +# Check if AWS Config is enabled +aws configservice describe-configuration-recorders \ + --query 'ConfigurationRecorders[*].[name,roleARN]' \ + --output table + +# List S3 buckets without access logging +aws s3api list-buckets --query 'Buckets[*].Name' --output text | \ +while read bucket; do + logging=$(aws s3api get-bucket-logging --bucket "$bucket" 2>&1) + if ! echo "$logging" | grep -q "LoggingEnabled"; then + echo "No access logging: $bucket" + fi +done +``` + +## Automated Security Audit Script + +```bash +#!/bin/bash +# comprehensive-security-audit.sh + +echo "=== AWS Security Audit Report ===" +echo "Generated: $(date)" +echo "" + +# IAM Checks +echo "## IAM Security" +echo "Users without MFA:" +aws iam get-credential-report --output text | \ + awk -F, '$4=="false" && $1!="" {print " - " $1}' + +echo "" +echo "Root account access keys:" +aws iam get-account-summary \ + --query 'SummaryMap.AccountAccessKeysPresent' --output text + +# Network Checks +echo "" +echo "## Network Security" +echo "Security groups open to 0.0.0.0/0:" +aws ec2 describe-security-groups \ + --query 'SecurityGroups[?IpPermissions[?IpRanges[?CidrIp==`0.0.0.0/0`]]].GroupId' \ + --output text | wc -l + +# Data Protection +echo "" +echo "## Data Protection" +echo "Unencrypted EBS volumes:" +aws ec2 describe-volumes \ + --query 'Volumes[?Encrypted==`false`].VolumeId' \ + --output text | wc -l + +echo "" +echo "Unencrypted RDS instances:" +aws rds describe-db-instances \ + --query 'DBInstances[?StorageEncrypted==`false`].DBInstanceIdentifier' \ + --output text | wc -l + +# Logging +echo "" +echo "## Logging & Monitoring" +echo "CloudTrail status:" +aws cloudtrail describe-trails \ + --query 'trailList[*].[Name,IsLogging]' \ + --output table + +echo "" +echo "=== End of Report ===" +``` + +## Security Score Calculator + +```python +#!/usr/bin/env python3 +# security-score.py + +import boto3 +import json + +def calculate_security_score(): + iam = boto3.client('iam') + ec2 = boto3.client('ec2') + s3 = boto3.client('s3') + + score = 100 + issues = [] + + # Check MFA + try: + report = iam.get_credential_report() + users_without_mfa = 0 + # Parse report and count + if users_without_mfa > 0: + score -= 10 + issues.append(f"{users_without_mfa} users without MFA") + except: + pass + + # Check open security groups + sgs = ec2.describe_security_groups() + open_sgs = 0 + for sg in sgs['SecurityGroups']: + for perm in sg.get('IpPermissions', []): + for ip_range in perm.get('IpRanges', []): + if ip_range.get('CidrIp') == '0.0.0.0/0': + open_sgs += 1 + break + + if open_sgs > 0: + score -= 15 + issues.append(f"{open_sgs} security groups open to internet") + + # Check unencrypted volumes + volumes = ec2.describe_volumes() + unencrypted = sum(1 for v in volumes['Volumes'] if not v['Encrypted']) + + if unencrypted > 0: + score -= 20 + issues.append(f"{unencrypted} unencrypted EBS volumes") + + print(f"Security Score: {score}/100") + print("\nIssues Found:") + for issue in issues: + print(f" - {issue}") + + return score + +if __name__ == "__main__": + calculate_security_score() +``` + +## Compliance Mapping + +**CIS AWS Foundations Benchmark** +- 1.1: Root account usage +- 1.2-1.14: IAM policies and MFA +- 2.1-2.9: Logging (CloudTrail, Config, VPC Flow Logs) +- 4.1-4.3: Monitoring and alerting + +**PCI-DSS** +- Requirement 1: Network security controls +- Requirement 2: Secure configurations +- Requirement 8: Access controls and MFA +- Requirement 10: Logging and monitoring + +**HIPAA** +- Access controls (IAM) +- Audit controls (CloudTrail) +- Encryption (EBS, RDS, S3) +- Transmission security (TLS/SSL) + +## Remediation Priorities + +**Critical (Fix Immediately)** +- Root account access keys +- Public RDS snapshots +- Security groups open to 0.0.0.0/0 on sensitive ports +- CloudTrail disabled + +**High (Fix Within 7 Days)** +- Users without MFA +- Unencrypted data at rest +- Missing VPC Flow Logs +- Overly permissive IAM policies + +**Medium (Fix Within 30 Days)** +- Old access keys (>90 days) +- Missing S3 access logging +- Unused IAM users +- KMS key rotation disabled + +## Example Prompts + +- "Run a comprehensive security audit on my AWS account" +- "Check for IAM security issues" +- "Find all unencrypted resources" +- "Generate a security compliance report" +- "Calculate my AWS security score" + +## Best Practices + +- Run audits weekly +- Automate with Lambda/EventBridge +- Export results to S3 for trending +- Integrate with SIEM tools +- Track remediation progress +- Document exceptions with business justification + +## Kiro CLI Integration + +```bash +kiro-cli chat "Use aws-security-audit to assess my security posture" +kiro-cli chat "Generate a security audit report with aws-security-audit" +``` + +## Additional Resources + +- [AWS Security Best Practices](https://aws.amazon.com/security/best-practices/) +- [CIS AWS Foundations Benchmark](https://www.cisecurity.org/benchmark/amazon_web_services) +- [AWS Security Hub](https://aws.amazon.com/security-hub/) diff --git a/skills_index.json b/skills_index.json index 9aa6336a..1366a2d7 100644 --- a/skills_index.json +++ b/skills_index.json @@ -539,6 +539,24 @@ "risk": "unknown", "source": "community" }, + { + "id": "aws-compliance-checker", + "path": "skills/security/aws-compliance-checker", + "category": "security", + "name": "aws-compliance-checker", + "description": "Automated compliance checking against CIS, PCI-DSS, HIPAA, and SOC 2 benchmarks", + "risk": "safe", + "source": "community" + }, + { + "id": "aws-iam-best-practices", + "path": "skills/security/aws-iam-best-practices", + "category": "security", + "name": "aws-iam-best-practices", + "description": "IAM policy review, hardening, and least privilege implementation", + "risk": "safe", + "source": "community" + }, { "id": "aws-penetration-testing", "path": "skills/aws-penetration-testing", @@ -548,6 +566,24 @@ "risk": "unknown", "source": "community" }, + { + "id": "aws-secrets-rotation", + "path": "skills/security/aws-secrets-rotation", + "category": "security", + "name": "aws-secrets-rotation", + "description": "Automate AWS secrets rotation for RDS, API keys, and credentials", + "risk": "safe", + "source": "community" + }, + { + "id": "aws-security-audit", + "path": "skills/security/aws-security-audit", + "category": "security", + "name": "aws-security-audit", + "description": "Comprehensive AWS security posture assessment using AWS CLI and security best practices", + "risk": "safe", + "source": "community" + }, { "id": "aws-serverless", "path": "skills/aws-serverless",