Authors: Akshay Kumar, Zach Dixon, Mo Jamal
This document is a starting point for engaging the community and standards bodies in developing collaborative solutions fit for standardization. As the solutions to problems described in this document progress along the standards-track, we will retain this document as an archive and use this section to keep the community up-to-date with the most current standards venue and content location of future work and discussions.
- This document status:
ACTIVE - Expected venue: W3C Web Authentication Working Group
- Current version: this document
- Related spec PR: w3c/webauthn#2375
- Related issue: w3c/webauthn#1577
The Web Authentication API (WebAuthn) enables strong, phishing-resistant authentication on the web using public-key cryptography. During a WebAuthn ceremony, the browser constructs a JSON object called clientDataJSON from values such as the origin, challenge, and ceremony type. This object is signed by the authenticator and later verified by the relying party.
Remote desktop web clients present a challenge for this model. When a user initiates a WebAuthn ceremony within a remote desktop session, the request originates from the remote host (e.g., https://accounts.example.com) but is executed in the context of the local web client (e.g., https://myrdc.example). The browser constructs clientDataJSON using the local client's origin rather than the remote host's origin. Meanwhile, the remote desktop host passes its own clientDataJSON (with the remote origin) to the platform authenticator API (e.g., the Windows WebAuthn API). This mismatch between the browser-constructed and host-provided clientDataJSON causes signature validation to fail.
The existing remoteDesktopClientOverride extension partially addresses this by allowing remote desktop clients to override the origin and crossOrigin fields. However, it still relies on the browser to construct clientDataJSON from component values, which may differ from the clientDataJSON that the remote host passed to the platform API. Any structural differences -- field ordering, additional fields, whitespace -- will produce a different hash and break signature verification.
The remoteClientDataJSON extension solves this by allowing an authorized remote desktop web client to provide the complete clientDataJSON string, which the browser passes through verbatim without modification.
- A user visits
https://accounts.example.comwithin a remote desktop session hosted on a remote machine. - The relying party at
https://accounts.example.cominitiates a WebAuthn ceremony. - The remote desktop host intercepts the request and forwards it to the local client via the Remote Desktop Protocol (RDP) WebAuthn virtual channel.
- The local remote desktop web client (e.g.,
https://myrdc.example) calls the WebAuthn API in the local browser. - The browser constructs its own
clientDataJSONusing the local client's context. - The authenticator signs a hash of this browser-constructed
clientDataJSON. - The response is sent back to the remote host, which attempts to verify the signature against the
clientDataJSONit originally provided to the platform API. - Verification fails because the two
clientDataJSONobjects differ.
Chromium already supports a remoteDesktopClientOverride extension that allows overriding the origin and sameOriginWithAncestors values used when constructing clientDataJSON:
navigator.credentials.get({
publicKey: {
challenge: ...,
rpId: "example.com",
allowCredentials: [...],
extensions: {
remoteDesktopClientOverride: {
origin: "https://accounts.example.com",
sameOriginWithAncestors: false,
},
},
},
});This extension corrects the origin and cross-origin flag, but the browser still constructs clientDataJSON itself. The resulting JSON may differ from what the remote host passed to the Windows WebAuthn API in field ordering, optional fields, or formatting -- any of which causes a hash mismatch and signature verification failure.
- Enable remote desktop web clients to provide a complete
clientDataJSONstring that the browser passes through to the authenticator without modification, ensuring hash consistency with the remote host. - Maintain the existing security model: per-origin authorization via enterprise policy or explicit user opt-in.
- Support both
navigator.credentials.create()(registration) andnavigator.credentials.get()(authentication) ceremonies. - Support non-managed device scenarios where enterprise policy is impractical, via browser flag configuration.
- Deprecating or removing the existing
remoteDesktopClientOverrideextension. Both extensions will coexist. - Modifying the behavior of WebAuthn for non-remote-desktop use cases.
- Implementing a general-purpose mechanism for arbitrary
clientDataJSONinjection outside of remote desktop scenarios. - Defining platform-specific authenticator behavior. The extension operates entirely at the client (browser) level.
A user connects to a remote Windows desktop via a web-based RDP client (https://myrdc.example). The remote desktop application on the host calls the Windows WebAuthn API, which accepts a complete clientDataJSON object. The RDP virtual channel forwards the WebAuthn request -- including the host's clientDataJSON -- to the web client. The web client uses remoteClientDataJSON to pass this exact JSON to the browser, ensuring the authenticator signs the same data that the remote host will use for verification.
A user accesses a corporate remote desktop from their personal laptop. Since the device is not enterprise-managed, configuring enterprise policy for WebAuthn remote desktop support is impractical. The user enables a browser flag (chrome://flags) and adds the remote desktop client's origin to the allowlist, enabling WebAuthn passkey authentication within the remote session.
A third-party remote desktop service (https://remoteapp.example) needs WebAuthn support for its web client. Using remoteClientDataJSON, the provider can forward the exact clientDataJSON from the remote host without worrying about browser-specific JSON construction differences across different Chromium-based browsers.
A new WebAuthn client extension, remoteClientDataJSON, accepts a complete clientDataJSON as a DOMString:
// The remote desktop web client at https://myrdc.example provides
// the exact clientDataJSON from the remote host.
const remoteJSON = JSON.stringify({
type: "webauthn.get",
challenge: "base64url-encoded-challenge",
origin: "https://accounts.example.com",
crossOrigin: false,
});
navigator.credentials.get({
publicKey: {
challenge: ...,
rpId: "example.com",
allowCredentials: [...],
extensions: {
remoteClientDataJSON: remoteJSON,
},
},
});The value is a JSON-serialized string containing the standard clientDataJSON fields (type, challenge, origin, crossOrigin). The browser passes this string through to the authenticator without modification.
Client Extension Input:
partial dictionary AuthenticationExtensionsClientInputs {
DOMString remoteClientDataJSON;
};
partial dictionary AuthenticationExtensionsClientInputsJSON {
DOMString remoteClientDataJSON;
};Client Extension Output:
partial dictionary AuthenticationExtensionsClientOutputs {
boolean remoteClientDataJson;
};
partial dictionary AuthenticationExtensionsClientOutputsJSON {
boolean remoteClientDataJson;
};Note: The input uses
remoteClientDataJSON(uppercaseJSON) while the output usesremoteClientDataJson(camelCaseJson), per the naming in the W3C spec PR.
When remoteClientDataJSON is present in the extension inputs:
- Permission check: Verify that the calling origin is authorized to use this extension (via enterprise policy, browser flag allowlist, or permissions policy).
- Parse the JSON: Parse the provided
remoteClientDataJSONstring. If parsing fails, throwNotSupportedError. - Extract the remote origin: Read the
"origin"field from the parsed JSON. - Validate RP ID: Verify that the requested
rpIdis a valid registrable domain suffix of the extracted remote origin. If validation fails, throwSecurityError. - Skip
clientDataJSONconstruction: The browser MUST NOT construct its ownclientDataJSON. The provided string is used as-is. - Compute the hash: Compute
SHA-256of the providedclientDataJSONstring for the authenticator. - Return verbatim: The
clientDataJSONin the response is the exact string provided by the caller, with no additions, removals, or modifications.
If both remoteClientDataJSON and remoteDesktopClientOverride are present in the same request, remoteClientDataJSON takes priority. The remoteDesktopClientOverride fields are ignored without raising an error.
The W3C spec PR defines a permissions policy feature:
- Feature identifier:
publickey-credentials-remote-client-data-json - Default allowlist:
'none'
This is designated as a powerful feature with a default permission state of "denied".
// Remote desktop web client at https://myrdc.example
const clientDataJSON = JSON.stringify({
type: "webauthn.create",
challenge: "SGVsbG8gV29ybGQ", // base64url-encoded challenge from the remote host
origin: "https://accounts.example.com",
crossOrigin: false,
});
const credential = await navigator.credentials.create({
publicKey: {
rp: { name: "Example Corp", id: "example.com" },
user: {
id: new Uint8Array([1, 2, 3, 4]),
name: "user@example.com",
displayName: "User",
},
challenge: new Uint8Array([/* challenge bytes */]),
pubKeyCredParams: [{ type: "public-key", alg: -7 }],
extensions: {
remoteClientDataJSON: clientDataJSON,
},
},
});
// credential.response.clientDataJSON contains the exact string
// provided above, enabling signature verification on the remote host.// Remote desktop web client at https://myrdc.example
const clientDataJSON = JSON.stringify({
type: "webauthn.get",
challenge: "dGVzdENoYWxsZW5nZQ",
origin: "https://accounts.example.com",
crossOrigin: false,
});
const assertion = await navigator.credentials.get({
publicKey: {
rpId: "example.com",
challenge: new Uint8Array([/* challenge bytes */]),
allowCredentials: [...],
extensions: {
remoteClientDataJSON: clientDataJSON,
},
},
});This extension requires explicit per-origin authorization. Three mechanisms are supported:
On managed devices, administrators configure the WebAuthnRemoteDesktopAllowedOrigins enterprise policy with a list of authorized origins. This is the recommended approach for enterprise deployments.
For personal or non-managed devices, users can enable WebAuthn remote desktop support via browser flags:
- Navigate to
chrome://flags#webauthn-remote-client-data-json. - Enter the authorized origin(s) (e.g.,
https://myrdc.example). - Restart the browser.
The flags page includes a standard warning about enabling experimental features and their potential security implications.
The W3C spec PR defines integration with the Permissions API and Permissions Policy. When standardized, this will provide a web-standard mechanism for sites to declare permission via HTTP headers:
Permissions-Policy: publickey-credentials-remote-client-data-json=(self "https://myrdc.example")
Adding more fields (e.g., challenge, type) to the existing remoteDesktopClientOverride extension to cover all clientDataJSON components.
Rejected because:
- Requires redundant parsing: the remote host already has the complete JSON, and decomposing it into individual fields only to have the browser reassemble them introduces unnecessary complexity and potential for divergence.
- Future additions to
clientDataJSONwould require corresponding changes to the extension interface. - Does not guarantee byte-for-byte equivalence with the remote host's JSON, since the browser may serialize fields differently.
Allow the caller to provide only the SHA-256 hash of clientDataJSON, rather than the full string.
Rejected because:
- The relying party expects the full
clientDataJSONin the authentication response for verification. Providing only a hash would require a separate channel to transmit the full JSON. - The browser would lose the ability to validate the RP ID against the origin in the JSON, weakening the security model.
The remoteClientDataJSON extension allows the calling origin to supply a clientDataJSON containing a different origin value than the local browser context. This is inherent to the remote desktop use case, but it means the browser must trust the caller to provide an accurate remote origin. This trust is mitigated by the per-origin authorization requirement.
The browser parses the provided clientDataJSON and validates the requested rpId against the origin extracted from the JSON, using the standard registrable domain suffix check. This ensures that even with a complete JSON override, the caller cannot make requests for arbitrary relying parties unrelated to the specified origin.
User agents MUST NOT grant this permission globally. The extension is only available to origins explicitly authorized via:
- Enterprise device management policy, or
- Explicit user opt-in through browser flags with a per-origin allowlist.
This ensures that arbitrary web pages cannot use this extension to forge clientDataJSON.
When both extensions are present, remoteClientDataJSON takes precedence. This is safe because remoteClientDataJSON provides a strict superset of the functionality of remoteDesktopClientOverride, and the same authorization model applies to both.
This extension does not introduce new privacy concerns beyond those already present in the remoteDesktopClientOverride extension. The clientDataJSON string provided by the caller contains only the standard fields (type, challenge, origin, crossOrigin) that the browser would normally construct itself. No additional user data is exposed.
The extension is not available by default and cannot be used for fingerprinting, as it requires explicit per-origin authorization that is not detectable by unauthorized origins.
-
Permissions API integration: The W3C spec PR (#2375) defines
remoteClientDataJSONas a powerful feature with a custom permission descriptor. Ongoing review (kreichgauer, April 2026) suggests the custom descriptor may be unnecessary. The scope of Permissions API integration depends on the resolution of this review. -
Feature identifier naming: Should the permissions policy feature use
remote-client-data-jsonorpublickey-credentials-remote-client-data-jsonto align with existing WebAuthn permission feature naming conventions? -
Related origin requests: When
remoteClientDataJSONis present and RP ID validation is performed against the extracted origin, should related origin requests also be evaluated, or should they be skipped? -
User communication: The spec recommends that user agents clearly communicate to users when a remote-desktop-proxied WebAuthn operation is in progress. The form and requirements of this communication are not yet defined.