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: if it’s broken or absent, the inbox tile remains visible and a user can sign in without MFA. See troubleshooting for the three “allow-all” code paths the filter takes when it’s not in a healthy state.
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 same check is exposed in the configuration tool — the Run self-test button in Diagnostics triggers it on demand without waiting for the next tick.
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.
Full discussion: Login Routing.
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), Assisted Login, and the Server-Sent Events live-update channel are not available — Mode="onprem" force-disables those Features.Use* flags at startup.
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.
Full resolution path: User setup.
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. Configuration changes take effect on the next logon — no reboot required.
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.
Related
Section titled “Related”- Login Routing — schedule and precedence rules.
- Approvers — who consents to Assisted Login flows.
- User setup — AD attributes + Local Users mapping.
- Registry reference — every value the DLL reads.
- Security FAQ — config protection, threat model, supply chain.