What Is AD Password Policy Compliance?
AD password policy compliance depends on the exact rule being evaluated. A domain can satisfy the numeric criteria quoted for EtcSec's ANSSI password-policy check and still fail its CIS check on the same configuration. The checks read overlapping attributes, but apply different thresholds and cover different settings.
The useful question is therefore: which attribute failed, against which documented baseline, and under which detector version? A result labelled ANSSI or CIS should lead to that evidence. It cannot, by itself, establish compliance with an entire publication.
This comparison separates the two detector predicates documented in a September 2026 collector review from the underlying recommendations. The document comparison uses CIS Microsoft Windows Server 2012 R2 Benchmark v2.2.0, dated April 28, 2016, sections 1.1 and 1.2. This is a historical edition. The current CIS catalogue lists Server 2022 v5.1.0, which was not read for this article.
Our practical ANSSI Active Directory guide explains why an AD security programme needs a defined set of complementary documents, rather than a compliance claim built around one PDF.
How the ANSSI and CIS Checks Differ
The following table distinguishes source recommendations from the conditions quoted for Detect(). Values describe the configuration that satisfies the quoted numeric conditions, rather than the failure expressions themselves.
The collector review quotes ad/compliance/anssi/r1-password-policy.go and ad/compliance/cis/password-policy.go. The full Go files were unavailable for this comparison. Consequently, the table supports conclusions about those excerpts; it does not establish unquoted branches, error handling, or coverage of missing collection data.
| Setting | ANSSI document guidance | ANSSI detector excerpt | Historical CIS 2012 R2 v2.2.0 | CIS detector excerpt |
|---|---|---|---|---|
minPwdLength | PG-078 R21: length depends on the required security level | At least 12 characters | Section 1.1.4: at least 14 characters | At least 14 characters |
pwdHistoryLength | The cited PG-078 recommendations do not establish the detector's 12-password threshold | At least 12 passwords | Section 1.1.1: at least 24 passwords | At least 24 passwords |
lockoutThreshold | PG-078 R10: limit authentication attempts over time; the detector's fixed range is separate | 1–10 failed attempts | Section 1.2.2: 1–10 failed attempts | 1–5 failed attempts |
maxPwdAge | PG-078 R24/R25 distinguish ordinary and privileged accounts | No age test in the quoted predicate | Section 1.1.2: nonzero, no more than 60 days | Nonzero, no more than 365 days |
minPwdAge | No corresponding numeric threshold attributed here | No test in the quoted predicate | Section 1.1.3: at least 1 day | At least 1 day |
Complexity, represented in pwdProperties | PG-078 R23: implement complexity rules | Not documented in the excerpt | Section 1.1.5: enabled | Not documented in the excerpt |
Sources for the document columns are ANSSI-PG-078 and the historical CIS Server 2012 R2 v2.2.0 PDF. The detector columns come from the quoted predicates reproduced below. They are implementation thresholds, not an attribution of every number to ANSSI. The 60/365-day and 10/5-attempt differences also show why an edition must accompany a document-level claim.
Complexity is a separate question
Microsoft defines pwdProperties as a domain-policy bitfield for complexity and storage restrictions. Its DOMAIN_PASSWORD_COMPLEX flag has value 1. Inspecting length, history and age cannot establish the state of that flag.
A complete assessment must therefore record complexity explicitly. The excerpts supplied for these two checks do not show a complexity condition. That is a limit of the available implementation evidence, not proof that the complete detectors ignore it. Do not turn an undocumented field into an assumed pass.
Cases Where the Results Diverge
These examples are hypothetical configurations evaluated against the quoted numeric predicates. They are not results from a customer environment or a live collector run. For these examples, assume durations are expressed in days, no expiration is represented as maxPwdAge == 0, and the other fields contain valid values. These assumptions match the quoted comparisons; the collector's conversion of directory values has not been verified.
| Example | Minimum length | History | Lockout threshold | Maximum age | Minimum age | ANSSI excerpt | CIS excerpt |
|---|---|---|---|---|---|---|---|
| Length below the CIS floor | 12 | 24 | 5 | 365 days | 1 day | Satisfied | Fails length |
| History below the CIS floor | 14 | 12 | 5 | 365 days | 1 day | Satisfied | Fails history |
| More permitted failed attempts | 14 | 24 | 10 | 365 days | 1 day | Satisfied | Fails lockout threshold |
| Non-expiring default policy | 14 | 24 | 5 | No expiration | 1 day | Satisfied | Fails maximum age |
| Immediate password changes | 14 | 24 | 5 | 365 days | 0 days | Satisfied | Fails minimum age |
| Common numeric baseline | 14 | 24 | 5 | 365 days | 1 day | Satisfied | Satisfied |
Each row isolates a reason for disagreement. A real policy may fail several conditions together, so retain all failing attributes instead of reporting only the first one encountered. That makes the remediation plan specific: a history failure needs a history change, while an age failure needs an explicit decision about expiration.
Can the reverse happen?
For these quoted predicates on the same valid inputs, satisfying the CIS numeric conditions implies satisfying the ANSSI numeric conditions. A minimum length of 14 also meets 12; a history of 24 meets 12; a lockout threshold between 1 and 5 also lies between 1 and 10. The CIS-only age conditions add requirements without relaxing those shared ones.
There is therefore no demonstrated CIS-pass/ANSSI-fail example for this pair of excerpts. If an audit reports that combination, compare the collected values, detector version and full finding details before explaining it as a difference between standards. Different inputs, implementations or audit scopes require their own evidence.
Nor does the final row establish complete benchmark compliance. It says only that these five numeric inputs satisfy the quoted expressions. Complexity remains a separate verification, and a complete benchmark contains additional controls.
Detection: Read the Default Domain Password Policy
Use the Active Directory PowerShell module to collect the default domain policy. Replace the example domain with the domain under review:
Get-ADDefaultDomainPasswordPolicy -Identity 'example.com' |
Select-Object DistinguishedName, MinPasswordLength, PasswordHistoryCount,
LockoutThreshold, MaxPasswordAge, MinPasswordAge, ComplexityEnabled
This is one read-only pipeline based on Microsoft's Get-ADDefaultDomainPasswordPolicy documentation. It has not been executed against a live domain for this article.
Read the output as evidence for a specific domain and collection time. Preserve the distinguished name together with the values, so a later review can determine whether the two audit results actually describe the same policy. Do not compare a remembered GPO setting with a fresh collector result and assume they have identical inputs.
MinPasswordLength is a character count. PasswordHistoryCount corresponds to the number of retained passwords; Microsoft's pwdHistoryLength schema page documents the directory attribute. The age properties are durations, whereas length, history and lockout threshold are counts. Keep those units explicit when transferring evidence into an audit worksheet.
The command returns the default domain policy. It does not establish the effective policy of every user when fine-grained password policies apply. Microsoft documents a separate resultant password-policy query for users; do not extend a domain-default result into an account-by-account compliance claim.
Remediation: Fix the Failed Attribute Against a Named Baseline
First decide which baseline and edition governs the change. Document the required outcome, then change the attributes that fail it. A setting that removes one finding can leave another finding intact, as the example table shows.
For an example that satisfies both quoted numeric predicates and the historical table's numeric criteria, use length 14, history 24, lockout threshold 5, maximum age 60 days and minimum age 1 day. The 60-day value comes from historical CIS section 1.1.2; the stricter 5-attempt choice comes from the CIS detector excerpt. Enable complexity for the cited document's separate complexity criterion. This is a comparison example, not a recommendation to adopt a historical benchmark today.
The following configuration example uses parameters documented by Microsoft for Set-ADDefaultDomainPasswordPolicy:
Set-ADDefaultDomainPasswordPolicy -Identity 'example.com' `
-MinPasswordLength 14 -PasswordHistoryCount 24 -LockoutThreshold 5 `
-MaxPasswordAge '60.00:00:00' -MinPasswordAge '1.00:00:00' `
-ComplexityEnabled $true -WhatIf
-WhatIf previews the proposed operation without applying it. This example was checked against the documentation; it was not executed in a live domain. An administrator should test the intended change, then apply it through the organisation's managed policy process and repeat the read-only query above. A preview is not a successful remediation result.
Resolve expiration deliberately
ANSSI-PG-078 R24 advises against default expiration for nonsensitive accounts when robust passwords and supporting systems permit it; R25 retains expiration for privileged accounts. The preceding text favours two-factor authentication for those accounts and discusses expiration when password-only authentication is used. That account distinction cannot be established by a single domain-wide age value. An absence of an ANSSI detector age finding does not validate the whole expiration policy.
If your chosen baseline requires a nonzero maximum age, retain that requirement or document the exception through your audit process. Clearing a dashboard finding and defending an exception are different outcomes; record which one you achieved.
Verify the change and the remaining exposure
Retain the before-and-after policy output, the baseline edition and the reason for each changed attribute. Re-run both checks against the same fresh collection and review any remaining findings individually. If the configuration changed but the finding did not, reconcile the collection time and reported values before making another policy change.
Password-policy compliance also needs an operational context. Our password-spraying article explains how a few guesses spread across many accounts can avoid obvious per-account lockouts, and why mitigation combines password controls, stronger authentication and correlated monitoring. Passing a lockout threshold check should not be used as evidence that spraying has been eliminated.
How EtcSec Detects This
The site's catalogue contains both ANSSI_R1_PASSWORD_POLICY and CIS_PASSWORD_POLICY. The collector review supplies the following failure conditions for their respective Detect() implementations:
ANSSI_R1_PASSWORD_POLICY
ad/compliance/anssi/r1-password-policy.go
minPwdLength < 12 OR pwdHistoryLength < 12
OR lockoutThreshold == 0 OR lockoutThreshold > 10
CIS_PASSWORD_POLICY
ad/compliance/cis/password-policy.go
minPwdLength < 14 OR pwdHistoryLength < 24
OR maxPwdAge > 365 OR maxPwdAge == 0
OR minPwdAge < 1 OR lockoutThreshold > 5 OR lockoutThreshold == 0
The age thresholds above are expressed in days for this comparison, consistent with the review's maxAge=120j example (line 127). The excerpts do not establish how the collector converts raw LDAP intervals or represents non-expiring policies. They explain why the same policy can produce different findings and why each finding should name its failing attribute.
The implementation evidence is the collector review at docs/research/ad/2026-09-13-ad-catalogue-gap-diff.md, lines 123 and 124 respectively. These lines quote the named Go files; Go source line numbers were not available. The full source files were unavailable in this review. Complexity coverage, missing-data behavior and any other unquoted branches remain unverified. These findings are useful configuration signals; their names do not turn a partial predicate into a complete ANSSI or CIS assessment.
Primary References
- ANSSI: Recommandations de sécurité relatives à Active Directory, DAT-NT-17 v1.1, September 10, 2014; R1, printed page 8.
- ANSSI: Authentication and password recommendations, ANSSI-PG-078 v2.0, October 8, 2021; R10 and R21–R25.
- CIS: Microsoft Windows Server benchmark catalogue and edition selection. Historical comparison: Server 2012 R2 v2.2.0, April 28, 2016; sections 1.1.1–1.1.5 and 1.2.2, PDF linked above. Server 2022 v5.1.0 was not read.
Explore the identity security pages that support this topic

