Rotate IAM Access Keys Every 90 Days
Overview
This check identifies IAM users with active access keys that have not been rotated in over 90 days. Access keys are long-term credentials used by applications, scripts, or CLI tools to authenticate with AWS. Regularly rotating these keys limits how long a compromised key remains valid.
Risk
If an access key is leaked (for example, through code repositories, logs, or accidental sharing), an attacker can use it to access your AWS account. The longer a key exists without rotation, the longer a leaked key remains exploitable. Unrotated keys increase the window of opportunity for:
- Unauthorized access to AWS resources
- Data theft or modification
- Unexpected AWS charges from malicious usage
- Compliance violations in regulated environments
Remediation Steps
Prerequisites
- Access to the AWS Console with permissions to manage IAM users, or AWS CLI configured with appropriate credentials
- Know which IAM user has the old access key (Prowler provides this in its findings)
AWS Console Method
- Sign in to the AWS IAM Console
- In the left navigation, click Users
- Click on the username that has the old access key
- Select the Security credentials tab
- Scroll down to the Access keys section
- Note the Age column to confirm which key needs rotation
- Click Create access key to generate a new key pair
- Important: Copy or download the new secret access key immediately (you cannot retrieve it later)
- Update your applications, scripts, or CLI configuration to use the new key
- Once the new key is working, return to the console and click Actions next to the old key
- Select Deactivate first to disable the old key
- After confirming nothing breaks, click Actions > Delete to permanently remove the old key
AWS CLI Method
Step 1: List existing access keys for the user
aws iam list-access-keys \
--user-name <USER_NAME> \
--region us-east-1
This shows you the Access Key IDs and their creation dates.
Step 2: Create a new access key
aws iam create-access-key \
--user-name <USER_NAME> \
--region us-east-1
Important: Save the SecretAccessKey from the output immediately. It cannot be retrieved again.
Step 3: Update your applications
Configure your applications, scripts, or AWS CLI profiles to use the new access key credentials.
Step 4: Deactivate the old access key
Once everything is working with the new key:
aws iam update-access-key \
--user-name <USER_NAME> \
--access-key-id <OLD_ACCESS_KEY_ID> \
--status Inactive \
--region us-east-1
Step 5: Delete the old access key
After confirming nothing depends on the old key:
aws iam delete-access-key \
--user-name <USER_NAME> \
--access-key-id <OLD_ACCESS_KEY_ID> \
--region us-east-1
CloudFormation
CloudFormation does not directly manage access key rotation. However, you can use AWS Secrets Manager with automatic rotation for credentials.
For programmatic access, consider using IAM roles instead of access keys. Here is an example of an IAM role that an EC2 instance can assume:
AWSTemplateFormatVersion: '2010-09-09'
Description: IAM role for EC2 instances - avoids long-term access keys
Resources:
ApplicationRole:
Type: AWS::IAM::Role
Properties:
RoleName: ApplicationRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: ec2.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess # Example policy
Tags:
- Key: Purpose
Value: ApplicationAccess
ApplicationInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
InstanceProfileName: ApplicationInstanceProfile
Roles:
- !Ref ApplicationRole
Outputs:
RoleArn:
Description: ARN of the IAM role
Value: !GetAtt ApplicationRole.Arn
InstanceProfileArn:
Description: ARN of the instance profile
Value: !GetAtt ApplicationInstanceProfile.Arn
This approach eliminates the need for long-term access keys on EC2 instances.
Terraform
Like CloudFormation, Terraform does not manage access key rotation directly. The recommended approach is to use IAM roles with temporary credentials.
Here is an example of an IAM role for an EC2 instance:
# IAM role that EC2 instances can assume
resource "aws_iam_role" "application_role" {
name = "ApplicationRole"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com"
}
Action = "sts:AssumeRole"
}
]
})
tags = {
Purpose = "ApplicationAccess"
}
}
# Attach a managed policy (example: S3 read-only)
resource "aws_iam_role_policy_attachment" "s3_read" {
role = aws_iam_role.application_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
}
# Instance profile for EC2
resource "aws_iam_instance_profile" "application_profile" {
name = "ApplicationInstanceProfile"
role = aws_iam_role.application_role.name
}
output "role_arn" {
description = "ARN of the IAM role"
value = aws_iam_role.application_role.arn
}
output "instance_profile_arn" {
description = "ARN of the instance profile"
value = aws_iam_instance_profile.application_profile.arn
}
For workloads outside AWS (CI/CD pipelines, on-premises servers), consider using IAM Roles Anywhere or OIDC federation instead of long-term access keys.
Verification
After completing the rotation:
- In the AWS Console, go to IAM > Users > select the user > Security credentials
- Confirm the old access key no longer appears (or shows as Inactive if not yet deleted)
- Verify the new key's Age shows it was recently created
- Test your applications to ensure they work with the new credentials
CLI Verification
# List access keys to verify rotation
aws iam list-access-keys \
--user-name <USER_NAME> \
--region us-east-1
# Generate a credential report to check all users
aws iam generate-credential-report --region us-east-1
# Download and review the credential report
aws iam get-credential-report \
--query 'Content' \
--output text \
--region us-east-1 | base64 --decode
The credential report includes access_key_1_last_rotated and access_key_2_last_rotated columns showing when each key was created or last rotated.
Additional Resources
- Managing Access Keys (IAM User Guide)
- IAM Credential Reports
- Security Best Practices in IAM
- IAM Roles Anywhere - For workloads outside AWS
Notes
- Prefer IAM roles over access keys: Where possible, use IAM roles with temporary credentials instead of long-term access keys. This applies to EC2 instances, Lambda functions, ECS tasks, and other AWS services.
- One key at a time: During rotation, you may temporarily have two active keys. Delete the old key as soon as the new one is confirmed working.
- Automate monitoring: Use AWS Config rules or set up CloudWatch alarms to detect access keys approaching the 90-day threshold.
- Service disruption risk: Deactivating or deleting an access key that is still in use will break applications. Always update applications to use the new key before removing the old one.
- Root account keys: If this check flags the root account, strongly consider deleting root access keys entirely. AWS best practices recommend not using root account access keys.