A read-only Python tool that audits an AWS account for common security misconfigurations, mapped to the CIS AWS Foundations Benchmark v2.0. Designed for security engineers who want fast, scriptable posture assessments without the overhead of a commercial CSPM.
| Service | Check | CIS Control | Severity |
|---|---|---|---|
| IAM | Root account MFA disabled | 1.5 | CRITICAL |
| IAM | Console users without MFA | 1.10 | HIGH |
| IAM | Access keys older than 90 days | 1.14 | MEDIUM |
| IAM | Customer policies with Action:/Resource: | 1.16 | CRITICAL |
| IAM | Weak password policy | 1.8 | MEDIUM |
| S3 | Public access block not fully enabled | 2.1.4 | HIGH |
| S3 | No default encryption | 2.1.1 | MEDIUM |
| S3 | Versioning disabled | 2.1.3 | LOW |
| S3 | Access logging disabled | 2.1.2 | LOW |
| CloudTrail | No trail in region | 3.1 | CRITICAL |
| CloudTrail | Single-region trail | 3.1 | HIGH |
| CloudTrail | Log file validation disabled | 3.2 | MEDIUM |
| CloudTrail | Not integrated with CloudWatch Logs | 3.4 | MEDIUM |
| CloudTrail | Logging stopped | 3.1 | CRITICAL |
| EC2 | Security group allows 0.0.0.0/0 on sensitive ports | 5.2 | HIGH |
| EC2 | Security group allows all inbound traffic | 5.2 | CRITICAL |
| EC2 | Default VPC present | 5.3 | LOW |
| EC2 | EBS encryption not default | 2.2.1 | MEDIUM |
| EC2 | IMDSv1 enabled (SSRF risk) | — | HIGH |
| GuardDuty | Not enabled in region | 4.15 | HIGH |
| GuardDuty | Detector disabled | 4.15 | HIGH |
| GuardDuty | Protection features disabled | — | MEDIUM |
git clone https://github.com/ClockworkZMP/aws-security-posture-checker.git
cd aws-security-posture-checker
pip install -r requirements.txtThe tool uses your existing AWS credentials. It only requires read-only access — attach the SecurityAudit or ReadOnlyAccess managed policy.
# Option 1: AWS CLI profile
aws configure --profile my-profile
# Option 2: Environment variables
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_DEFAULT_REGION=us-east-1# Full scan, default region (us-east-1)
python posture_check.py
# Scan multiple regions
python posture_check.py --regions us-east-1 us-west-2 eu-west-1
# Scan all enabled regions
python posture_check.py --regions all
# Run specific checks only
python posture_check.py --checks s3 iam cloudtrail
# Export to JSON or CSV
python posture_check.py --output findings.json
python posture_check.py --output findings.csv
# Use a specific AWS profile
python posture_check.py --profile prod-readonly
# Only show HIGH and above
python posture_check.py --min-severity HIGH
# Validate credentials without running checks
python posture_check.py --dry-run=================================================================
AWS Security Posture Report
Account: 123456789012 | Regions: us-east-1, us-west-2
Generated: 2026-06-13 18:00:00 UTC
=================================================================
[IAM]
CRITICAL arn:aws:iam::root
Root account does not have MFA enabled.
Fix: Enable a hardware MFA device for the root account immediately.
HIGH iam/user/deploy-bot
IAM user 'deploy-bot' has console access but no MFA device enrolled.
Fix: Enforce MFA via an IAM policy condition or AWS IAM Identity Center.
[EC2]
HIGH sg/sg-0abc123 (web-tier)
Security group allows inbound SSH (port 22) from 0.0.0.0/0.
Fix: Restrict port 22 to known IP ranges or use a bastion/VPN.
─────────────────────────────────────────────────────────────────
Summary: 14 finding(s) — 2 CRITICAL | 5 HIGH | 4 MEDIUM | 3 LOW
─────────────────────────────────────────────────────────────────
The tool exits with code 2 if any CRITICAL findings are found — plug it into your pipeline:
# GitHub Actions example
- name: AWS Security Posture Check
run: |
pip install -r requirements.txt
python posture_check.py --checks s3 iam --min-severity HIGH --output findings.json
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}Attach the AWS-managed SecurityAudit policy, or scope to these actions:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"s3:GetBucketAcl", "s3:GetBucketEncryption", "s3:GetBucketLogging",
"s3:GetBucketPublicAccessBlock", "s3:GetBucketVersioning", "s3:ListAllMyBuckets",
"iam:GetAccountPasswordPolicy", "iam:GetAccountSummary", "iam:GetPolicyVersion",
"iam:ListAccessKeys", "iam:ListMFADevices", "iam:ListPolicies",
"iam:ListUsers", "iam:GetLoginProfile",
"cloudtrail:DescribeTrails", "cloudtrail:GetTrailStatus",
"ec2:DescribeInstances", "ec2:DescribeRegions", "ec2:DescribeSecurityGroups",
"ec2:DescribeVolumes", "ec2:DescribeVpcs", "ec2:GetEbsEncryptionByDefault",
"guardduty:GetDetector", "guardduty:ListDetectors",
"sts:GetCallerIdentity"
],
"Resource": "*"
}]
}aws-security-posture-checker/
├── posture_check.py # CLI entrypoint
├── checks/
│ ├── base.py # Finding, Severity, CheckBase
│ ├── s3.py # S3 checks
│ ├── iam.py # IAM checks
│ ├── cloudtrail.py # CloudTrail checks
│ ├── ec2.py # EC2/VPC/EBS/IMDSv2 checks
│ └── guardduty.py # GuardDuty checks
├── utils/
│ └── reporter.py # Terminal, JSON, CSV output
├── examples/
│ └── sample_report.json
├── requirements.txt
└── README.md
MIT