Blue Team of One field notes · security

HomeIdentity SecurityAuthentication & MFA

Authentication · password hygiene

The password nobody can set: Entra Password Protection, end to end

Complex-looking passwords built from your company name and city sail through most policies — Contoso2025!Widget passes a length-and-complexity check but is trivially guessable. Entra Password Protection stops it on-prem, at the domain controller, even when it's obfuscated to C0nt0s0!W1dget. Here's the architecture, and the scoring algorithm that makes the decision.

Traditional password complexity rules measure the wrong thing. "At least one uppercase, one number, one symbol" says nothing about whether the password is guessable — and the most guessable passwords in any organisation are the ones built from its own vocabulary: the company name, the city, the product line, the season and year. Entra Password Protection extends Microsoft's cloud-side banned-password enforcement down to your on-prem Active Directory, so those get rejected at the domain controller the moment a user tries to set one.

01The architecture — proxy + DC agent

Two components, and the on-prem DC never has to call the cloud at validation time.

The on-prem deployment has two roles. Deploy the proxy on at least two servers for redundancy; install the DC agent on every domain controller that will enforce.

ComponentRole
Proxy service (≥2 servers)Domain-joined middlemen between the DCs and Entra ID. They download the latest policy (global + custom banned lists) from Entra and advertise availability by creating a serviceConnectionPoint (SCP) in AD.
DC agent (every DC)Filters password-change events via a DLL, locates a proxy through the SCP to fetch policy, caches it in SYSVOL (so it replicates to other DCs), and validates password changes locally.
# the flow — note the validation step never leaves the DC
DC agent  →  finds a proxy (via SCP)  →  proxy pulls policy from Entra ID
          →  policy cached in SYSVOL  →  passwords evaluated LOCALLY on the DC

The DC agent checks the policy file for updates and, after startup, refreshes it hourly if the cached copy is older than an hour. The important consequence: password validation happens entirely on the DC against the locally cached policy — when a user changes a password, there's no round-trip to the cloud, so there's no latency and no dependency on internet reachability at the moment of the change.

02Two banned lists — global and custom

Microsoft's threat intelligence, plus your own vocabulary.

ListWhat's on it
Global banned listCurated by Microsoft from real-world threat telemetry — the passwords and patterns actually seen in attacks. You don't manage it; it updates automatically.
Custom banned listYour terms — company name, locations, product names, notable brands. This is where you block the organisation-specific words that make a password guessable to anyone who knows the business.

The worked example

Say the company is Contoso, based in London, building a product called Widget. A user tries Contoso2025!Widget — passes complexity, but it's guessable to anyone who's seen a business card. Add contoso, london, and widget to the custom list, and it's blocked — and so is the obfuscated C0nt0s0!W1dget, because the engine normalizes leetspeak and does fuzzy matching before it scores.

03The scoring algorithm the core

Accept/reject isn't a blocklist lookup — it's a points score.

This is the part almost nobody knows, and it explains why some "close" passwords pass and others fail. Entra Password Protection doesn't just check "does this contain a banned word." It normalizes the password (lowercases, maps common character substitutions like 0→o, 1→i/l, $→s), fuzzy-matches banned terms, then assigns a score:

# the scoring rules
- each banned term found         = 1 point
- each remaining (non-banned) char = 1 point
- a password must score >= 5 points to be ACCEPTED

The intuition: banned terms are worth almost nothing (1 point no matter how long the word), so a password padded with your company name has very little "real" entropy left to reach 5. Two worked examples:

PasswordNormalizedScoringResult
C0ntos0Blank12contosoblank12contoso (1) + blank (1) + 1 (1) + 2 (1) = 4❌ Rejected (< 5)
C0ntos0R4ining88!contosor4ining88!contoso (1) + r,4,i,n,i,n,g,8,8,! (10) = 11✅ Accepted (≥ 5)

In the first, two banned terms (contoso, blank) collapse most of the string to 2 points, leaving only two digits — total 4, rejected. In the second, only contoso is banned; the remaining ten characters each earn a point, easily clearing the threshold. The lesson for users: padding a banned word with a couple of numbers isn't enough — the banned word barely counts, so you need genuine additional length that isn't part of a banned term.

04Deployment notes

Roll it out in audit mode first, then enforce.

# sensible rollout order
1. Install proxy on 2+ domain-joined servers; register the forest
2. Install the DC agent on ONE DC first; validate in AUDIT mode
   (audit logs what WOULD be rejected without blocking anyone)
3. Confirm rejections behave as expected, then switch to ENFORCE
4. Roll the DC agent to remaining DCs, rebooting each out of hours
5. Verify replication + agent health after each reboot

Audit mode is not optional

Go straight to enforce and you risk blocking legitimate password changes (and generating help-desk tickets) before you understand what your custom list actually catches. Audit mode logs every would-be rejection without blocking, so you can tune the custom list against real user behaviour first. Every DC needs the agent to enforce consistently — a DC without it silently accepts weak passwords.

05Monitoring — Event ID 30027

Watch rejections across every DC to prove the policy is working.

Once enforcing, the DC agent logs password-validation outcomes to the Windows event log. Centralise Event ID 30027 (a rejected password due to the banned-list policy) across all DCs — forward it to your SIEM — so you can see the policy actually firing, spot which terms are catching the most attempts, and confirm coverage is uniform across the estate. A DC that never logs a rejection when others do is a sign its agent isn't healthy.

The takeaway

Entra Password Protection pushes Microsoft's global banned list plus your own vocabulary down to the DC, where passwords are scored locally with no cloud round-trip. The scoring model — banned terms worth 1 point, real characters worth 1 point, 5 to pass — is why padding your company name with two digits still fails. Deploy proxy + DC agent, tune in audit mode, enforce everywhere, and watch Event ID 30027 to prove it's working.

Further reading

Anonymized from real deployment work; server, domain, and organisation identifiers have been replaced with generic examples.

Comments

Questions or corrections welcome. Sign in with GitHub to join the thread.