🏢Active DirectoryPasswordCompliance

AD Password Policy Compliance: Why ANSSI and CIS Checks Differ

Compare ANSSI and CIS password-policy checks attribute by attribute, verify the AD domain policy, and remediate against a clearly identified baseline.

Younes AZABARBy Younes AZABAR10 min read
AD Password Policy Compliance: Why ANSSI and CIS Checks Differ

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.

SettingANSSI document guidanceANSSI detector excerptHistorical CIS 2012 R2 v2.2.0CIS detector excerpt
minPwdLengthPG-078 R21: length depends on the required security levelAt least 12 charactersSection 1.1.4: at least 14 charactersAt least 14 characters
pwdHistoryLengthThe cited PG-078 recommendations do not establish the detector's 12-password thresholdAt least 12 passwordsSection 1.1.1: at least 24 passwordsAt least 24 passwords
lockoutThresholdPG-078 R10: limit authentication attempts over time; the detector's fixed range is separate1–10 failed attemptsSection 1.2.2: 1–10 failed attempts1–5 failed attempts
maxPwdAgePG-078 R24/R25 distinguish ordinary and privileged accountsNo age test in the quoted predicateSection 1.1.2: nonzero, no more than 60 daysNonzero, no more than 365 days
minPwdAgeNo corresponding numeric threshold attributed hereNo test in the quoted predicateSection 1.1.3: at least 1 dayAt least 1 day
Complexity, represented in pwdPropertiesPG-078 R23: implement complexity rulesNot documented in the excerptSection 1.1.5: enabledNot 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.

ExampleMinimum lengthHistoryLockout thresholdMaximum ageMinimum ageANSSI excerptCIS excerpt
Length below the CIS floor12245365 days1 daySatisfiedFails length
History below the CIS floor14125365 days1 daySatisfiedFails history
More permitted failed attempts142410365 days1 daySatisfiedFails lockout threshold
Non-expiring default policy14245No expiration1 daySatisfiedFails maximum age
Immediate password changes14245365 days0 daysSatisfiedFails minimum age
Common numeric baseline14245365 days1 daySatisfiedSatisfied

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

Explore the identity security pages that support this topic