This check flags AWS accounts where the IAM password policy lets users cycle back to old passwords. Without a password reuse restriction, a compromised credential can be quietly reinstated. Fix it by setting PasswordReusePrevention to at least 24 in the account password policy.
Password rotation only works if users cannot rotate straight back to the password they just changed. When an IAM password policy has no reuse prevention, a user forced to update their password can set it to the same one a few cycles later, or simply alternate between two favourites. That defeats the entire point of rotation and leaves stale, possibly leaked credentials valid for far longer than intended.
This Lensix check (account_passwordreuse) inspects your AWS account password policy and reports a finding when the policy does not prevent reuse of previous passwords.
What this check detects
AWS lets you define a single account-wide password policy that governs how IAM users (the ones who sign in with a username and password, not federated identities) create and update their console passwords. One of the optional settings is PasswordReusePrevention, which tells IAM how many of a user's previous passwords to remember and block.
The check returns a fail when:
- No account password policy exists at all, or
- A policy exists but
PasswordReusePreventionis unset, or - The remembered-password count is set too low for your security baseline
Note: This setting only affects IAM users with console access. If your organisation logs in through AWS IAM Identity Center (formerly SSO) or an external IdP, password rules live in that identity source instead. It is still worth setting a strong account policy for any break-glass or service IAM users that remain.
Why it matters
Password reuse prevention is one of those controls that looks like compliance box-ticking until you trace through how credentials actually get compromised.
The reuse loop defeats rotation
Say your policy forces a password change every 90 days but does not remember old passwords. A user with a habit of using Summer2024! simply changes to Spring2024! at rotation, then back again next quarter. If Summer2024! was scraped from a phishing kit or a third-party breach a year ago, it is still live. The attacker waits for the predictable cycle and walks in.
Credential stuffing has a longer runway
Breach databases like the ones behind Have I Been Pwned contain billions of email and password pairs. Attackers replay those pairs against cloud consoles. If an IAM user reused a personal password and your policy lets that password stay valid indefinitely through reuse, you have handed an attacker a stable target.
Warning: IAM users with console access and no MFA are the highest-risk version of this problem. Reuse prevention reduces the blast radius, but it is not a substitute for MFA. Treat a failing reuse check as a signal to audit MFA coverage too.
Compliance frameworks expect it
CIS AWS Foundations Benchmark, PCI DSS, and most internal security baselines call for a minimum password history. The CIS benchmark recommends preventing reuse of at least the last 24 passwords. A failing check here will surface in audits and slow down certifications.
How to fix it
You set reuse prevention as part of the account password policy. There is one policy per account, so updating it affects all IAM users at once.
Warning: The update-account-password-policy call replaces the entire policy, not just the field you pass. Always include every setting you want to keep, or you will silently reset things like minimum length back to defaults.
Option 1: AWS CLI
First, read the current policy so you know what you are working with:
aws iam get-account-password-policy
Then apply a policy that includes reuse prevention along with your other requirements:
aws iam update-account-password-policy \
--minimum-password-length 14 \
--require-symbols \
--require-numbers \
--require-uppercase-characters \
--require-lowercase-characters \
--max-password-age 90 \
--password-reuse-prevention 24 \
--allow-users-to-change-password
The key flag is --password-reuse-prevention 24, which blocks reuse of the last 24 passwords. The maximum value AWS accepts is 24.
Option 2: AWS Console
- Open the IAM console.
- In the left navigation, choose Account settings.
- Under Password policy, choose Edit (or Set password policy if none exists).
- Enable Prevent password reuse and set Number of passwords to remember to
24. - Confirm the rest of your settings, then choose Save changes.
Option 3: Terraform
If you manage IAM as code, define the policy once and let your pipeline enforce it:
resource "aws_iam_account_password_policy" "strict" {
minimum_password_length = 14
require_lowercase_characters = true
require_uppercase_characters = true
require_numbers = true
require_symbols = true
max_password_age = 90
password_reuse_prevention = 24
allow_users_to_change_password = true
}
Apply it and confirm the drift is gone:
terraform apply
aws iam get-account-password-policy --query 'PasswordPolicy.PasswordReusePrevention'
The command should return 24.
Tip: Wrap the password policy in a reusable Terraform module and apply it across every account in your organisation. Pairing this with AWS Organizations means new accounts inherit the baseline from day one rather than starting with the empty default policy.
How to prevent it from happening again
Fixing one account is easy. Keeping every account compliant as your footprint grows is the real work. A few approaches scale better than manual checks.
Detect drift with AWS Config
AWS Config ships a managed rule, iam-password-policy, that continuously evaluates your account policy against parameters you set, including reuse prevention. Deploy it as an organisation-wide conformance pack so every account is watched.
{
"RequireUppercaseCharacters": "true",
"RequireLowercaseCharacters": "true",
"RequireSymbols": "true",
"RequireNumbers": "true",
"MinimumPasswordLength": "14",
"PasswordReusePrevention": "24",
"MaxPasswordAge": "90"
}
Gate it in CI/CD
If your IAM policy lives in Terraform, add a policy-as-code check that fails the build when reuse prevention is missing or too low. Here is an Open Policy Agent (Rego) rule for a Terraform plan:
package terraform.iam
deny[msg] {
resource := input.resource_changes[_]
resource.type == "aws_iam_account_password_policy"
reuse := resource.change.after.password_reuse_prevention
reuse < 24
msg := sprintf("password_reuse_prevention must be >= 24, got %d", [reuse])
}
Run it in your pipeline before terraform apply so non-compliant changes never reach AWS.
Tip: Lensix runs this check continuously across your accounts, so you get an alert the moment a policy drifts or a new account joins without one. That covers the gap between scheduled audits when manual reviews tend to miss things.
Best practices
Reuse prevention is one piece of a healthy IAM password posture. Round it out with these:
- Remember 24 passwords. Use the maximum AWS allows. There is no downside, and it satisfies CIS.
- Set a minimum length of 14 or more. Length beats complexity. Combine it with required character classes.
- Enforce MFA on every console user. Reuse prevention slows attackers down, MFA stops them. Treat both as non-negotiable.
- Minimise IAM users entirely. Move human access to IAM Identity Center or federation so password policy applies to a tiny number of break-glass accounts rather than your whole team.
- Set a sensible max password age. 90 days is a common baseline, but pair it with reuse prevention so rotation actually means something.
- Audit regularly. Run a credential report (
aws iam generate-credential-report) to spot users with old passwords or no MFA.
Danger: Before tightening max-password-age on a live account, confirm your break-glass user has a current, securely stored password and working MFA. Locking yourself out of the one account you use to recover the others is a bad day no one forgets.
Password reuse prevention costs nothing to enable and closes a quiet but real gap in your account's defences. Set it once, enforce it in code, and let continuous monitoring keep it that way.

