← Back to Blog

AWS Security Checklist for Production (Real Examples)

Most AWS breaches do not happen because of sophisticated zero-day exploits. They happen because of misconfigured S3 buckets, overpermissive IAM policies, and disabled logging. This checklist covers every critical AWS security control with real configuration examples you can apply today.

IAM: Identity and Access Management

IAM is the single most important security layer in AWS. Every other control depends on it. Get IAM wrong and nothing else matters.

Enable MFA on the Root Account

The root account has unrestricted access to everything in your AWS account. Enable hardware MFA (YubiKey preferred) on the root account immediately. Never use the root account for daily operations. Create IAM users or use AWS SSO instead.

Enforce Least Privilege IAM Policies

Every IAM policy should grant the minimum permissions needed. Never use Action: "*" or Resource: "*" in production policies. Here is a real example of a properly scoped policy for an application that needs to read from S3 and write to DynamoDB:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-app-data",
        "arn:aws:s3:::my-app-data/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "dynamodb:PutItem",
        "dynamodb:GetItem",
        "dynamodb:Query"
      ],
      "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/my-app-table"
    }
  ]
}

Use IAM Roles Instead of Access Keys

Long-lived access keys are the most common source of AWS credential leaks. Use IAM roles with temporary credentials wherever possible:

  • EC2 instances: Use instance profiles (IAM roles attached to EC2)
  • ECS/EKS: Use task roles (ECS) or IRSA (EKS)
  • Lambda: Use execution roles
  • CI/CD: Use OIDC federation (GitHub Actions, GitLab CI) instead of storing access keys
  • Cross-account: Use STS AssumeRole

If you must use access keys, rotate them every 90 days and monitor for exposure using the techniques in our API key exposure detection guide.

Enable IAM Access Analyzer

IAM Access Analyzer identifies resources shared with external entities and validates IAM policies against best practices. Enable it in every region:

aws accessanalyzer create-analyzer \
  --analyzer-name production-analyzer \
  --type ACCOUNT \
  --region us-east-1

Check Your Web Infrastructure Security

AWS security is only one layer. Make sure your web application is not exposing secrets through .env files, git directories, or misconfigured headers.

Scan Your Domain Free

S3: Storage Security

Block Public Access (Account Level)

Enable S3 Block Public Access at the account level. This is the single most impactful S3 security control:

aws s3control put-public-access-block \
  --account-id 123456789012 \
  --public-access-block-configuration \
    BlockPublicAcls=true,\
    IgnorePublicAcls=true,\
    BlockPublicPolicy=true,\
    RestrictPublicBuckets=true

Enable Default Encryption

Every S3 bucket should have default encryption enabled. Use SSE-S3 (AES-256) as a baseline, or SSE-KMS for additional control over key management:

aws s3api put-bucket-encryption \
  --bucket my-production-bucket \
  --server-side-encryption-configuration '{
    "Rules": [{
      "ApplyServerSideEncryptionByDefault": {
        "SSEAlgorithm": "aws:kms",
        "KMSMasterKeyID": "arn:aws:kms:us-east-1:123456789012:key/key-id"
      },
      "BucketKeyEnabled": true
    }]
  }'

Enable Versioning and Object Lock

Versioning protects against accidental deletion and ransomware. Object Lock provides immutable backups:

aws s3api put-bucket-versioning \
  --bucket my-production-bucket \
  --versioning-configuration Status=Enabled

VPC: Network Security

Minimize Security Group Rules

Every security group should follow least privilege. Never use 0.0.0.0/0 for inbound rules except for public-facing load balancers on ports 80 and 443. Here is an example of a properly configured application security group:

# Application server - only accepts traffic from ALB
aws ec2 authorize-security-group-ingress \
  --group-id sg-app-server \
  --protocol tcp --port 8080 \
  --source-group sg-alb

# Database - only accepts traffic from application
aws ec2 authorize-security-group-ingress \
  --group-id sg-database \
  --protocol tcp --port 5432 \
  --source-group sg-app-server

Use VPC Flow Logs

Enable VPC Flow Logs to capture network traffic metadata. This is essential for forensic investigation and anomaly detection:

aws ec2 create-flow-logs \
  --resource-type VPC \
  --resource-ids vpc-123456 \
  --traffic-type ALL \
  --log-destination-type cloud-watch-logs \
  --log-group-name /vpc/flow-logs/production

Use Private Subnets for Backend Services

Databases, caches, application servers, and internal services should run in private subnets with no direct internet access. Use NAT Gateways for outbound traffic and VPC endpoints for AWS service access. Use the Subnet Calculator to plan your CIDR allocation.

Logging and Monitoring

Enable CloudTrail in All Regions

CloudTrail records every API call in your AWS account. Enable it in all regions with a multi-region trail:

