Most organisations still run password policies written for a threat model that NIST and the NCSC have both abandoned: short minimums, complexity rules and 90-day expiry. Those settings produce predictable passwords, help desk load and audit findings, while doing little against password spraying and credential stuffing. This guide is about the policy itself: what a modern, NIST SP 800-63B-4 aligned policy should say, how to express it in Active Directory, Microsoft Entra ID, AWS IAM and Okta, how precedence and drift work, and how to prove to an auditor that the policy is actually enforced. It is written for identity engineers, security architects and the people who own the written policy. For the wider picture on password attacks, storage and password managers, see the Password Security Guide.
Key takeaways
- Length and screening replace complexity and rotation. NIST SP 800-63B-4 requires at least 15 characters for single-factor passwords (8 when the password is one factor of MFA), forbids composition rules and forbids periodic forced change.
- A blocklist is mandatory, not optional. New and changed passwords must be checked against commonly used, expected and compromised values, and the user must be told why a password was rejected.
- The written policy and the technical policy drift apart. Default Domain Policy, fine-grained policies, cloud tenant settings and SaaS identity providers each hold their own copy; audit what is effective, not what is documented.
- Change on evidence, not on the calendar. Force a reset when there is evidence of compromise (breach corpus match, risky sign-in, leaked credential), and pair that with rate limiting and MFA.
- Password policy is attacker reconnaissance. MITRE ATT&CK T1201 Password Policy Discovery covers reading your lockout and length settings to tune spraying, so log and alert on policy reads and changes.
The settings a password policy must decide
A password policy is a small number of decisions. The table compares the two main public baselines with the values most organisations end up configuring. NIST SP 800-63B-4 uses SHALL and SHOULD language; the NCSC guidance is advice for system owners.
| Setting | NIST SP 800-63B-4 | NCSC guidance | Practical policy value |
|---|---|---|---|
| Minimum length | 15 characters if single-factor; at least 8 if used only within MFA (SHALL) | Set a minimum length; no specific number given | 15 for any account that can sign in with a password alone; 12 to 15 where MFA is always enforced |
| Maximum length | Permit at least 64 characters (SHOULD); verify the whole password, no truncation (SHALL) | Do not set a maximum | 64 or more; test that long passphrases survive every downstream system |
| Composition (mixed character types) | SHALL NOT impose | Do not use complexity requirements | Off, where the platform allows it |
| Periodic expiry | SHALL NOT require; SHALL force change on evidence of compromise | Do not enforce regular expiry | Never expire; event-driven reset |
| Blocklist | SHALL check on set and change; whole password compared; reason given to user | Use deny lists, tailored to the organisation | Common and breached passwords plus organisation terms |
| Failed attempts | SHALL rate limit; no more than 100 consecutive failures (section 3.2.2) | Prefer throttling; if locking out, allow 5 to 10 attempts | Throttling or smart lockout around 10 attempts, with monitoring |
| Hints and security questions | No hints visible to unauthenticated users; no prompts for knowledge-based questions | Not addressed directly | Disable both |
| Paste and password managers | SHALL allow password managers and autofill; SHOULD allow paste and show-password | Allow paste; promote password managers | Allow; never block paste in sign-in forms |
| Character set | SHOULD accept printing ASCII, space and Unicode; each code point counts as one character; NFC normalisation before hashing | Not addressed directly | Accept spaces; check Unicode support per platform |
NIST also sets verifier storage rules that belong in an application password standard rather than a user-facing policy: salted hashing with a password hashing scheme and a cost factor that increases over time, a salt of at least 32 bits, and optionally a secret key held separately, ideally in an HSM, TEE or TPM. The NCSC's "three random words" advice is a good user instruction to sit alongside a 15-character minimum.
Where password policy actually lives
An organisation rarely has one password policy. It has one written policy and several enforcement points, each with its own defaults, limits and precedence rules. Inventory them before changing anything.
| Platform | Where the policy is set | Default behaviour | Limits and precedence to know |
|---|---|---|---|
| Active Directory (domain) | Account Policies in the domain-level GPO, usually Default Domain Policy: Computer Configuration\Windows Settings\Security Settings\Account Policies\Password Policy | Minimum length 7 in the Default Domain Policy | The GPO setting accepts 0 to 14 characters; one domain-wide value |
| Active Directory (fine-grained) | Password Settings Objects (PSOs) in the Password Settings Container, via Active Directory Administrative Centre or PowerShell | None until created; domain functional level Windows Server 2012 or higher | Apply only to users and global security groups; a PSO overrides the domain policy for its targets; lowest precedence value wins |
| Microsoft Entra ID (cloud accounts) | Tenant and domain settings (Update-MgDomain for expiry), per-user PasswordPolicies, Password protection blade | 8 to 256 characters, three of four character classes, no expiry for tenants created since 2021 (older tenants defaulted to 90 days), smart lockout after 10 failures | Length and complexity are fixed; you control expiry, banned list and lockout; synced users follow on-premises policy unless EnforceCloudPasswordPolicyForPasswordSyncedUsers is set |
| AWS IAM | Account password policy (UpdateAccountPasswordPolicy) | 8 to 128 characters, three of four character types, never expires | Minimum 6 to 128; expiry 1 to 1,095 days; reuse prevention 1 to 24; applies to IAM user console passwords only, not the root user or access keys; no lockout setting |
| Okta | Password policies assigned to groups, with rules | Default policy; new developer orgs use a 12-character minimum and history of 24 | Minimum 4 to 30; common password check; breached password protection; for AD and LDAP sourced users the directory enforces many settings |
| Applications with local accounts | Application configuration or code | Varies widely | Usually the weakest point; bring under SSO or apply an application password standard |
Two points cause most confusion. First, AWS applies minimum length and character changes only when users next change their password, but an expiry period takes effect immediately and expires every password older than it. Second, AWS states that an IAM user whose console password expires can still use their access keys, which is why password policy says nothing about the security of long-lived keys. See the AWS IAM Policies and Roles Guide.
Active Directory: domain policy, fine-grained policies and precedence
Active Directory is where most password policy debt lives, because the domain policy is old, widely depended on and capped by the GPO interface.
- The 14-character ceiling: Microsoft documents the Minimum password length GPO setting as 0 to 14 characters and states that values above 14 are not supported in that setting. To require 15 or more for a group of users, use fine-grained password policies.
- Fine-grained password policies: PSOs hold their own length, complexity, history, age and lockout values (attributes such as msDS-MinimumPasswordLength, msDS-PasswordComplexityEnabled, msDS-MaximumPasswordAge and msDS-LockoutThreshold). Create them with New-ADFineGrainedPasswordPolicy and attach them with Add-ADFineGrainedPasswordPolicySubject.
- Precedence: a PSO linked directly to a user beats one that applies through a group; among group-applied PSOs the lowest msDS-PasswordSettingsPrecedence value wins; ties break on the lowest object GUID. Users with no PSO fall back to the domain policy.
- Effective policy: read the computed msDS-ResultantPSO attribute or run Get-ADUserResultantPasswordPolicy for a user. Auditors should be shown this, not the PSO list.
- Only global security groups: a PSO linked to a universal or domain local group, or to an organisational unit, does nothing. This is a frequent silent failure.
- Privileged accounts: a dedicated PSO for Tier 0 and admin groups is the usual first PSO. See the Active Directory and Entra ID Hardening Guide.
Screening: blocklists and breached password checks
Screening is the control that makes a no-complexity policy safe. NIST requires the check on every set and change, compares the whole password, and says the list should be large enough to block passwords attackers would try before reaching the attempt limit.
- Microsoft Entra Password Protection: combines a global banned list (built from Entra telemetry, not configurable) with a custom list of up to 1,000 organisation terms. It normalises case and common substitutions (0 to o, 1 to l, $ to s, @ to a), fuzzy matches at edit distance 1, checks the user's names and tenant name, and accepts a password only if it scores at least 5 points.
- On-premises AD: the same policy reaches domain controllers through a proxy service and a DC agent with a password filter DLL. Domain controllers never contact the internet, the policy is cached in SYSVOL and refreshed hourly, and a domain controller with no policy fails open. Install the agent on every domain controller: clients can change passwords on any of them.
- Audit before enforce: Microsoft recommends starting in Audit mode, where weak passwords are logged but accepted, before switching to Enforced.
- Breached corpus checks: the Have I Been Pwned Pwned Passwords range API uses k-anonymity: the client sends only the first five characters of the SHA-1 hash and compares the returned suffixes locally. It supports an NTLM mode and an Add-Padding header that hides response size. Use it, or an offline copy, in custom applications.
- Okta: enable the common password check and choose a breached password protection action (expire after a set number of days, log the user out, or run a workflow).
- Existing passwords: screening at change time does nothing for passwords already set. The NCSC suggests searching stored hashes against the deny list retroactively; treat matches as evidence of compromise and force a reset.
Custom list content that works: company and product names, office locations, sports teams near your offices, internal project names and seasonal words. Do not add short fragments that will reject large numbers of strong passphrases.
Rotation, lockout and throttling
Removing expiry is the change that most often stalls in governance, so the policy must state what replaces it.
- Event-driven change: force a reset on a breached corpus match, a high user risk detection, a confirmed phishing click, a leaked credential report or offboarding of anyone who knew a shared password.
- Entra ID expiry: check with Get-MgDomain and set the validity period with Update-MgDomain. Microsoft warns that reverting a user's PasswordPolicies from DisablePasswordExpiration to None forces a change at next sign-in for any password older than 90 days, so plan that change.
- Lockout thresholds: NIST sets 100 consecutive failures as an upper bound; NCSC suggests 5 to 10 if you lock out at all. Low thresholds turn spraying into denial of service; high thresholds without throttling help the attacker.
- Layered lockout: where an identity provider fronts AD, set its threshold below the directory's. Okta gives the example of 9 in Okta against 10 in AD, so the cloud layer locks before the domain account does. Entra smart lockout ignores repeats of the same bad password.
- History: keep history only to stop an immediate return to the old password after a forced reset. Long history settings exist to support rotation and add little once rotation is gone.
Spraying and stuffing defence goes beyond policy settings. See the Password Spraying and Credential Stuffing Defence Guide.
Choosing values: decision guidance
| Situation | Recommended approach | Trade-off |
|---|---|---|
| Password is the only factor (legacy apps, some VPNs, kiosks) | 15-character minimum, screening, throttling; plan to add MFA or SSO | Longest passwords where users feel it most; justify with the NIST single-factor rule |
| MFA enforced on every sign-in path | 12 to 15 characters, screening, no expiry | Weaker if any path bypasses MFA (legacy protocols, local logon), so verify coverage first |
| Privileged and Tier 0 accounts | Separate PSO or policy, phishing-resistant MFA, vaulted or passwordless where possible | NCSC notes extra complexity rules on admin accounts add burden without clear benefit; MFA is the primary control |
| Regulated sector still requiring rotation | Comply, but document the risk acceptance and the compensating controls; raise it at the next framework review | Audit friction versus control quality |
| Small organisation on one cloud identity provider | Use the provider's banned list and smart lockout; switch off expiry; one written page of policy | Limited configurability (Entra cloud length and complexity are fixed) |
| Large hybrid estate | Central standard, per-platform configuration baseline, quarterly effective-policy report | More enforcement points to keep aligned |
Where identity fits: service accounts and machine passwords
User password policy is often applied by accident to service accounts, which then break when expiry or lockout triggers, or are exempted wholesale with "password never expires" and a short shared value. Write a separate standard for non-human accounts.
- Prefer no password: group managed service accounts, workload identity federation and managed identities remove the human-set password entirely. See the Service Account Security Guide.
- Where a password remains: generate it randomly at full platform length, store it in a vault, rotate it on a schedule and on staff change, and deny interactive logon. Scheduled rotation is right here because no human memorises the value.
- Local administrator accounts: manage them with LAPS rather than a shared image password. See the LAPS Guide.
- Defaults: change every vendor default password before deployment, as the NCSC advises. MITRE D3FEND lists this as Change Default Password (D3-CDP).
Rolling out a NIST-aligned policy
- Inventory enforcement points: export the effective policy from the AD domain, every PSO, each Entra tenant, every AWS account, the SaaS identity provider and applications with local accounts.
- Get the written policy approved first: state minimum length, screening, event-driven change, lockout, the non-human account standard and how exceptions are granted and reviewed.
- Turn on screening in audit mode: deploy Entra Password Protection agents to all domain controllers in Audit, review the event log for a few weeks, then switch to Enforced.
- Pilot length and no-complexity: create a PSO for a pilot group with a 15-character minimum and complexity disabled. Test downstream systems that receive passwords (RADIUS, mainframe bridges, VPN appliances, legacy apps) for truncation or character problems.
- Stop expiry: set expiry to never for the pilot, then expand by ring. Communicate that change happens on evidence of compromise.
- Raise length at next change: new length rules apply as users next change; combine with a forced reset only for accounts that match the breached list.
- Roll back cleanly: removing a pilot group from the PSO returns users to the domain policy; setting password protection to No puts DC agents in a quiescent mode where they accept all passwords. Record the previous AWS policy JSON (get-account-password-policy) before changing it.
- Baseline and monitor: store the approved settings as a configuration baseline and compare effective settings against it on a schedule.
Detection, auditability and drift
Treat password policy as configuration that can be changed by an attacker or a well-meaning administrator, and as information an attacker will read.
| Signal | Source | Why it matters |
|---|---|---|
| Password policy reads | AWS CloudTrail GetAccountPasswordPolicy; command lines such as net accounts /domain or Get-ADDefaultDomainPasswordPolicy | ATT&CK T1201 Password Policy Discovery: attackers read lockout and length to tune spraying |
| Policy changes | CloudTrail UpdateAccountPasswordPolicy and DeleteAccountPasswordPolicy; GPO and PSO changes in AD; Entra audit logs | Weakening policy is a form of T1484 Domain or Tenant Policy Modification |
| Weak password set attempts | Microsoft\AzureADPasswordProtection\DCAgent\Admin log: 10014 and 10015 pass, 10016 and 10017 fail, 10024 and 10025 audit-only would-fail | Shows screening is running on every domain controller and how often it bites |
| Accounts exempt from policy | AD accounts with password never expires or password not required flags; Entra users with DisablePasswordExpiration | Exemptions are where weak and shared passwords collect |
| Spraying patterns | Sign-in logs: one password across many accounts, failures spread under the lockout threshold | Tests whether lockout and throttling settings are right |
For point-in-time evidence, keep a dated export of each platform's effective policy (Get-ADDefaultDomainPasswordPolicy, Get-ADUserResultantPasswordPolicy for sample users, Get-MgDomain, aws iam get-account-password-policy) with the approved baseline. Get-AzureADPasswordProtectionSummaryReport summarises DC agent outcomes.
Metrics that show it is working:
- Percentage of enforcement points whose effective settings match the approved baseline.
- Percentage of domain controllers running the DC agent with a current policy.
- Number of active accounts whose password matches a breached corpus, trending to zero.
- Number of policy exemptions, each with an owner and review date.
- Password reset tickets per 1,000 users per month, before and after removing expiry.
- Sign-in paths where a password alone is sufficient, trending to zero.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| NIST SP 800-63B-4 | Sections 3.1.1.1 and 3.1.1.2 (passwords), 3.2.2 (rate limiting) | Source of length, screening, no-rotation and verifier rules |
| NIST SP 800-53 Rev. 5 | IA-5 Authenticator Management; IA-5(1) Password-based Authentication; AC-7 Unsuccessful Logon Attempts; CM-2 Baseline Configuration | Control statements auditors test the policy against |
| NIST CSF 2.0 | PR.AA-01 identities and credentials managed; PR.AA-03 users, services and hardware authenticated | Outcome-level placement |
| CIS Controls v8.1 | Control 5 Account Management, Safeguard 5.2 Use Unique Passwords | Check the safeguard's own length values against your policy |
| ISO/IEC 27001:2022 Annex A | 5.17 Authentication information | Allocation and management of passwords |
| MITRE ATT&CK v20 | T1201; T1110.001 Password Guessing; T1110.002 Password Cracking; T1110.003 Password Spraying; T1110.004 Credential Stuffing; T1078 Valid Accounts | Attacks the policy is designed to resist |
| MITRE D3FEND | D3-SPP Strong Password Policy; D3-CDP Change Default Password | Defensive technique names for mapping |
Common failure patterns
- Complexity without screening: "Summer2024!" passes every complexity rule and is one of the first guesses in a spray. Only a blocklist stops it.
- Default and trivial passwords on side systems: the McHire Default Password Flaw 2025 shows an administrative login with "123456" on an application outside the main identity estate. Policy must cover local application accounts and defaults, not only the directory.
- Reuse across services: the 23andMe Breach 2023 was credential stuffing with passwords reused from other breaches. Breached password screening and MFA address this; length and complexity rules do not.
- PSO linked to the wrong object: a PSO linked to an OU or a universal group applies to nobody, and the stricter admin policy exists only on paper.
- Partial DC agent deployment: password protection installed on some domain controllers means changes that land on others are not screened, and a domain controller without a policy fails open.
- Expiry left on in one tenant or account: an older Entra tenant still on 90 days, or an AWS account policy copied from a 2015 template, contradicts the written policy and reappears as an audit finding.
Practitioner checklist
- Export the effective password policy from every directory, tenant, cloud account and identity provider, and compare it with the written policy.
- Set a 15-character minimum for any account where a password alone grants access; use PSOs where AD's 14-character GPO limit applies.
- Disable composition rules and periodic expiry, and document event-driven reset triggers.
- Enable banned and breached password screening on every enforcement point, starting in audit mode, with a custom list of organisation terms.
- Deploy the Entra Password Protection DC agent to all domain controllers and alert on missing or stale policy.
- Set lockout or throttling within the NIST and NCSC ranges, with the identity provider threshold below the directory's.
- Allow paste and password managers in every sign-in form you control.
- Write a separate standard for service accounts, local admin accounts and default credentials.
- Log and alert on password policy reads and changes, including CloudTrail GetAccountPasswordPolicy and UpdateAccountPasswordPolicy.
- Keep dated effective-policy exports as audit evidence and review exemptions quarterly.
Standards and references
- NIST: SP 800-63B-4 Digital Identity Guidelines, Authentication and Authenticator Management
- NCSC: Password policy, updating your approach
- NIST: SP 800-53 Rev. 5
- Microsoft Learn: Eliminate bad passwords using Microsoft Entra Password Protection
- Microsoft Learn: Monitor on-premises Microsoft Entra Password Protection
- Microsoft Learn: Configure fine-grained password policies for AD DS
- AWS: Set an account password policy for IAM users
- MITRE ATT&CK: Password Policy Discovery
Related NHI Mgmt Group resources: Password Security Guide · Password Spraying and Credential Stuffing Defence Guide · Passwordless and Passkeys Guide · Authorisation Models Guide