Architecture and authentication flows
The Mideye Credential Provider is two cooperating COM objects loaded by Windows Logon: a credential provider that draws the Mideye tile and runs the MFA flow, and a credential provider filter that hides the inbox tile while Mideye is active. This page covers where they sit, how they talk to the Mideye backend, and the timing model.
Where the credential provider runs in Windows Logon
Section titled “Where the credential provider runs in Windows Logon”LogonUI.exe is a LocalSystem process. Both Mideye DLLs run inside it, they have SYSTEM privileges and read the registry root unconditionally regardless of the user attempting to log on.
The filter is the lockout-prone surface, and it is deliberately built to fail open. Before hiding anything, it checks that the Mideye provider could actually render its own tile, and takes an “allow-all” path if not. There are five such paths: the provider DLL missing from disk, the filter DLL missing, the registry root missing, Enabled absent or 0, and the mode’s credentials incomplete (ClientId + ClientSecret in cloud mode, MideyeUrl + ApiToken on-prem).
That trade is what stops a half-finished deployment from producing a logon screen with no tiles at all. The cost is that a broken install silently stops enforcing MFA rather than announcing itself, so verify with MideyeProviderConfig.exe --preflight instead of inferring enforcement from the absence of complaints.
What the installer puts on disk
Section titled “What the installer puts on disk”| File | Path |
|---|---|
| Credential provider DLL | C:\Windows\System32\MideyeCredentialProvider.dll |
| Credential filter DLL | C:\Windows\System32\MideyeCredentialFilter.dll |
| Configuration tool | C:\Program Files\Mideye\MideyeProviderConfig.exe |
| Logs | C:\ProgramData\Mideye\credential-provider.log |
| Filter health task | Scheduled task MideyeFilterHealthCheck (5-minute cadence) |
Both DLLs link the static C runtime so they have no Visual C++ redistributable dependency on the target host.
Filter health watchdog
Section titled “Filter health watchdog”A scheduled task named MideyeFilterHealthCheck runs every five minutes and at every logon. It guards against two kinds of silent failure that would otherwise let a user bypass MFA without anyone noticing.
-
The credential-filter COM registration is gone. If a Windows Update edge case, third-party security software, or an operator action removes the filter’s COM registration, the Mideye tile still appears, but the standard Windows password tile becomes selectable alongside it, and a user can sign in by clicking the password tile and skipping MFA entirely. The watchdog re-checks the registration on every tick and writes event 5301 if it’s broken; event 5302 fires when it recovers.
-
The DLLs on disk are not the ones the MSI shipped. A SHA-256 hash and the Authenticode publisher thumbprint of both
MideyeCredentialProvider.dllandMideyeCredentialFilter.dllare captured as a baseline at install time and re-verified on every tick. A mismatch writes event 5304. The baseline auto-refreshes on a legitimate MSI upgrade (event 5305), so an operator doesn’t have to clear anything after a normal version bump.
The current state is summarised at the foot of the configuration tool’s navigation rail, and can be run on demand with MideyeProviderConfig.exe --silent --filter-healthcheck (exit 0 healthy, 4 any FAIL).
The MFA decision ladder
Section titled “The MFA decision ladder”Every logon attempt runs through a fixed 11-step precedence ladder in CCredential::ResolveMfaDecision. The order exists so that a misconfigured deploy cannot lock anyone out, Break-Glass beats every other rule, including the schedule’s Deny cells.
| Step | Test | Outcome |
|---|---|---|
| 1 | User in Accounts\BreakGlass | BreakGlass: skip MFA, accept username + password. Beats everything below. |
| 1b | Accounts\Assisted\OverrideDeny=1 && useAssistedLogin && user in Accounts\Assisted | NeedAssisted (or NeedTicket if the ticket gate isn’t satisfied), listed Assisted users override Deny cells. |
| 1c | Accounts\MfaOverride\OverrideDeny=1 && user in TouchOnly or TokenOnly | NeedTouch / NeedToken: force-factor users override Deny. Strict: if the forced factor isn’t available, Deny. |
| 2 | Schedule cell = D | Deny. EVENT_LOGIN_DENIED (1001) written with reason schedule deny in the message body. |
| 3 | Schedule cell = A && useAssistedLogin | NeedAssisted (or NeedTicket). |
| 4 | useAssistedLogin && user in Accounts\Assisted | NeedAssisted (or NeedTicket). Per-user roster always promotes MFA cells to Assisted. |
| 5 | User in TouchOnly | NeedTouch if useTouch && hasPhone, else Deny. Strict, no fallback. |
| 6 | User in TokenOnly | NeedToken if `useToken && (onprem |
| 7 | Mode=onprem | NeedToken if useToken, else Deny. (On-prem resolves the serial server-side; hasToken is irrelevant.) |
| 8 | useTouch && hasPhone && useToken && hasToken | NeedSelect: user picks. |
| 9 | useTouch && hasPhone | NeedTouch. |
| 10 | useToken && hasToken | NeedToken. |
| 11 | otherwise | Deny. |
The simplified 5-step version that appears in some developer asides is a pedagogical shortcut, the table above is the actual code.
The Login Schedule tab paints the cell values that steps 2 and 3 read.
Cloud-mode flow
Section titled “Cloud-mode flow”Cloud mode talks to the Mideye Authentication API over OAuth2 client credentials. Below is a Touch push from a domain user logging on to a member server.
Each leg of the auth-api call is bounded at 120 seconds. Assisted Login adds a second leg (the approver’s phone) for a 240-second wall-clock cap end-to-end.
On-prem-mode flow
Section titled “On-prem-mode flow”On-prem mode talks directly to the customer-hosted mideye-server over a static Bearer token. Hardware-token OTP is the only flow:
On-prem mode has no internet egress. Touch push (useTouch) and Assisted Login are not available, Mode="onprem" force-disables those Features.Use* flags at startup.
Cloud with on-prem failover
Section titled “Cloud with on-prem failover”A cloud deployment can nominate a local Mideye Server as a fallback for the case where the cloud is unreachable. It is off by default (Failover\UseOnPremToken, added in v0.9.0) and changes only what happens on the failure path:
The failover only helps users who already have a hardware token or TOTP seed registered on that server, so it has to be provisioned before the outage to be worth anything. Without it, an unreachable cloud refuses the logon and writes event 5810 (API_UNREACHABLE_DENY); Break-Glass accounts never reach that branch, because they bypass the API entirely.
What the credential provider reads from Active Directory
Section titled “What the credential provider reads from Active Directory”For domain-joined hosts, the credential provider reads two attributes per user via LDAP using the host’s machine account:
| Default | Configurable as | Holds |
|---|---|---|
mobile | PhoneAttribute | E.164 phone number for Touch (push or SMS) push |
ipPhone | TokenAttribute | Hardware-token serial for OTP |
A smart classifier routes the value based on its prefix, + is a phone, AI / ubbc / zmub / oath are token serials, so phones and tokens can share an attribute if the AD schema doesn’t allow both.
For workgroup or standalone hosts where AD lookup is unavailable, the credential provider falls back to the Local Users registry mapping (UserPhoneMap\<sam> and UserTokenMap\<sam>) populated through the configuration GUI.
Both mappings are edited on the Local User Phone/Token tab of the configuration tool.
What leaves the host
Section titled “What leaves the host”| Mode | Destination | Direction | Port |
|---|---|---|---|
| Cloud | Mideye Authentication API | Outbound HTTPS | 443 |
| Cloud | OAuth token endpoint | Outbound HTTPS | 443 |
| On-prem | mideye-server LAN host | Outbound HTTPS | 8443 (configurable) |
| Both | Domain controller | Outbound LDAP | 389 / 636 |
No telemetry. No analytics. No cloud sync of configuration. Cloud mode sends only the auth-flow payload (phone number, display strings, machine name), itemised in GDPR.
Configuration model
Section titled “Configuration model”All configuration lives in the registry under HKLM\SOFTWARE\Mideye\CredentialProvider. Two write paths:
MideyeProviderConfig.exe --apply-config <path.json>: JSON-driven, validated, atomic. Recommended for fleet deployments and scripted rollouts.MideyeProviderConfig.exeGUI, interactive Save All. Recommended for single-host setup and for ad-hoc edits.
The credential provider DLL re-reads the registry on every logon attempt: LogonUI constructs a fresh provider each time, so configuration changes take effect on the next logon with no reboot and no service to restart. That property is what makes recovery a single registry write.
The registry root is locked to SYSTEM + Administrators only by a deferred CustomAction (HardenRegistry) at MSI install time. The opt-out is POLICY_REGISTRY_STRICT_ACLS=0 on the msiexec command line; not recommended for production.
ClientSecret (cloud) and ApiToken (on-prem) are stored as plain REG_SZ values protected by that ACL, not by an application-layer cipher. This matches the Mideye PAM module’s convention on Linux: an administrator on the box can read them, an ordinary user cannot, and encryption at rest belongs at the volume layer. Earlier versions used DPAPI blobs and were reverted, because DPAPI added nothing against the on-box threat model while causing lockouts on cloned, sysprepped and P2V’d images whose master key had changed.
Interface language
Section titled “Interface language”The logon tile resolves its language once per provider load: the Language registry value first, then the system UI language, then English. An unrecognised value logs once and falls back rather than rendering a blank tile. English, Ukrainian and Russian ship today.
Logs and Event Log entries stay English regardless. The UI string and the log string are resolved separately at the same call site, so a localised deployment does not produce a log file that support and SIEM rules cannot read.
Related
Section titled “Related”- Quickstart, the 10-minute path to MFA on RDP.
- Recovery, the one command that undoes a lockout and four ways to deliver it.