aws cloudtrail create-trail \
  --name production-trail \
  --s3-bucket-name my-cloudtrail-bucket \
  --is-multi-region-trail \
  --enable-log-file-validation \
  --kms-key-id arn:aws:kms:us-east-1:123456789012:key/key-id

aws cloudtrail start-logging --name production-trail

Enable GuardDuty

GuardDuty provides intelligent threat detection by analyzing CloudTrail, VPC Flow Logs, and DNS logs. Enable it in every region:

aws guardduty create-detector --enable

GuardDuty detects cryptocurrency mining, unauthorized access attempts, compromised instances, and data exfiltration patterns. It costs approximately $1 to $2 per million events analyzed.

Set Up CloudWatch Alarms

Create alarms for critical security events:

  • Root account login
  • Failed console login attempts (more than 3 in 5 minutes)
  • IAM policy changes
  • Security group changes
  • S3 bucket policy changes
  • CloudTrail configuration changes
  • Unauthorized API calls

Data Protection

Enable RDS Encryption

All RDS instances should have encryption at rest enabled. This cannot be changed after creation, so enable it from the start. Enable automated backups with a retention period of at least 7 days (35 days recommended for production).

Use AWS Secrets Manager

Never hardcode database passwords, API keys, or other secrets. Use AWS Secrets Manager with automatic rotation:

aws secretsmanager create-secret \
  --name production/database/credentials \
  --secret-string '{"username":"app_user","password":"generated-password"}'

# Enable automatic rotation
aws secretsmanager rotate-secret \
  --secret-id production/database/credentials \
  --rotation-lambda-arn arn:aws:lambda:us-east-1:123456789012:function:rotate-db-secret \
  --rotation-rules AutomaticallyAfterDays=30

Learn more about securing secrets in our environment variables security guide.

Enable EBS Encryption by Default

aws ec2 enable-ebs-encryption-by-default --region us-east-1

The Complete Checklist

  1. Root account MFA enabled (hardware key preferred)
  2. No root access keys exist
  3. IAM password policy enforced (14+ characters, MFA required)
  4. All IAM policies follow least privilege
  5. IAM roles used instead of access keys where possible
  6. IAM Access Analyzer enabled
  7. S3 Block Public Access enabled (account level)
  8. S3 default encryption enabled on all buckets
  9. S3 versioning enabled on critical buckets
  10. VPC Flow Logs enabled
  11. Security groups follow least privilege (no 0.0.0.0/0 on non-public ports)
  12. Backend services in private subnets
  13. CloudTrail enabled in all regions with log validation
  14. GuardDuty enabled in all regions
  15. CloudWatch alarms for security events
  16. RDS encryption at rest enabled
  17. EBS encryption by default enabled
  18. AWS Secrets Manager for all credentials
  19. AWS Config enabled for compliance monitoring
  20. Billing alerts configured

Frequently Asked Questions

How much does AWS security tooling cost?

The core security services are surprisingly affordable. CloudTrail costs $2 per 100,000 management events (first trail is free). GuardDuty costs $1 to $4 per million events. AWS Config costs $0.003 per configuration item. For a small to mid-sized production environment, expect to spend $50 to $200 per month on security tooling. This is negligible compared to the cost of a breach, which averages $3.31 million for organizations under 500 employees.

Should I use AWS Organizations for a single account?

Yes. Even with a single account, AWS Organizations provides Service Control Policies (SCPs) that act as guardrails. You can use SCPs to prevent disabling CloudTrail, removing encryption, or making S3 buckets public. As you grow, you can add separate accounts for staging, development, and security tooling. Multi-account architecture is an AWS best practice for production environments.

What is the most overlooked AWS security control?

CloudTrail log file validation. Many organizations enable CloudTrail but skip log file validation, which means an attacker with access could modify or delete logs to cover their tracks. Always enable log file validation and store CloudTrail logs in a separate, locked-down S3 bucket with Object Lock enabled. Also frequently overlooked: checking what your web application exposes publicly. Run the SecureBin Exposure Checker to catch exposed configuration files that might contain AWS credentials.

Verify Your Web Security Posture

AWS infrastructure security means nothing if your application exposes .env files with database credentials. SecureBin Exposure Checker catches these issues in seconds.

Run Free Security Check

The Bottom Line

AWS security is not about implementing every possible control. It is about consistently applying the fundamentals: least privilege IAM, encrypted storage, comprehensive logging, and network segmentation. The checklist above covers the controls that prevent the vast majority of AWS breaches. Start at the top, work through each item, and build security into your infrastructure from the beginning. Retrofitting security is always harder and more expensive than building it in from day one.

Related reading: Cloud Misconfigurations That Lead to Breaches, Secure Environment Variables in Production, How to Check if API Key is Exposed, SOC 2 Compliance Checklist.