Introduction
After spending years helping teams set up their AWS infrastructure, I've noticed something interesting: many of us face the same security challenges when starting out. You know what I mean if you've ever wondered "Wait, is my S3 bucket actually secure?" or "Should I really be using the root account for this?" (Spoiler: probably not!)
The good news? I've put together this guide to help you build a rock-solid AWS security foundation from day one. We'll cover 10 essential security measures that I've seen make a real difference in protecting AWS environments. While absolute security is a journey rather than a destination, implementing these steps will put you way ahead of the game in defending against common attack vectors.
And I've also created a Terraform project that you can use as baseline for your securing your AWS account!
The best part? It's all under the AWS free tier! š
Essentially, I got tired or reading the same posts regarding people (or organizations) getting their account hacked, here's my solution for that!
1. Set up AWS Organizations
Let's talk about AWS Organizations, it's one of those services that I wish someone had told me about when I first started with AWS!
What is AWS Organizations?
AWS Organizations is like a control center for all your AWS accounts. Think of it as a tree for your AWS infrastructure, where you can manage multiple accounts under one umbrella. Even if you're starting with just one account, setting up Organizations from day one is a smart move (I'll tell you why in a moment!).
Why Organizations is Essential for Security
Here's what makes Organizations so powerful:
- Centralized Security Management: Apply security policies across all accounts from one place
- Consolidated Billing: One bill for all accounts (and often volume discounts!)
- Service Control Policies (SCPs): Think of these as guardrails that prevent security troubles
- API-driven account creation: Automate new account creation (super handy as you grow)
Benefits for Single Account Holders
"But wait," you might say, "I only have one account!" Trust me, I hear this a lot. Here's why Organizations is still valuable for you:
- Future-Proofing: When (not if) you need another account for development/staging, you're ready
- Security Best Practices: You can set SCPs only with AWS Organization
- Cost Management: Track and categorize spending more effectively
- Free to Use: There's no additional cost for using Organizations, right under the AWS Free Tier
Quick Setup Guide
- Log into your AWS root account
- Navigate to AWS Organizations
- Click "Create Organization"
- Choose "All features" (don't limit yourself!)
Want to make this even easier? My Terraform module sets this all up automatically with best practices in it!
Your AWS account structure is like the foundation of a house: it's much easier to get it right from the start than to renovate later!
2. Implement AWS Single Sign-On (SSO)
If you're still creating IAM users and managing access keys, let me introduce you to a game-changer: AWS SSO (now called IAM Identity Center).
What is AWS SSO?
AWS Single Sign-On (SSO), now called AWS IAM Identity Center, is a cloud service that lets you centrally manage access to your AWS accounts and business applications. Instead of having individual IAM users with long-term access keys in each AWS account, users log in once through a web portal and get temporary security credentials to access AWS resources.
Think of it like this:
- Old way: Create IAM users in each account, manage access keys, update permissions in multiple places
- SSO way: Users log in once at
, click on the account/role they need, and get instant secure accesshttps://your-domain.awsapps.com/start
Why AWS SSO is Awesome
With AWS SSO you can say goodbye to a very long list of "bad practices":
- No More Access Key Management: Users log in through a web portal instead
- Temporary Credentials: Security tokens that expire automatically
- Centralized Access Control: Manage permissions for all accounts in one place
- Perfect with Organizations: Works seamlessly with the structure we just set up
Here's what makes SSO particularly secure:
User Login ā SSO Portal ā Temporary Credentials ā AWS Access ā³ MFA Required ā³ Auto-expires ā³ Limited Scope
Every access is:
- Authenticated (you prove who you are)
- Authorized (you get only the permissions you need)
- Audited (every login is logged)
- Temporary (credentials expire automatically)
There are 2 things to keep in mind, AWS Managed policies and Customer Managed policies. Customer Managed policies are custom policies and they need to be replicated in each AWS account..
Setting It Up
- Go to IAM Identity Center in your Organization's management account
- Click "Enable"
This step can only be done manually, unfortunately AWS doesn't support enabling SSO programmatically. After you have done this part, you can continue with the Terraform.
Best Practices I've Learned
- Always Enable MFA: Make it mandatory for all users. The best part? It's enabled by default š¤©
- Use Groups: Assign permissions to groups, not individual users
- Regular Access Reviews: Review permissions!
- It's free: AWS SSO is free under the AWS Free Tier
Good security should make the right way the easy way. AWS SSO does exactly that!
Anyway, if you have just opened you AWS account, I highly suggest to create an "Admin" group and put your user in there! This way you can ditch the root user you are probably using right now.
3. Enable Multi-Factor Authentication (MFA)
If you're not using MFA yet, this is probably the most important section of this guide.
What is MFA and Why It's Non-Negotiable
MFA adds an extra verification step when someone tries to access your AWS accounts:
- Something you know (password)
- Something you have (MFA device/app)
Without MFA, a compromised password means game over. With MFA, attackers need both pieces of the puzzle!
Essential MFA Setup Checklist
Root Account MFA (Absolutely Critical! šØ)
AWS Console ā Root user ā Security credentials ā Assign MFA device ā Choose Virtual MFA device
IAM Users MFA (For any remaining IAM users)
IAM ā Users ā User name ā Security credentials ā Assign MFA device
SSO Users MFA (Remember our previous section?)
IAM Identity Center ā Settings ā Multi-factor authentication ā Enable
Protecting Sensitive Operations
Here's a cool trick - you can require MFA for specific operations. For example, protecting CloudTrail logs deletion:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "RequireMFAForDelete", "Effect": "Deny", "Action": "s3:DeleteObject", "Resource": "arn:aws:s3:::my-cloudtrail-bucket/*", "Condition": {"BoolIfExists": {"aws:MultiFactorAuthPresent": false}} } ] }
Best Practices I Always Follow
- Backup MFA: Store MFA recovery codes in a secure password manager
- Test Recovery: Practice account recovery procedures.
Quick Setup Guide
Setting up Virtual MFA (most common option):
- Download an authenticator app (like Google Authenticator)
- Scan the QR code from AWS
- Enter two consecutive codes to verify
- Store recovery codes safely
Common Questions
These are some questions I get asked a lot:
Q: "What if I lose my MFA device?" A: That's why we keep recovery codes. If you have lost them, no worries, the AWS Support can help, you will need to identify yourself.
Q: "Isn't this overkill for a small account?" A: Not at all. This is the number one best practices to follow. There are some other guardrails that may be overkill for non-organizations, but this one, it's a life saver!
4. Configure Service Control Policies (SCPs)
Time to talk about Service Control Policies (SCPs): your organization's security guard rails! These are like having organization-wide rules that no one (not even account administrators) can override.
What Are SCPs, Really?
Think of SCPs as a firewall for AWS actions:
- They define maximum permissions (what CAN'T be done)
- Apply to all users and roles (even root users!)
- Work across your entire AWS Organization
User Permissions = IAM Policies ā© SCPs (In other words: you only get permissions allowed by BOTH)
Essential SCPs for Every AWS Organization
Here are my top "must-have" SCPs that I implement in every environment:
- Prevent Root User Actions
- Require MFA for Sensitive Actions
- Restrict Regions (reduce attack surface)
- Deny disabling CloudTrail
- Deny leaving the AWS Organizations
There are many more examples online if you want to add a few more SCPs to restrict even more your AWS environment.
Common Gotchas to Avoid
ā ļø Watch out for these common mistakes:
- SCPs don't affect service-linked roles
- SCPs don't grant permissions (they only restrict)
- Maximum 5 SCPs for account/OU and maximum size is 5120 bytes (choose conditions wisely!)
- As of now, there is no way to debug or to test them out
5. Set up AWS Budgets Alarms
Let's talk money! š° AWS Budgets Alarms aren't just about controlling costs, they're also an excellent security tool. Unexpected spikes in AWS bills often indicate security issues (like crypto mining on compromised resources).
Why Budget Alarms are a Security Feature
Here's a secret many don't know: Budget alarms can be your first warning of:
- Compromised access keys mining crypto
- DDoS attacks consuming resources
- Misconfigured autoscaling groups
- Forgotten running resources
Essential Budget Alerts to Set Up
I recommend starting with these three basic budgets:
- Overall Monthly Spend
- Free Tier Usage
- Anomaly Detection
Best Practices for Budget Alarms
Set Multiple Thresholds
- 80% warning
- 90% warning
- 100% alert
Use Multiple Contact Methods
- Email notifications
- SNS topics for automation
- Consider integration with Slack/Teams
Free Tier Considerations
Good news! AWS Budgets is partially free:
- First two budgets are free
- Additional budgets cost $0.10/day
Anyway, you can do just fine with 2 budgets within the AWS Free Tier āļø
Cost monitoring isn't just about saving money, it's an essential part of your security monitoring strategy!
6. Use IAM Roles with Least Privilege
One of the most fundamental AWS security principles is the concept of least privilege: giving users and services only the permissions they absolutely need to perform their tasks. IAM Roles are the preferred way to implement this principle in AWS, as they provide temporary credentials and eliminate the need for storing long-term access keys.
If you're wondering why this matters so much, think of it this way: you wouldn't give your house keys to everyone who needs to drop off a package, right? The same goes for AWS permissions!
Understanding IAM Roles
IAM Roles are like virtual users that can be assumed by AWS services, applications, or human users. Unlike traditional IAM users with permanent credentials, roles provide temporary security credentials that automatically rotate. The best part? No more storing long-term access keys (which, trust me, can be a security nightmare).
Implementing Least Privilege
Here's how I approach implementing least privilege with IAM Roles:
- Start with Zero Trust: I know it's tempting to just click "full access," but trust me, start with zero permissions add only what's necessary
- Use AWS-Managed Policies Carefully: While convenient, these often provide more permissions than needed, like using a sledgehammer when you need a scalpel
- Create Custom Policies: Write specific policies that match your exact requirements
- Use Policy Conditions: Add restrictions based on IP ranges, time of day, or required MFA
Practical Tips for Implementation
Look, I get it, implementing least privilege can be a pain. Here's what works for me in the real world:
- Use AWS IAM Access Analyzer to identify unused permissions
- Enable CloudTrail to monitor actual usage (more on this later š)
- Implement session tags to add additional context to role assumptions
- Regular review cycles to remove unnecessary permissions
When Things Get Tricky
Let's be honest, sometimes least privilege is harder than it sounds. The elephant in the room is: Development Speed vs. Security
This topic is tricky, teams often need quick access during development and can't wait 2 weeks for new permissions. Here are some solutions:
- Create separate roles for development and production environments
- Dive access to a sandbox account, this account is usually detached from your main network š
- Create practical documentation on how to test locally, if possible
Practical Role Management
Here's what works for me:
- Name roles clearly:
is better thanprod-api-read-only
role1
- Document everything: Future you will appreciate knowing why each permission exists
- Use tags wisely: They're great for keeping things organized
- Audit regularly: Set a calendar reminder for quarterly reviews
When Perfect Isn't Possible
Sometimes you can't get least privilege perfect right away. Here's what to do instead:
- Lock down your network with VPC endpoints
- Use time-based restrictions when possible
- Implement resource tagging, and limit access with ABAC
- Add IP-based conditions
Those are some best practices I've learned along the way. If you're just starting with AWS and don't want to go down this complex path right now, that's okay! Just make sure to use Administrator access only for MFA-backed users! It's not perfect, but it's way better than having non-MFA admin accounts running around. You can always come back to implement more granular permissions later.
7. Rotate Access Keys and Passwords Regularly
Let's talk about one of those security practices that everyone knows they should do but often forgets: rotating access keys and passwords.
Why Rotate Access Keys?
You might be wondering why we need to rotate keys if they haven't been compromised. Here's the thing: you might not always know if they've been compromised! Regular rotation helps limit the potential damage from undetected breaches and ensures that any leaked credentials have a limited lifetime.
Key Rotation
AWS makes this pretty straightforward. Here's how to get started:
For IAM Users:
- Use AWS IAM to create a new active access keys
- Replace the old one with the new one
- Test everything
- Deactivate
- Test everything again
For Applications:
- Use AWS Secrets Manager (my preferred choice) or AWS System Manager Parameter Store
- Set up automatic rotation schedules
- In your application, make the API call
For CI/CD:
- For some of them you don't even need a IAM User
- For others, I suggest the IAM User to only assume another role used for deploying everything
Best Practices I've Learned
Rotation Schedule:
- 90 days for regular access keys
- 30 days for high-privilege accounts
- Immediate rotation if you suspect compromise
Documentation:
- Keep a rotation schedule
- Document emergency procedures
8. Enable CloudTrail
If you're not using it yet, you're flying blind, and trust me, that's not where you want to be! š«
Why CloudTrail Is a Must-Have
Think of CloudTrail as your AWS security camera system. It records:
- Who's doing what in your account
- When they did it
- Where they did it from
- Whether they succeeded or failed
Setting Up CloudTrail (The Right Way)
Here's my recommended setup:
- ā Enable multi-region logging
- ā Enable log file validation
- ā Enable CloudWatch Logs integration
- ā Turn on S3 Object Lock for compliance
- ā Enable MFA Delete on S3
Anyway, if you are using the Terraform template, it comes out of the box š
9. Properly Configure S3 Bucket Policies
I've seen too many news headlines about exposed S3 buckets, so let's make sure yours isn't next! š”ļø
Block Public Access (No Exceptions!)
No need to do anything, it's enabled by default. Just don't disable it š
Secure Bucket Policy Template
Here's a solid starting point for your bucket policies, we are going to allow only HTTPS traffic:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "DenyHTTP", "Effect": "Deny", "Principal": "*", "Action": "s3:*", "Resource": [ "arn:aws:s3:::your-bucket", "arn:aws:s3:::your-bucket/*" ], "Condition": { "Bool": { "aws:SecureTransport": "false" } } } ] }
Serving Content Securely
Need to serve public content? Here's the right way: use CloudFront
- Create a CloudFront distribution
- Use Origin Access Control (OAC)
- Enable HTTPS only
- Set up custom domain if needed
- Update S3 Bucket Policy
Best Practices I Always Follow
- Use unique, non-guessable names
- Consider using prefixes for organization
- Use folders for access control
- Implement lifecycle policies
- Use presigned URLs for temporary access
- Implement VPC endpoints for internal access
- Use bucket policies for cross-account access (not roles)
10. Use VPCs and Network Segmentation
Please, please, please don't leave your security groups wide open to the internet! š° At least use your own IP address!
Why Default VPC Is Not Your Friend
The default VPC is like leaving your front door unlocked. Sure, it's convenient, but:
- It's too permissive by default
- Everyone knows its structure
- It lacks proper segmentation
That being said, you need to create your own VPC. AWS has a neat interface for doing it, but I highly suggest you to write one with Terraform (or another IAC tool), it's really simple, you can even use a module from the community. Anyway, time to design our VPC:
- Public Subnets: Only for load balancers and bastion hosts, this subnet has an Internet Gateway
- Private Subnets: For your applications, if you need internet use NAT or a NAT instance
- Database Subnets: Isolated from everything else. Use managed services as database so you don't need to download updates from the internet
šØ Security Groups - The Golden Rules šØ
This is crucial:
- ā NEVER allow 0.0.0.0/0 to your security groups except for load balancers
- ā NEVER open all ports (like port range 0-65535)
- ā NEVER use the default security group
This alone will prevent most of the attacks!
Conclusion
And there you have it, folks. That was a lot to take in, wasn't it? But you will thank me in the future, or not cause with these best practices it's unlikely your are getting hacked!
Anyway, if you're feeling overwhelmed, here's your bare minimum security checklist:
- ā Turn on CloudTrail
- ā Block public access to S3 buckets
- ā Never allow 0.0.0.0/0 in security groups (except for load balancers)
- ā Use AWS Organizations for account management
- ā Enable SSO with MFA
- ā Enable MFA on root and IAM users
Security isn't a one-time setup, it's a journey. Don't know where to start? Here is a complete baseline to get started š
Here's the link to my GitHub repository: https://github.com/Depaa/terraform-aws-security-baseline š
p.s. there's another great tool that can help you with the setup, it's called AWS Control Tower. I didn't want to include too much information as we've covered a lot here already. If that's something that interests you, let me know.
If you enjoyed this article, please let me know in the comment section or send me a DM. I'm always happy to chat! āļø
Thank you so much for reading! š Keep an eye out for more AWS-related posts, and feel free to connect with me on LinkedIn š https://www.linkedin.com/in/matteo-depascale/.
References
- https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html
- https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html
- https://docs.aws.amazon.com/awscloudtrail/latest/userguide/WhatIsCloudTrail-Security.html
- https://docs.aws.amazon.com/AmazonS3/latest/userguide/security-best-practices.html
- https://docs.aws.amazon.com/vpc/latest/userguide/vpc-security-best-practices.html
Disclaimer: opinions expressed are solely my own and do not express the views or opinions of my employer.