webauthnRegister.js: sync with upstream - #7
Conversation
I found two issues while running recent Keycloak with WebAuthn: - registerByWebAuthn() ignored PublicKeyCredential.authenticatorAttachment, so the registration request didn't include it. - Only legacy requireResidentKey was handled in authenticatorSelection, so the new setting residentKey was ignored. This commit brings webauthnRegister.js in sync with current upstream Keycloak's version and so fixes both issues.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughWebAuthn registration now supports the ChangesWebAuthn registration
Estimated code review effort: 2 (Simple) | ~10 minutes Mergeability Score: ⚪ Minimal · up to This localized change adds the missing WebAuthn registration settings for authenticator attachment and resident keys; no actionable merge-blocking risk remains after normal checks and review. Possibly related issues
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@keycloak-theme/public/login/js/webauthnRegister.js`:
- Around line 34-46: Add residentKey to the WebauthnRegister context contract
and the registration input object consumed by webauthnRegister.js. In the
fallback branch around input.requireResidentKey, normalize an absent value to
"not specified" before evaluating it, so fallback is skipped unless the
deprecated option is explicitly provided.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 66c83bbe-97e9-45e3-86e2-39e149372929
📒 Files selected for processing (1)
keycloak-theme/public/login/js/webauthnRegister.js
| if (input.residentKey && input.residentKey !== 'not specified') { | ||
| // residentKey is the current spec field and the source of truth. requireResidentKey is | ||
| // deprecated but still set for older clients: it is true iff residentKey is 'required'. | ||
| authenticatorSelection.residentKey = input.residentKey; | ||
| authenticatorSelection.requireResidentKey = input.residentKey === 'required'; | ||
| isAuthenticatorSelectionSpecified = true; | ||
| } else if (input.requireResidentKey !== 'not specified') { | ||
| // fall back to the deprecated option when residentKey is not specified | ||
| if (input.requireResidentKey === 'Yes') { | ||
| authenticatorSelection.residentKey = 'required'; | ||
| authenticatorSelection.requireResidentKey = true; | ||
| } else { | ||
| authenticatorSelection.residentKey = 'discouraged'; |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- caller ---'
cat -n keycloak-theme/login/pages/webauthn-register/useScript.tsx | sed -n '1,90p'
printf '%s\n' '--- webauthnRegister.js relevant sections ---'
cat -n keycloak-theme/public/login/js/webauthnRegister.js | sed -n '1,75p'
cat -n keycloak-theme/public/login/js/webauthnRegister.js | sed -n '120,155p'
printf '%s\n' '--- references ---'
rg -n -C 3 'registerByWebAuthn|residentKey|requireResidentKey' keycloak-theme/login keycloak-theme/public/login/jsRepository: keycloakify/login-ui
Length of output: 14311
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- resident-key definitions and context fields ---'
rg -n -C 4 'residentKey|requireResidentKey|webauthn-register\.ftl|WebAuthnRegister' . \
-g '!node_modules' -g '!dist' -g '!build'
printf '%s\n' '--- candidate context/type files ---'
git ls-files | rg '(^|/)(KcContext|kcContext|webauthn|WebAuthn|login).*'
printf '%s\n' '--- exact branch probe ---'
node - <<'JS'
function selection(input) {
const authenticatorSelection = {};
let specified = false;
if (input.residentKey && input.residentKey !== "not specified") {
authenticatorSelection.residentKey = input.residentKey;
authenticatorSelection.requireResidentKey = input.residentKey === "required";
specified = true;
} else if (input.requireResidentKey !== "not specified") {
if (input.requireResidentKey === "Yes") {
authenticatorSelection.residentKey = "required";
authenticatorSelection.requireResidentKey = true;
} else {
authenticatorSelection.residentKey = "discouraged";
authenticatorSelection.requireResidentKey = false;
}
specified = true;
}
return specified ? authenticatorSelection : undefined;
}
for (const input of [
{},
{ requireResidentKey: undefined },
{ requireResidentKey: "not specified" },
{ requireResidentKey: "No" },
{ requireResidentKey: "Yes" },
{ residentKey: "required", requireResidentKey: "No" }
]) {
console.log(JSON.stringify(input), "=>", JSON.stringify(selection(input)));
}
JSRepository: keycloakify/login-ui
Length of output: 21931
🏁 Script executed:
#!/bin/bash
set -eu
printf '%s\n' '--- WebauthnRegister context type ---'
cat -n src/core/KcContext/KcContext.ts | sed -n '405,435p'
printf '%s\n' '--- WebauthnRegister mocks ---'
cat -n src/core/KcContext/kcContextMocks.ts | sed -n '515,540p'
cat -n src/core/KcContext/getKcContextMock.ts | sed -n '1,80p'
printf '%s\n' '--- upstream/default-theme generator ---'
cat -n scripts/shared/downloadKeycloakDefaultTheme.overridable.ts | sed -n '380,445p'
rg -n -C 5 'requireResidentKey|residentKey' scripts src keycloak-themeRepository: keycloakify/login-ui
Length of output: 15363
🌐 Web query:
Keycloak webauthn-register.ftl requireResidentKey residentKey values "not specified" "Yes"
💡 Result:
In Keycloak, the requireResidentKey property historically used in webauthn-register.ftl is a legacy boolean field that has been superseded by the residentKey property in the WebAuthn specification [1][2]. Keycloak has historically encountered issues where the "Require discoverable credential" policy setting was not correctly propagated to the frontend, sometimes resulting in requireResidentKey being incorrectly passed as a string value (e.g., "Yes") rather than a boolean or the appropriate residentKey string value (such as "required" or "preferred") [1][3]. Keycloak has been actively transitioning to using residentKey to align with modern WebAuthn standards [3]. Recent updates and issue resolutions (such as Issue #42513) have focused on replacing the deprecated requireResidentKey with the residentKey property in registration requests to improve compatibility with passkeys and modern authenticators [3]. For current implementations, relying on the legacy requireResidentKey boolean is discouraged, as it cannot express the "preferred" option and may be ignored or handled inconsistently by modern platforms [2]. Developers should refer to the latest Keycloak documentation and release notes—particularly for versions 26.4 and newer—regarding improved passkey and WebAuthn configuration support [4].
Citations:
- 1: Require discoverable credential is not correctly propagated to JavaScript keycloak/keycloak#37168
- 2: https://www.passkeywebauthn.com/webauthn-fido2-protocol-fundamentals/public-key-vs-symmetric-credential-types/when-to-use-resident-vs-discoverable-credentials/
- 3: Set residentKey instead of requireResidentKey in Webauthn creation request keycloak/keycloak#42513
- 4: https://www.keycloak.org/2025/09/passkeys-support-26-4
🌐 Web query:
site:github.com/keycloak/keycloak webauthnRegister.js requireResidentKey residentKey
💡 Result:
In the context of the WebAuthn API and implementations like Keycloak's webauthnRegister.js, requireResidentKey is a deprecated property, whereas residentKey (often referred to in documentation as "Discoverable Credential" requirement) is the modern, preferred property [1][2][3][4]. The WebAuthn specification and current implementations have transitioned to using residentKey within the authenticatorSelection criteria of PublicKeyCredentialCreationOptions [2][5]. Key Characteristics: - Deprecation: requireResidentKey is deprecated and is being phased out in favor of residentKey [1][2][3]. - Nomenclature: The industry has moved toward the term "Discoverable Credential" to describe what was previously known as a "Resident Key" [2][4]. - Implementation Status: In systems like Keycloak, recent updates have introduced residentKey as a policy option to replace the deprecated requireResidentKey [1][6]. The older property was frequently misused or incorrectly propagated (often as a string instead of a boolean), leading to registration issues where the authenticator would not correctly generate a discoverable credential [5]. - Configuration: When configuring WebAuthn policies or registration requests, you should prioritize the residentKey parameter, which typically accepts values such as 'required', 'preferred', or 'discouraged' [2]. If you are maintaining or updating code like webauthnRegister.js, you should check for the availability of residentKey in your configuration objects and transition away from relying on requireResidentKey to ensure compatibility with modern browsers and authenticators [1][6].
Citations:
- 1: Set residentKey instead of requireResidentKey in Webauthn creation request keycloak/keycloak#42513
- 2: https://github.com/keycloak/keycloak/blob/main/docs/documentation/server_admin/topics/authentication/webauthn.adoc
- 3: Use the official "Discoverable Credential" terminology for the new WebAuthn policy option keycloak/keycloak#50015
- 4: Rename "Resident key" to "Discoverable Credential" keycloak/keycloak#9508
- 5: Require discoverable credential is not correctly propagated to JavaScript keycloak/keycloak#37168
- 6: keycloak/keycloak@31cf0d5
Pass residentKey through the WebAuthn registration context.
useScript.tsx supplies only requireResidentKey, and KcContext.WebauthnRegister does not declare residentKey. Add the field to the context contract and input object. Treat an absent requireResidentKey as "not specified" before applying the fallback; otherwise it produces residentKey: "discouraged".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@keycloak-theme/public/login/js/webauthnRegister.js` around lines 34 - 46, Add
residentKey to the WebauthnRegister context contract and the registration input
object consumed by webauthnRegister.js. In the fallback branch around
input.requireResidentKey, normalize an absent value to "not specified" before
evaluating it, so fallback is skipped unless the deprecated option is explicitly
provided.
I found two issues while running recent Keycloak with WebAuthn:
This commit brings webauthnRegister.js in sync with current upstream Keycloak's version and so fixes both issues.
Summary by CodeRabbit
New Features
Bug Fixes