Back to Blog AWS Security

AWS Security Best Practices: A Complete Guide for 2025

12 min read

AWS provides powerful security tools, but the shared responsibility model means your organization is accountable for securing everything you build on top of AWS infrastructure. This guide covers the essential security practices every team should implement to protect their AWS workloads.

Understanding the Shared Responsibility Model

Before diving into specific practices, it's crucial to understand what AWS secures versus what you're responsible for:

  • AWS Responsibility: Physical security, hardware, networking infrastructure, and the hypervisor layer
  • Your Responsibility: Operating systems, applications, data, IAM, network configuration, and encryption

Most AWS security breaches occur due to misconfigurations on the customer side - not vulnerabilities in AWS itself.

1. Identity and Access Management (IAM)

IAM misconfigurations are the #1 cause of AWS security incidents. Here's how to get it right:

Enforce Least Privilege Access

Every IAM policy should grant the minimum permissions required to perform a task. Avoid using wildcards (*) in resource ARNs and actions.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": "arn:aws:s3:::my-app-bucket/uploads/*"
        }
    ]
}

Use IAM Roles Instead of Long-Term Credentials

Never embed AWS access keys in your application code. Instead:

  • Use IAM roles for EC2 instances, Lambda functions, and ECS tasks
  • Use IRSA (IAM Roles for Service Accounts) for EKS workloads
  • Use IAM Identity Center (formerly AWS SSO) for human access

Implement MFA Everywhere

Require MFA for:

  • All IAM users with console access
  • Root account (use hardware MFA for root)
  • Sensitive API operations via MFA-protected API calls

Use Permission Boundaries

Permission boundaries prevent privilege escalation by setting maximum permissions that IAM policies can grant:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestedRegion": ["us-east-1", "us-west-2"]
                }
            }
        },
        {
            "Effect": "Deny",
            "Action": [
                "iam:CreateUser",
                "iam:DeleteUser",
                "organizations:*"
            ],
            "Resource": "*"
        }
    ]
}

2. Network Security

VPC Design Principles

  • Use private subnets: Place databases, application servers, and internal services in private subnets with no direct internet access
  • Implement network segmentation: Separate workloads by environment (dev/staging/prod) and function (web/app/data)
  • Use VPC endpoints: Access AWS services like S3, DynamoDB, and Secrets Manager without traversing the internet

Security Groups Best Practices

  • Never use 0.0.0.0/0 for ingress rules except for public-facing load balancers on ports 80/443
  • Reference other security groups instead of IP ranges where possible
  • Use descriptive names and tags for audit purposes
  • Regularly review and remove unused rules

Enable VPC Flow Logs

VPC Flow Logs capture network traffic metadata for security analysis and troubleshooting:

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

3. Data Protection

Encryption at Rest

Enable encryption for all data stores:

  • S3: Enable default bucket encryption with SSE-S3 or SSE-KMS
  • RDS: Enable encryption at database creation (cannot be added later)
  • EBS: Enable default EBS encryption at the account level
  • DynamoDB: Use AWS-managed or customer-managed KMS keys

Encryption in Transit

  • Enforce HTTPS for all public endpoints using ACM certificates
  • Enable TLS for RDS connections
  • Use VPC endpoints to keep traffic within the AWS network

S3 Bucket Security

S3 bucket misconfigurations are a leading cause of data breaches. Implement these controls:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::my-bucket",
                "arn:aws:s3:::my-bucket/*"
            ],
            "Condition": {
                "Bool": {
                    "aws:SecureTransport": "false"
                }
            }
        }
    ]
}
  • Enable S3 Block Public Access at the account level
  • Use bucket policies to enforce encryption and HTTPS
  • Enable versioning and MFA delete for critical buckets
  • Use S3 Object Lock for compliance requirements

4. Logging and Monitoring

Enable AWS CloudTrail

CloudTrail logs all API calls across your AWS account. Enable it organization-wide with these settings:

  • Multi-region trail to capture activity in all regions
  • Log file validation to detect tampering
  • S3 bucket with versioning and MFA delete
  • CloudWatch Logs integration for real-time alerting

Set Up Security Alerts

Create CloudWatch alarms for critical security events:

  • Root account usage
  • IAM policy changes
  • Security group modifications
  • Failed console login attempts
  • KMS key deletion or disabling

Use AWS Security Hub

Security Hub aggregates findings from multiple AWS services and third-party tools:

  • Enable the AWS Foundational Security Best Practices standard
  • Enable CIS AWS Foundations Benchmark checks
  • Integrate with GuardDuty, Inspector, and Macie
  • Set up automated remediation for common findings

5. Secrets Management

Use AWS Secrets Manager

Never hardcode credentials. Store and rotate secrets automatically:

# Retrieve secret in application code
import boto3
import json

def get_secret(secret_name):
    client = boto3.client('secretsmanager')
    response = client.get_secret_value(SecretId=secret_name)
    return json.loads(response['SecretString'])

Enable Automatic Rotation

Configure automatic rotation for database credentials and API keys. Secrets Manager supports native rotation for RDS, Redshift, and DocumentDB.

6. Infrastructure as Code Security

Scan Terraform/CloudFormation Before Deployment

Use tools like Checkov, tfsec, or cfn-nag to catch misconfigurations before they reach AWS:

# Example: Running Checkov on Terraform
checkov -d ./terraform --framework terraform

# Common findings:
# - S3 buckets without encryption
# - Security groups with 0.0.0.0/0
# - RDS instances without encryption
# - IAM policies with wildcard permissions

Use Service Control Policies (SCPs)

In AWS Organizations, use SCPs to enforce guardrails across all accounts:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": [
                "ec2:RunInstances"
            ],
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "StringNotEquals": {
                    "ec2:InstanceType": [
                        "t3.micro",
                        "t3.small",
                        "t3.medium"
                    ]
                }
            }
        }
    ]
}

7. Incident Response Preparation

Enable AWS GuardDuty

GuardDuty uses machine learning to detect threats across your AWS environment:

  • Cryptocurrency mining detection
  • Compromised EC2 instances
  • Unauthorized access patterns
  • S3 bucket compromise

Create Incident Response Runbooks

Document procedures for common scenarios:

  • Compromised IAM credentials
  • Exposed S3 bucket
  • Cryptominer detected on EC2
  • Unusual API activity from GuardDuty

Quick Wins Checklist

Start with these high-impact, low-effort security improvements:

  • Enable MFA on root and all IAM users
  • Enable S3 Block Public Access at account level
  • Enable default EBS encryption
  • Enable CloudTrail in all regions
  • Enable GuardDuty
  • Enable Security Hub with AWS Foundational Security Best Practices
  • Review and remove unused IAM users, roles, and access keys
  • Enable AWS Config to track resource configurations

Next Steps

AWS security is an ongoing process, not a one-time setup. Regularly review your security posture using AWS Security Hub, conduct access reviews, and stay updated on new AWS security features.

Need help securing your AWS infrastructure? Contact us for a comprehensive security assessment and implementation support.