The 69 AWS checks 6WAF runs automatically
39 cost-waste checks · 24 security checks · 6 reliability checks. Each one has its own page with the detection threshold, the data source and how to verify it by hand.
The Pro plan also includes Deep Scan (Prowler) with hundreds of additional checks — not counted above.
Cost — waste checks(39)
Idle resources, oversized instances, wrong pricing model, costly architecture and accumulated junk.
V1 — Idle: paying for what nobody uses
Unattached EBS Volume
EBS in available (detached) state → $0.08–0.125/GB/month even when unused
NAT Gateway with no traffic
BytesOutToDestination < 1 GB/day for 14 days → fixed charge $0.045/hr (~$32/mo)
Lambda with 0 invocations
Lambda not invoked for 30 days — Provisioned Concurrency still billed
RDS instance with no connections
0 database connections for 7 consecutive days → forgotten instance, 100% savings possible
Kinesis Stream with no records
0 records for 14 days → shard-hour charge $0.015/shard/hr (~$11/shard/mo)
EFS with < 1 GB data
EFS $0.30/GB/month — 13× more expensive than S3. Small filesystems not using POSIX should migrate to S3
SageMaker endpoint with 0 invocations
ML endpoint not invoked for 7 days — model still in S3, endpoint can be safely deleted
VPN Connection with no traffic
Site-to-site VPN 0 bytes for 14 days → $36.50/month fixed charge being wasted
Orphaned Route53 Health Check
Health check not attached to any record set → $0.50–1.00/month per check
Elastic IP not attached to instance
EIP not attached to a running instance → AWS charges $0.005/hr when idle
Load Balancer with no healthy targets
ALB/NLB/Classic ELB with no healthy targets → fixed charge $0.008–0.025/hr
V2 — Oversize: paying for more than needed
EC2 Rightsizing
avg CPU < 20% and peak < 40% for 14 days → downsize 1 tier (CloudWatch CPUUtilization)
RDS Rightsizing
Max connections < 10 for 14 days → downsize 1 tier; Multi-AZ × 2
Redshift Rightsizing
avg CPU < 20% and connections < 5 → recommend pause/resume off-hours (~50% savings)
OpenSearch Rightsizing
avg CPU < 20% and JVM < 60% for 14 days → downsize instance type
ECS Fargate Rightsizing
avg CPU utilization < 25% (Container Insights) → reduce task CPU reservation (Fargate only)
ElastiCache Rightsizing
Redis/Memcached node CPU < 20% and memory < 20% → downsize 1 tier
Over-provisioned EBS io1/io2 IOPS
Peak consumed IOPS < 30% provisioned IOPS → migrate to gp3 with custom IOPS (much cheaper)
RDS Multi-AZ for Dev/Test
Instance tagged Environment=dev/test/staging has Multi-AZ enabled → 50% savings when disabled
Inefficient DynamoDB Provisioned capacity
avg utilization < 20% RCU/WCU for 14 days → switch to PAY_PER_REQUEST
Lambda Memory Rightsizing
avg memory < 30% allocated (Lambda Insights required) → reduce memory, save GB-seconds
MSK Broker Rightsizing
avg CPU < 20% on brokers for 14 days → downsize instance type or reduce broker count
V3 — Wrong Model: On-Demand when RI/SP is cheaper
ElastiCache Reserved Nodes
Cache nodes running 90+ days On-Demand → 1-year Reserved Node saves ~30%
OpenSearch Reserved Instances
Domain running 90+ days → 1-year RI saves ~28%
Redshift Reserved Nodes
Cluster running 90+ days On-Demand → Reserved Node saves ~34%
RI/SP Over-commitment
RI or SP utilization < 50% — paying upfront for capacity that's going unused
V4 — Architecture: built in ways that inflate the bill
Dev/Test running 24/7
EC2 tagged Environment=dev/test/staging running continuously → auto-stop saves 64%
Missing VPC Endpoint for S3/DynamoDB
Traffic to S3/DDB via NAT Gateway → paying $0.045/GB NAT fee; Gateway Endpoint is FREE
API Gateway REST → HTTP API
HTTP API (v2) $1.00/million requests vs REST API $3.50/million — 71% cheaper
S3 without CloudFront
Public S3 bucket > 1 GB/day without CloudFront → main benefits are latency + GET request-cost offload (per-GB egress rates are similar — informational)
EC2 Spot opportunity
Instances tagged dev/test/batch/worker running On-Demand → Spot saves 60–90%
V5 — Accumulated: junk that piles up over time
Unused AMI & Snapshot
AMI/snapshot > 90 days not attached to any running instance → $0.05/GB/month
S3 Intelligent Tiering
Bucket > 1 GB Standard without lifecycle rule → save ~30% by moving to IA/Glacier
Stale ECR Image
Container image > 90 days (not tagged 'latest') → save $0.10/GB/month
EBS gp2 → gp3 migration
gp2 $0.10/GB vs gp3 $0.08/GB — migrate to gp3, save $0.02/GB/month (no downtime)
CloudWatch Logs without retention
Log group with no expiry → $0.03/GB/month accumulating indefinitely
Abandoned S3 Multipart Uploads
Multipart uploads > 7 days incomplete → storage charged for uncommitted parts
S3 Versioning without lifecycle
Bucket has versioning enabled but no NoncurrentVersionExpiration → ~50% storage is old versions
EC2 instance stopped > 30 days
Stopped instance incurs no CPU cost but EBS volumes still charged $0.08–0.125/GB/month
Security — Fast Scan(24)
AWS API checks (IAM, S3, network, CloudTrail, KMS). Deterministic results — no LLM is used for detection.
Identity & access (IAM)
Root account MFA not enabled
CRITICALRoot has full access and cannot be restricted by IAM policy — without MFA the whole account is one stolen password from takeover
Root account has active access keys
CRITICALRoot access keys are the most dangerous attack vector — never use them in code or automation
No IAM password policy configured
HIGHNo account password policy is set, so IAM users can choose arbitrarily weak passwords
IAM password minimum length below 14
MEDIUMMinimum length in the password policy is under 14 characters (6WAF's recommended threshold, aligned to CIS)
Password reuse not prevented
MEDIUMThe password policy does not stop users from returning to previous passwords
IAM password expiry not enforced
LOWNo MaxPasswordAge is set, so a leaked password stays valid indefinitely
Access key unused for 90+ days
MEDIUMAn IAM user access key has not been used for more than 90 days — deactivate or delete it
IAM Identity Center (SSO) not configured
MEDIUMIAM users sign in to the console with long-term passwords instead of centralised SSO/federation
EC2 instance has no IAM role attached
MEDIUMNo instance profile attached, which tends to push applications into storing static access keys on the host
Data protection (S3, EBS, KMS)
S3 bucket Public Access Block missing or incomplete
HIGHThe bucket does not have all four Public Access Block settings enabled, or has no configuration at all — risk of public data exposure
S3 account-level Public Access Block not fully enabled
HIGHAccount-level Block Public Access is not fully enabled, so newly created buckets are not protected by default
S3 bucket uses SSE-S3 instead of SSE-KMS
LOWThe bucket is encrypted with S3-managed keys, without KMS key control and its dedicated audit trail
S3 bucket has no explicit encryption configuration
LOWThe bucket does not declare a default encryption configuration explicitly
EBS volume not encrypted
MEDIUMThe volume is not encrypted at rest, and snapshots taken from it are not encrypted either
KMS key automatic rotation not enabled
LOWA customer-managed symmetric KMS key in Enabled state has rotation off; AWS-managed and asymmetric keys are skipped
Network (Security Groups, VPC)
Security Group open to all internet traffic
CRITICALAn inbound rule allows all protocols from 0.0.0.0/0 or ::/0 — every port is reachable
Port 22 (SSH) open to the internet
HIGHA Security Group allows SSH from 0.0.0.0/0 — exposed to brute-force and credential stuffing
Port 3389 (RDP) open to the internet
HIGHA Security Group allows RDP from 0.0.0.0/0 — exposed to brute-force and credential stuffing
VPC has no Flow Logs
MEDIUMNo network traffic logs are available to investigate incidents or spot unusual access
Logging & audit (CloudTrail)
CloudTrail not enabled
HIGHNo trail exists — administrative activity in the account is not recorded for audit
CloudTrail trail paused
HIGHThe trail exists but logging is stopped, leaving a gap in the audit trail
No CloudTrail multi-region trail
MEDIUMNo trail records activity in all regions, so activity in rarely used regions may go unrecorded
CloudTrail log file validation not enabled
MEDIUMYou cannot prove log files were not modified or deleted after delivery
CloudTrail not sending logs to CloudWatch Logs
LOWYou cannot build real-time metric filters and alarms on CloudTrail events
Reliability — production resources(6)
Only resources tagged Environment=production or prod are evaluated; untagged resources are reported as not evaluated, never as passing.
Resilience & recovery
Production RDS instance is not Multi-AZ
MEDIUMThe instance runs in a single Availability Zone — an AZ outage takes the database offline until it is restored
Production DynamoDB table has no point-in-time recovery
MEDIUMAn accidental delete or bad write cannot be rolled back to an earlier point within the last 35 days
Production Auto Scaling group uses a single Availability Zone
MEDIUMAll instances sit in one AZ, so losing that AZ removes all serving capacity
Production subnets depend on a NAT gateway in another AZ
MEDIUMSubnets route through a NAT gateway in another AZ — that AZ failing cuts outbound access for the others (severity is a 6WAF classification; no matching Security Hub control)
Production resource has no AWS Backup recovery point
MEDIUM / LOWRDS and DynamoDB (Medium) and in-use EBS volumes (Low) are not protected by an AWS Backup plan
Production S3 bucket has versioning disabled
LOWOverwritten or deleted objects cannot be restored to a previous version
Checking all 69 by hand takes days. 6WAF scans in about 10 minutes.
Scan your AWS account for free