You typed "keycloak device trust" or "keycloak device posture" into a search box. The hits you get are issue #8742, a pull request about skipping MFA, and threads that mix X.509, WebAuthn and "remember this computer" as if they were the same product. They are not.
This write-up is for an engineer who already runs Keycloak and wants a straight map: what the IdP can prove about a machine today, what it cannot prove, and where an agent has to sit. There is a product at the end. There is no pitch in the middle.
What Keycloak can say about a device today
Three mechanisms show up in every thread. Each one answers a real question. None of them answers "is this workstation a machine the company knows, in a state the company accepts".
1. The trusted-device cookie
Keycloak has no native device-posture check. The closest in-tree work is pull request #48138, a TrustedDeviceAuthenticator that sets a cookie.
On the user's consent the authenticator writes a cookie; on later logins that cookie is enough to skip the second factor. There is no hardware attestation, no posture signal, no agent, and no device registry. The PR was still open when we last read the sources (August 2026). It closes issue #8742.
The issue text is unambiguous. The user story is: "As a user I want to only input two factor authenticator every 30 days." That is fewer MFA prompts, not device trust.
A cookie that says "this browser was here before" is not a device identity. Anyone who can steal the cookie — malware, a shared family laptop, a session that outlived the person — inherits the skip. The IdP has no way to ask the machine "are you still the same computer, still encrypted, still not a clone of yesterday's VM".
If you needed a 30-day MFA exemption, the cookie is the right tool. If you needed "unknown laptop, known password, deny", it is the wrong category.
2. X.509 and mTLS
Keycloak can require a client certificate. That is a real control. It is also a different product from posture.
X.509 / mTLS proves that the client presented a certificate the IdP is willing to trust. It does not prove disk encryption, OS version, screen lock, or that the machine is the one in a company registry. To issue and revoke those certificates you need a CA, usually SCEP or an equivalent, and a process that puts the cert on the box. Without that infrastructure the control is dead. With it, you still only know "this is that cert".
Self-service enrollment is the part that usually breaks. A contractor on a personal Mac does not want your CA on the login keychain. A helpdesk that mails P12 files is the process you were trying to retire.
3. WebAuthn
WebAuthn proves possession of an authenticator bound to an origin. A passkey, a security key, a platform authenticator. That is a strong answer to phishing of the person. It is not an answer about the workstation.
The authenticator can sit on a YubiKey in a bag, on a phone, or in the laptop's TPM. Keycloak sees a valid assertion. It does not see whether the laptop that opened the browser is the corporate Mac, a cloned VM, or a cafe machine the user borrowed for five minutes. W3C spent years trying to thread device information through WebAuthn (devicePubKey, then supplementalPubKeys) and dropped both from the Candidate Recommendation snapshot of 26 May 2026. The platform itself refused to smuggle posture into the passkey.
Passkeys make device trust more necessary, not less. Once phishing of the credential is gone, the residual risk is the device and the live session.
What "posture" actually means
Posture is a statement about the machine at the moment of the decision: identity of the box, a handful of security properties, freshness. Typical questions:
- Is this serial / hardware identity in our registry, in a state we accept (enrolled, not revoked)?
- Is the disk encrypted? Is the OS past the floor we set? Is the screen lock on?
- Was this statement signed recently, by a key that belongs to this machine, not replayed from last Tuesday?
An IdP can consume a verdict. It cannot collect those facts from inside a browser tab. The browser is a renderer. It does not have a privileged view of the disk, the firmware, or the TPM, and it is not supposed to.
A browser extension outside ChromeOS cannot obtain a single hardware-attested fact about the device. That is not a missing permission in manifest.json. On Windows, macOS and Linux the enterprise.* APIs that actually return device data (deviceAttributes, platformKeys, networkingAttributes) are ChromeOS only. The one desktop API, enterprise.hardwarePlatform, returns {manufacturer, model}.
Chrome can report real posture — disk encryption, secure boot, antivirus, patch level — through chrome.enterprise.reportingPrivate. That API is compiled behind a hardcoded allowlist of seven Google extensions. Force-install does not open it. An architecture "posture as an extension, no agent" is physically impossible off ChromeOS.
That is why the agent exists. Not because native messaging is fashionable. Because it is the only channel that can see the machine.
What the agent actually sends
The TrustFlare agent installs without MDM and without administrator rights. It collects a short inventory (model, serial, OS, language, timezone) and signs it with a key that lives on that machine. The core checks the signature, the registry, freshness, and policy, then answers allow or deny.
No MDM, no admin rights: the agent is meant for the laptop you do not own — contractor, BYOD, a designer who will never join the domain.
Passwords, Keycloak sessions and IdP secrets do not go to TrustFlare cloud. What leaves is the username at sign-in, IP, user-agent, and the signed inventory. A trial core lives 14 days; data is deleted after 30. If the data must not leave the building, that is the Ultimate column, not the default.
We do not claim the agent is an EDR. It does not read files, mail, or keystrokes. It does not give your security team a shell on a personal laptop. Visibility for the sign-in decision, not guts of a private life.
How the authenticator step looks
The user types a password in Keycloak the way they always did. After the password (Required), the flow has a step named TrustFlare Device Trust.
The step talks to the core with a one-shot handle. The agent has already posted the signed payload. Allow — the flow continues, the session is issued as usual. Deny — login stops, and a full event lands in your SIEM: who, from where, which device, why. Nothing in the applications themselves changes. No SDK in the SPA, no reverse proxy in front of every admin.
The first time a new laptop shows up, it sits in the registry until a person who already has a trusted device — typically the owner's phone — approves it. That is the Duo-style loop: the circuit breaker is in a pocket, not in a ticket.
A second laptop without the agent, same password, same TOTP, is a deny. That is the whole product, demonstrated on the live stand.
The boundary: we do not protect the session after login
TrustFlare decides at authentication time. Once Keycloak has issued the session, we do not sit in the request path, we do not revoke the cookie when the laptop's disk encryption falls off an hour later, and we do not terminate an SSH session that was opened this morning.
That is not a missing checkbox. It is the shape of an IdP authenticator. The authenticator runs when the user logs in. After that, the session is Keycloak's, the VPN's, the application's.
Things this does not mean:
- We are not an EDR. An EDR watches the process tree. We do not.
- We are not a replacement for step-up on a sensitive action inside an app. If you need "re-check the device before this transfer", that is a different hook, and we do not pretend we have it.
- We are not Google DBSC. DBSC binds a cookie to a device to fight infostealers, Chrome on Windows only, and the spec says it does not guarantee device state. Different layer.
If a stolen session token is your main threat, you need token binding, short lifetimes, and whatever your apps already do. Device trust at login is complementary: it stops the next login from an unknown box with a valid password. It does not rewind the login that already happened.
We would rather write that sentence here than have an engineer discover it on a Friday incident.
Where to go next
If the map matches the problem you have — Keycloak, mixed fleet, no appetite for rip-and-replace — the shortest path is the quickstart: a trial core, a JAR in providers/, three environment variables, trustflare-doctor, an agent on one machine. Thirty minutes if Keycloak is already up.
The price ladder is on /pricing/. Free up to 100 users. A pilot is paid — four weeks on your own stand, not a sales call with a slide.
If you only needed to skip MFA for 30 days, use the cookie. That problem is already named, and it is not this one.