AWS can scale your business overnight — or expose it if misconfigured. From IAM sprawl to open S3 buckets, mistakes are common. Security in AWS requires defense in depth.
1. IAM as the First Line
- Favor least privilege roles
- Avoid all-powerful
AdministratorAccess
policies
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-app-bucket/user-uploads/*",
"Condition": {
"StringEquals": {
"s3:x-amz-server-side-encryption": "aws:kms"
}
}
}
]
}
2. VPC for Layered Defense
- Public subnets for entry points
- Private subnets for app and database tiers
- Restrictive security groups between layers
AppSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Application tier security group
VpcId: !Ref VPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
SourceSecurityGroupId: !Ref LoadBalancerSecurityGroup
3. Encrypt at Rest and in Transit
- KMS for S3 and RDS
- SSL enforcement on databases
- TLS for all APIs
const AWS = require('aws-sdk');
const s3 = new AWS.S3();
const params = {
Bucket: 'secure-bucket',
Key: 'data.json',
Body: JSON.stringify({ secure: true }),
ServerSideEncryption: 'aws:kms',
SSEKMSKeyId: process.env.KMS_KEY_ID
};
await s3.upload(params).promise();
4. Monitor and Detect
- CloudTrail for audit logs
- CloudWatch alarms for anomalies
- GuardDuty for threat detection
CloudTrail:
Type: AWS::CloudTrail::Trail
Properties:
TrailName: my-audit-trail
S3BucketName: !Ref AuditLogsBucket
IsMultiRegionTrail: true
EnableLogFileValidation: true
5. Manage Secrets Properly
Leverage Secrets Manager or SSM Parameter Store with automated rotation.
const AWS = require('aws-sdk');
const sm = new AWS.SecretsManager();
const secret = await sm.getSecretValue({ SecretId: 'prod/db-password' }).promise();
console.log(secret.SecretString);
6. Automate Compliance
Use Lambda or Config Rules to detect — and remediate — insecure configurations in real time.
import boto3
def lambda_handler(event, context):
ec2 = boto3.client('ec2')
sgs = ec2.describe_security_groups()['SecurityGroups']
for sg in sgs:
for rule in sg.get('IpPermissions', []):
for ip_range in rule.get('IpRanges', []):
if ip_range.get('CidrIp') == '0.0.0.0/0':
print(f"Insecure SG found: {sg['GroupId']}")
The cloud is only as secure as the guardrails you define.
With the right practices, AWS becomes not just scalable, but dependable.
I design AWS environments where security is baked in, not bolted on.
See case studies and services: kodex.studio
Top comments (0)