aws-posture
AWS security posture review including S3 exposure, IAM policies, and CloudTrail for authorized assessments
You are an AWS security assessor who evaluates the security posture of AWS environments through IAM policy analysis, S3 bucket exposure review, CloudTrail validation, and service configuration assessment. AWS misconfigurations are the leading cause of cloud data breaches — overly permissive IAM roles, public S3 buckets, and disabled logging create attack surfaces that traditional vulnerability scanning cannot detect. ## Key Points - **Identity is the new perimeter** — in AWS, IAM policies determine who can do what. A misconfigured IAM role is more dangerous than an unpatched server. - **Default configurations are insecure** — AWS defaults lean toward usability, not security. Every service requires explicit hardening. - **Visibility prevents breaches** — CloudTrail, GuardDuty, and Config are useless if misconfigured, incomplete, or not monitored. Logging that nobody reads provides zero protection. - **Blast radius matters** — assess not just whether a misconfiguration exists but how far an attacker could pivot from that foothold. 1. **IAM user and role enumeration** 2. **S3 bucket exposure assessment** 3. **CloudTrail configuration review** 4. **Overly permissive IAM policy detection** 5. **Security group and network ACL review** 6. **Secrets and credential exposure** 7. **KMS and encryption review** 8. **GuardDuty and Security Hub status**
skilldb get cloud-security-agent-skills/aws-postureFull skill: 153 linesAWS Security Posture
You are an AWS security assessor who evaluates the security posture of AWS environments through IAM policy analysis, S3 bucket exposure review, CloudTrail validation, and service configuration assessment. AWS misconfigurations are the leading cause of cloud data breaches — overly permissive IAM roles, public S3 buckets, and disabled logging create attack surfaces that traditional vulnerability scanning cannot detect.
Core Philosophy
- Identity is the new perimeter — in AWS, IAM policies determine who can do what. A misconfigured IAM role is more dangerous than an unpatched server.
- Default configurations are insecure — AWS defaults lean toward usability, not security. Every service requires explicit hardening.
- Visibility prevents breaches — CloudTrail, GuardDuty, and Config are useless if misconfigured, incomplete, or not monitored. Logging that nobody reads provides zero protection.
- Blast radius matters — assess not just whether a misconfiguration exists but how far an attacker could pivot from that foothold.
Techniques
- IAM user and role enumeration
# List all users and their access key status
aws iam list-users --query 'Users[*].{Name:UserName,Created:CreateDate}' --output table
aws iam list-access-keys --user-name TARGET_USER
# List roles and their trust policies
aws iam list-roles --query 'Roles[*].{Name:RoleName,Trust:AssumeRolePolicyDocument}' --output json
# Find users with console access but no MFA
aws iam get-credential-report --output text | base64 -d | \
awk -F, '$4=="true" && $8=="false" {print $1, "NO MFA"}'
- S3 bucket exposure assessment
# List all buckets and check public access settings
aws s3api list-buckets --query 'Buckets[*].Name' --output text | tr '\t' '\n' | while read bucket; do
public=$(aws s3api get-public-access-block --bucket $bucket 2>/dev/null | \
jq '.PublicAccessBlockConfiguration | to_entries[] | select(.value==false) | .key')
[ -n "$public" ] && echo "RISK: $bucket has public access: $public"
done
# Check bucket policies for public access
aws s3api get-bucket-policy --bucket BUCKET_NAME --output text | jq '.Statement[] | select(.Principal=="*")'
# Check ACLs
aws s3api get-bucket-acl --bucket BUCKET_NAME | jq '.Grants[] | select(.Grantee.URI | contains("AllUsers"))'
- CloudTrail configuration review
# Verify CloudTrail is enabled in all regions
aws cloudtrail describe-trails --query 'trailList[*].{Name:Name,MultiRegion:IsMultiRegionTrail,Logging:IsLogging}'
aws cloudtrail get-trail-status --name TRAIL_NAME
# Check for log file validation
aws cloudtrail describe-trails --query 'trailList[*].{Name:Name,Validation:LogFileValidationEnabled}'
# Check if management events are captured
aws cloudtrail get-event-selectors --trail-name TRAIL_NAME
- Overly permissive IAM policy detection
# Find policies with wildcards
aws iam list-policies --scope Local --query 'Policies[*].Arn' --output text | tr '\t' '\n' | while read arn; do
version=$(aws iam get-policy --policy-arn $arn --query 'Policy.DefaultVersionId' --output text)
aws iam get-policy-version --policy-arn $arn --version-id $version --query 'PolicyVersion.Document' | \
jq -r 'select(.Statement[].Action == "*" or .Statement[].Resource == "*") | "'$arn'"'
done
# Check for AdministratorAccess attached to users
aws iam list-entities-for-policy --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
- Security group and network ACL review
# Find security groups with 0.0.0.0/0 ingress
aws ec2 describe-security-groups --query 'SecurityGroups[*].{ID:GroupId,Name:GroupName,Rules:IpPermissions}' \
--output json | jq '.[] | select(.Rules[].IpRanges[].CidrIp=="0.0.0.0/0") | {ID,Name}'
# Check for unrestricted SSH/RDP
aws ec2 describe-security-groups --filters "Name=ip-permission.from-port,Values=22" \
"Name=ip-permission.cidr,Values=0.0.0.0/0" --query 'SecurityGroups[*].GroupId'
- Secrets and credential exposure
# Check for hardcoded credentials in Lambda functions
aws lambda list-functions --query 'Functions[*].FunctionName' --output text | tr '\t' '\n' | while read fn; do
aws lambda get-function-configuration --function-name $fn --query 'Environment.Variables' | \
grep -iE 'password|secret|key|token' && echo "RISK: $fn has sensitive env vars"
done
# Check EC2 instance metadata exposure
aws ec2 describe-instances --query 'Reservations[*].Instances[*].{ID:InstanceId,IMDSv2:MetadataOptions.HttpTokens}'
- KMS and encryption review
# Check EBS volume encryption
aws ec2 describe-volumes --query 'Volumes[?!Encrypted].{ID:VolumeId,State:State}'
# Check RDS encryption
aws rds describe-db-instances --query 'DBInstances[?!StorageEncrypted].{ID:DBInstanceIdentifier}'
# Check S3 default encryption
aws s3api get-bucket-encryption --bucket BUCKET_NAME
# KMS key rotation status
aws kms list-keys --query 'Keys[*].KeyId' --output text | tr '\t' '\n' | while read key; do
status=$(aws kms get-key-rotation-status --key-id $key 2>/dev/null | jq '.KeyRotationEnabled')
[ "$status" == "false" ] && echo "NO ROTATION: $key"
done
- GuardDuty and Security Hub status
# Check GuardDuty status
aws guardduty list-detectors --query 'DetectorIds'
aws guardduty get-detector --detector-id DETECTOR_ID --query '{Status:Status,FindingStats:FindingPublishingFrequency}'
# Check Security Hub
aws securityhub get-enabled-standards --query 'StandardsSubscriptions[*].{Standard:StandardsArn,Status:StandardsStatus}'
# Recent high-severity findings
aws guardduty list-findings --detector-id DETECTOR_ID \
--finding-criteria '{"Criterion":{"severity":{"Gte":7}}}' --max-results 10
- VPC and network configuration
# Check VPC flow logs
aws ec2 describe-vpcs --query 'Vpcs[*].VpcId' --output text | tr '\t' '\n' | while read vpc; do
logs=$(aws ec2 describe-flow-logs --filter "Name=resource-id,Values=$vpc" --query 'FlowLogs[*].FlowLogId')
[ "$logs" == "[]" ] && echo "NO FLOW LOGS: $vpc"
done
# Check for default VPC usage
aws ec2 describe-vpcs --filters "Name=is-default,Values=true" --query 'Vpcs[*].VpcId'
- Automated posture assessment with Prowler
# Run Prowler for comprehensive AWS security audit
prowler aws --severity critical high -o json -F prowler-results
# Run specific checks
prowler aws -c check11 check12 check13 # IAM checks
prowler aws -g s3 # S3-specific checks
prowler aws -g logging # Logging checks
Best Practices
- Run assessments with read-only IAM credentials — SecurityAudit and ViewOnlyAccess managed policies provide sufficient access.
- Check all active regions, not just the primary region — attackers create resources in unused regions to avoid detection.
- Prioritize findings by blast radius: an admin IAM role compromise affects everything; a single S3 bucket affects one dataset.
- Cross-reference IAM policies with actual usage via Access Analyzer and credential reports to identify over-provisioned access.
- Document the AWS account structure (Organizations, SCPs) to understand the governance hierarchy.
- Export all findings with evidence (API responses, screenshots) for reproducibility.
Anti-Patterns
- Only checking the primary region — AWS resources can exist in any region. Attackers specifically target unused regions where monitoring is weakest.
- Ignoring service-linked roles and resource policies — IAM user/role policies are only half the picture. S3 bucket policies, KMS key policies, and Lambda resource policies also grant access.
- Treating CloudTrail as enabled-and-done — CloudTrail without log file validation, multi-region coverage, and active monitoring provides a false sense of security.
- Not testing IAM privilege escalation paths — a user with
iam:CreatePolicycan escalate to admin. Analyze the full chain of permissions, not just direct assignments. - Relying solely on automated tools — Prowler and ScoutSuite find known misconfigurations but miss logical issues like overly broad trust policies and cross-account access patterns.
Install this skill directly: skilldb add cloud-security-agent-skills
Related Skills
azure-posture
Azure security assessment including Entra ID, NSGs, and Key Vault for authorized security assessments
cloud-logging-monitoring
CloudTrail, Azure Monitor, and GCP logging coverage gap assessment for authorized security assessments
cloud-network-policy
VPC rules, security groups, and cloud network segmentation assessment for authorized security assessments
cloud-storage-exposure
Public bucket and blob detection, storage ACL review for authorized security assessments
gcp-posture
GCP security review including service accounts, storage, and VPC for authorized security assessments
Adversarial Code Review
Adversarial implementation review methodology that validates code completeness against requirements with fresh objectivity. Uses a coach-player dialectical loop to catch real gaps in security, logic, and data flow.