AWS Security
AWS IAM Security Best Practices: Protecting Your Cloud Identity
Master AWS IAM security with practical best practices for identity management, access control, and privilege governance in your cloud environment.
CloudPoint Team
Identity and Access Management (IAM) is the first line of defense in AWS security. Misconfigurations in IAM are among the most common security vulnerabilities, yet they’re also the most preventable. This guide covers essential IAM security practices for protecting your AWS environment.
The Principle of Least Privilege
The foundation of IAM security is granting only the minimum permissions necessary.
What It Means
Users and services should have access to only what they need to perform their specific job functions - nothing more.
Why It Matters
- Limits blast radius: Compromised credentials can’t do as much damage
- Reduces risk of accidents: Users can’t accidentally delete critical resources
- Compliance requirement: Many frameworks mandate least privilege
- Easier auditing: Clear understanding of who can do what
How to Implement
- Start with Nothing: Begin with no permissions, add as needed
- Use Permission Boundaries: Set maximum permissions users can have
- Regular Reviews: Remove permissions that are no longer needed
- Test Permissions: Verify users have access to required resources
- Document Reasoning: Keep track of why specific permissions were granted
Root Account Security
The root account has unrestricted access to everything in your AWS account. Protecting it is critical.
Essential Protections
1. Enable MFA with Hardware Token
- Use a hardware security key (YubiKey) or hardware token
- Avoid virtual MFA apps for root account
- Store backup MFA device securely offline
2. Use Strong, Unique Password
- Generate with a password manager
- Minimum 32 characters
- Store in secure, offline location
- Never share or reuse
3. Delete Access Keys
- Root account should never have programmatic access keys
- If they exist, delete them immediately
4. Minimize Usage
- Only use for tasks that absolutely require root
- Document when and why root access was used
- Set up CloudWatch alarms for root activity
5. Secure Contact Information
- Use monitored email address
- Keep contact details current
- Secure the email account with MFA
6. Lock Away Credentials
- Store in physical safe or encrypted vault
- Require multiple people to access
- Document emergency access procedures
Monitoring Root Account Activity
Configure CloudWatch alarm for root account usage:
{
"source": ["aws.signin"],
"detail-type": ["AWS Console Sign In via CloudTrail"],
"detail": {
"userIdentity": {
"type": ["Root"]
}
}
}
Send alerts to security team immediately.
IAM Users vs IAM Identity Center
When to Use IAM Users
Limited circumstances:
- Service accounts (prefer roles where possible)
- Break-glass emergency access
- Programmatic access where roles aren’t available
Not for:
- Regular human user access
- Cross-account access
- Temporary access
When to Use IAM Identity Center
Preferred for human users:
- Multi-account environments
- Centralised access management
- SSO integration
- Temporary credentials
- Audit trail
Migration Path
If you’re using IAM users today:
- Deploy IAM Identity Center: Set up in management account
- Create Permission Sets: Mirror existing IAM policies
- Create Groups: Organise users
- Migrate Users: Enable in Identity Center, disable IAM users
- Remove IAM Users: After confirming Identity Center works
- Delete Access Keys: Eliminate long-lived credentials
MFA Enforcement
Multi-factor authentication should be mandatory, not optional.
Who Needs MFA
Required:
- Root account (hardware token)
- All human users (any MFA method)
- Users with administrative access (hardware token preferred)
- Users accessing production (any MFA method)
- Users accessing sensitive data (any MFA method)
Optional:
- Service accounts (use roles instead)
- Read-only access to non-sensitive resources
MFA Options
Hardware Security Key (Most Secure):
- YubiKey
- Titan Security Key
- Supports multiple AWS accounts on one device
Hardware Token:
- Gemalto tokens
- Display rotating codes
- More expensive but very secure
Virtual MFA (Acceptable):
- Google Authenticator
- Authy
- 1Password
- Microsoft Authenticator
SMS (Avoid):
- Vulnerable to SIM swapping
- Not supported for AWS root account
- Only use if no other option
Enforcing MFA
Use IAM policies to require MFA for sensitive actions:
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyAllExceptListedIfNoMFA",
"Effect": "Deny",
"NotAction": [
"iam:CreateVirtualMFADevice",
"iam:EnableMFADevice",
"iam:ListMFADevices",
"iam:ListUsers",
"iam:ListVirtualMFADevices",
"sts:GetSessionToken"
],
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": "false"
}
}
}]
}
Access Key Management
Long-lived access keys are a security risk.
Best Practices
1. Prefer Temporary Credentials
- IAM roles for EC2/Lambda/ECS
- IAM Identity Center for users
- STS AssumeRole for cross-account
2. Rotate Keys Regularly
- Maximum 90 days
- Automated rotation where possible
- Document active keys
3. Never Commit to Code
- Use environment variables
- AWS Secrets Manager
- Parameter Store
- Never in source control
4. Limit Privileges
- Keys should have minimal permissions
- Separate keys for different purposes
- Never use root account keys
5. Monitor Usage
- CloudTrail logs all API calls
- Alert on unusual patterns
- Review Access Advisor regularly
Detecting Unused Keys
Use IAM credential report:
aws iam generate-credential-report
aws iam get-credential-report --query 'Content' --output text | base64 -d > credential_report.csv
Review for:
access_key_1_last_used_dateoraccess_key_2_last_used_dateolder than 90 days- Keys that have never been used
- Users who haven’t logged in recently
IAM Policies: Structure and Best Practices
Policy Structure
Policies are JSON documents defining permissions:
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DescriptiveIdentifier",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": "203.0.113.0/24"
}
}
}]
}
Writing Secure Policies
1. Use Specific Resources
// Bad - Too broad
"Resource": "*"
// Good - Specific resources
"Resource": [
"arn:aws:s3:::my-specific-bucket",
"arn:aws:s3:::my-specific-bucket/*"
]
2. Limit Actions
// Bad - Wildcard
"Action": "s3:*"
// Good - Specific actions
"Action": [
"s3:GetObject",
"s3:PutObject"
]
3. Use Conditions
"Condition": {
"StringEquals": {
"s3:x-amz-server-side-encryption": "AES256"
},
"IpAddress": {
"aws:SourceIp": ["203.0.113.0/24"]
}
}
4. Avoid NotAction
- Difficult to maintain
- Easy to accidentally grant too much
- Use explicit Allow instead
Managed vs Inline Policies
AWS Managed Policies:
- Maintained by AWS
- Best practices built-in
- Regularly updated
- Use when they fit your needs
Customer Managed Policies:
- Reusable across users/groups/roles
- Version controlled
- Easier to audit
- Preferred for custom permissions
Inline Policies:
- Attached directly to single user/group/role
- Deleted with the principal
- Use rarely, for exceptions only
IAM Roles and AssumeRole
Roles are the preferred way to grant permissions in AWS.
Types of Roles
Service Roles: For AWS services (EC2, Lambda, ECS)
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}]
}
Cross-Account Roles: For access from another AWS account
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "unique-external-id"
}
}
}]
}
Federated Roles: For SAML or OIDC authentication
AssumeRole Best Practices
- Use External ID: For cross-account access to prevent confused deputy
- Limit Session Duration: Shorter is more secure
- MFA for Sensitive Roles: Require MFA to assume privileged roles
- Condition Keys: Restrict when and how roles can be assumed
- Audit AssumeRole: Monitor who is assuming roles and when
Service Control Policies (SCPs)
SCPs define maximum permissions in AWS Organizations.
Key Concepts
- SCPs are filters, not grants
- They limit what IAM policies can allow
- Apply to all principals in account (except root in management account)
- Inherited down the OU hierarchy
Example SCPs
Prevent Leaving Organization:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Deny",
"Action": "organisations:LeaveOrganization",
"Resource": "*"
}]
}
Require MFA for Actions:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Deny",
"Action": "*",
"Resource": "*",
"Condition": {
"BoolIfExists": {
"aws:MultiFactorAuthPresent": false
}
}
}]
}
Restrict Regions (Data Sovereignty):
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Deny",
"NotAction": [
"iam:*",
"sts:*",
"cloudfront:*",
"route53:*",
"support:*"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": [
"ap-southeast-2",
"ap-southeast-4"
]
}
}
}]
}
Permission Boundaries
Permission boundaries set the maximum permissions an IAM entity can have.
Use Cases
- Delegate permission management safely
- Prevent privilege escalation
- Enforce organizational policies
- Compliance requirements
Example
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": [
"s3:*",
"dynamodb:*",
"lambda:*"
],
"Resource": "*"
}]
}
Even if a user has AdministratorAccess, the permission boundary limits them to S3, DynamoDB, and Lambda.
Monitoring and Auditing
Essential Monitoring
CloudTrail: Every API call IAM Access Analyzer: Unintended resource sharing Access Advisor: Unused permissions Credential Report: User and key status CloudWatch Alarms: Suspicious activity
Regular Audits
Monthly:
- Review IAM users (should be minimal)
- Check for unused access keys
- Review MFA status
Quarterly:
- Full access review
- Permission audit
- Role usage analysis
- Policy optimisation
Annually:
- Comprehensive security review
- Compliance assessment
- Architecture review
Common IAM Mistakes
- Using root account regularly: Lock it away
- No MFA: Always require MFA
- Overly permissive policies: Start restrictive, expand as needed
- Unused IAM users: Remove them
- Old access keys: Rotate or delete
- Inline policies everywhere: Use managed policies
- No regular reviews: Permissions accumulate over time
- Hardcoded credentials: Use roles and environment variables
Conclusion
IAM security is the foundation of AWS security. By following these best practices - implementing least privilege, protecting the root account, enforcing MFA, and regular auditing - you significantly reduce your security risk.
For Australian businesses subject to industry regulations, Privacy Act, or other regulations, proper IAM security is not just a best practice - it’s a compliance requirement.
CloudPoint can review your IAM configuration, identify security gaps, and implement best practices tailored to your business needs. Contact us for an IAM security assessment.
Concerned About Your AWS Security Posture?
CloudPoint’s security reviews assess your IAM configuration against best practices and compliance requirements. Get in touch to identify and address security gaps.