This check flags AWS accounts where the IAM password policy is missing or too weak to resist credential attacks. Tighten the policy with minimum length, complexity, rotation, and reuse rules, then enforce it as code so it never drifts back.
IAM users with console access authenticate with passwords, and the strength of those passwords is governed by a single account-wide setting: the IAM password policy. If that policy is absent or set to permissive defaults, you are trusting every human in the account to pick a strong password on their own. That trust rarely pays off.
The account_passwordpolicy check inspects your account's IAM password policy and fails when it does not meet a sensible baseline for length, character requirements, rotation, and reuse prevention.
What this check detects
Lensix calls the IAM GetAccountPasswordPolicy API and evaluates the returned settings against a minimum security baseline. The check fails in two scenarios:
- No policy exists at all. When you have never configured one, the API returns a
NoSuchEntityerror and AWS falls back to its minimal built-in rules, which only require a length of 8 and no other constraints. - A policy exists but is too weak. Common gaps include short minimum length, no requirement for symbols or numbers, no maximum password age, and no password reuse prevention.
Note: The IAM password policy applies only to IAM users signing in to the AWS Management Console. It does not affect the root user, IAM Identity Center (SSO) users, or programmatic access keys. If you have already moved console access to Identity Center, this policy still matters for any break-glass or legacy IAM users that remain.
Why it matters
Weak passwords are one of the oldest and most reliable ways into a cloud account. The risk is not theoretical:
- Credential stuffing. Attackers replay username and password pairs leaked from unrelated breaches. If your engineer reused a password and you allow no rotation, that credential stays valid indefinitely.
- Brute force and guessing. An 8-character password with no complexity requirement falls well within the reach of automated guessing, especially against an account without MFA on every user.
- Slow lateral movement. Once an attacker has any console foothold, they enumerate permissions and look for paths to escalate. A stale, never-rotated password gives them a stable beachhead for weeks.
This control also shows up directly in compliance frameworks. CIS AWS Foundations Benchmark has dedicated recommendations for password length and reuse, and auditors will ask for evidence. A failing policy is an easy finding to write up and an easy one to remediate, which is exactly why it should never linger.
Warning: A password policy is a useful layer, but it is not a substitute for MFA. The single most effective control against credential attacks is enforcing multi-factor authentication on every IAM user and the root account. Treat the password policy as defense in depth, not the whole defense.
How to fix it
You can set the policy from the console, the CLI, or infrastructure as code. Start by checking what you have today.
1. Inspect the current policy
aws iam get-account-password-policy
If the command returns NoSuchEntity, no policy exists and AWS is using its weak defaults. Otherwise you will see the current values to compare against your baseline.
2. Set a strong policy via the CLI
The following sets a baseline that satisfies common benchmarks: 14-character minimum, all character classes required, 90-day rotation, and a 24-password reuse history.
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
Warning: Setting --max-password-age will force users to change their password at the next login once their current password exceeds the age you set. Communicate the change before applying it, or you will generate a wave of confused support requests on Monday morning.
One option worth a deliberate decision is --hard-expiry. By default an expired password can still be changed by the user at sign-in. With --hard-expiry set, expired users are locked out and an administrator must reset the password.
Danger: Do not enable --hard-expiry unless you have a tested admin reset process and ideally an alternative access path. Combined with a short max age, it can lock every user out of the console at once, including the people who would normally fix it.
3. Console steps
- Open the IAM console.
- In the left navigation, choose Account settings.
- Under Password policy, choose Edit.
- Set the minimum length, enable all character requirements, set the rotation period, and set the reuse prevention count.
- Choose Save changes.
4. Codify it with Terraform
Clicking through the console fixes the symptom once. Defining the policy as code fixes it for good and makes drift visible in your plans.
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
}
Tip: Because the password policy is a single account-level resource, put it in the same module that manages your account baseline alongside CloudTrail, the account alias, and default EBS encryption. That keeps the foundational security settings in one reviewable place.
How to prevent it from coming back
A one-time fix drifts the moment someone edits the policy by hand or spins up a new account. Build guardrails that catch regressions automatically.
- Manage it in IaC and run a plan in CI. If the password policy lives in Terraform, a scheduled
terraform planin your pipeline will surface any manual change as drift before it goes unnoticed for months. - Add a policy-as-code gate. Tools like Checkov, tfsec, or OPA can reject pull requests that weaken or remove the policy. Below is a simple Open Policy Agent rule against a Terraform plan.
package iam.password_policy
deny[msg] {
resource := input.resource.aws_iam_account_password_policy[name]
resource.minimum_password_length < 14
msg := sprintf("password policy '%s' allows minimum length below 14", [name])
}
- Use an AWS Config rule for continuous detection. The managed rule
iam-password-policyevaluates the live account setting and flags non-compliance even when no code change triggered it. - Enforce across the organization. If you run AWS Organizations, deploy the policy through a baseline (for example via Control Tower or a StackSet) so every new account inherits it on day one instead of starting from the weak defaults.
Tip: Pair the Config rule with an automatic remediation action that calls update-account-password-policy. The account self-heals within minutes of any drift, and you get an audit trail of when and why it changed.
Best practices
- Favor length over churn. Modern guidance, including NIST 800-63B, leans toward longer passwords and away from aggressive forced rotation. Many compliance baselines still require a max age, so balance the two: a 14-character minimum does more real work than a 30-day rotation on a short password.
- Make MFA non-negotiable. Enforce MFA for every IAM user and the root account. A strong password policy plus MFA closes most of the credential attack surface.
- Reduce the number of IAM users. Move human console access to IAM Identity Center with your existing identity provider. Fewer long-lived IAM users means fewer passwords to govern.
- Protect the root user separately. The root user is not covered by the IAM password policy. Give it a long unique passphrase, hardware MFA, and lock it away for break-glass use only.
- Document your baseline. Record the chosen values and the reasoning so the next engineer does not loosen them without understanding the tradeoff.
The password policy is a small setting with an outsized return. It takes one command to set, costs nothing, and removes an easy finding from every audit. Set it strong, codify it, and gate it so it stays that way.

