Skip to content

(Draft proposal): Janssen Passkey Enhancement Spec

Mostafejur Rahman edited this page Mar 27, 2026 · 2 revisions

Janssen Passkey Enhancement Spec

1. Executive Summary

The current agama-passkey project provides a functional WebAuthn/FIDO2 enrollment and authentication flow, but it is scoped narrowly: one login flow, one enrollment flow, one device management screen. To drive real passkey adoption — the boss's stated goal of breaking 10% and beyond — Janssen needs to expand in three directions:

  1. More Agama Projects covering the full adoption lifecycle (not just "add a passkey")
  2. AdminUI observability so operators can see how the rollout is going
  3. Documentation reframed around "passkey adoption" rather than FIDO technical jargon

2. Current State Analysis

What exists today

Component What it does Gap
org.gluu.agama.passkey.main Password login → passkey list/mgmt No passkey-first / passwordless path
org.gluu.agama.passkey.add Enroll a new passkey No "passkey append" nudge post-login
org.gluu.agama.passkey.list View/rename passkeys, auth with passkey No delete, no last-used info, no device type
org.gluu.agama.passkey.nickname Name a newly enrolled passkey Nickname is required — blocks flow if skipped
FidoValidator WebAuthn assertion (login) No Conditional UI / autofill support
FidoEnroller WebAuthn attestation (register) platformAuthn flag commented out; no resident key policy config
ScimFido2Helper SCIM Fido2Devices CRUD Filters out deviceData — loses authenticator type info
AdminUI (none specific to passkeys) No adoption metrics, no per-user passkey status

Key code issues noted

  • passkey-add.ftlh has a debug alert() left in the registration success path
  • FidoValidator.assertionRequest() has dead code (builds a JSON string then overwrites it)
  • ScimFido2Helper.getFidoDeviceByUser() silently drops entries that have deviceData — this excludes platform authenticators on some platforms
  • Nickname is mandatory with no skip/default — friction at enrollment completion
  • No Conditional UI (autocomplete="username webauthn") on the login form — misses the "one-tap" experience

3. Proposed Enhancements

3.1 New Agama Projects (Workflows)

The article's framework maps directly to missing Agama flows. Each should be a standalone deployable project.

3.1.1 agama-passkey-adopt — Post-Login Passkey Nudge

Purpose: After a user successfully logs in with password+OTP, detect if they have no passkey registered and prompt them to add one.
Trigger: Wraps any existing authentication flow as a step-up.
Key logic:

  • Check EnrollmentHelper.getMFAUserInfoByFido2(uid) — if count == 0, show nudge screen
  • Offer "Add a passkey now" (triggers org.gluu.agama.passkey.add) or "Remind me later" (skippable, with configurable snooze via user attribute)
  • Track nudge impressions vs. conversions in a custom LDAP/DB attribute

Why it matters: This is the "Automatic Passkey Append" pattern from the Corbado guide — the single highest-impact driver of adoption.


3.1.2 agama-passkey-first — Passkey-First / Passwordless Login

Purpose: An identifier-first login flow where passkey is the primary method, password is the fallback.
Flow:

  1. User enters username (identifier-first)
  2. Conditional UI (autocomplete="username webauthn") triggers browser passkey picker automatically
  3. If no passkey exists or user declines → fall back to password
  4. On successful password login with no passkey → trigger nudge (3.1.1)

Frontend change needed in main.ftlh:

<input type="text" name="username" autocomplete="username webauthn" ...>

This enables the browser's native passkey autofill without any button press.

Why it matters: The article calls this the "identifier-first approach" and "One-Tap Login" — it's the UX pattern that drives the highest login success rates.


3.1.3 agama-passkey-recovery — Account Recovery with Passkey Re-enrollment

Purpose: When a user loses all passkeys (device lost/replaced), provide a secure re-enrollment path without requiring a support call.
Flow:

  1. User attempts passkey login → fails
  2. Offer "I lost my passkey" link
  3. Verify identity via email OTP or backup code
  4. Immediately prompt to enroll a new passkey on the current device
  5. Optionally: integrate with identity verification provider for high-assurance recovery

Why it matters: The article identifies account recovery cost as one of the top 3 problems passkeys solve — but only if the recovery path itself is digitalized.


3.1.4 agama-passkey-step-up — Step-Up Authentication for Sensitive Actions

Purpose: Require passkey re-authentication before high-risk operations (password change, MFA settings, payment confirmation).
Flow:

  1. User is already logged in (session exists)
  2. Sensitive action triggers step-up
  3. Assert passkey for the current user's uid (scoped assertion)
  4. On success, grant elevated session claim

Why it matters: Demonstrates passkeys as phishing-resistant MFA, not just a password replacement — important for regulated industries.


3.1.5 agama-passkey-cross-device — Cross-Device / QR Code Flow

Purpose: Allow login on a desktop using a passkey stored on a mobile device.
Flow:

  1. User clicks "Use a passkey from another device"
  2. WebAuthn transport: ["hybrid"] triggers QR code display
  3. User scans with phone, authenticates with biometric
  4. Desktop session is established

Note: This is largely handled by the browser/OS via the CTAP2 hybrid transport — the Agama flow mainly needs to not block it. Current code deletes authenticatorAttachment in passkey-add.ftlh which is correct, but the assertion flow should also avoid restricting transports.


3.2 AdminUI: Passkey Adoption Dashboard

Proposed AdminUI additions

3.2.1 Adoption Metrics Panel
A new "Passkey Adoption" section in AdminUI showing:

Metric Source How to compute
Total users LDAP/DB user count Existing
Users with ≥1 passkey SCIM Fido2Devices count > 0 per user New query
Adoption % (users with passkey / total users) × 100 Derived
Passkeys enrolled (total) Sum of all Fido2Device entries New query
Avg passkeys per enrolled user total passkeys / enrolled users Derived
New enrollments (last 7/30 days) Fido2Device creationDate filter New query
Passkey login events (last 7/30 days) Auth server event log filter New query

3.2.2 Per-User Passkey Status
In the existing user detail view, add a "Passkeys" tab showing:

  • List of enrolled passkeys with nickname, creation date, last used date, authenticator type (platform vs. roaming)
  • Admin ability to revoke a passkey (calls SCIM DELETE on Fido2Device)
  • "Send enrollment nudge" button (triggers email with enrollment link)

3.2.3 Rollout Configuration Panel
Allow admins to configure the nudge/adoption strategy without code changes:

  • Enable/disable post-login nudge globally
  • Set nudge frequency (e.g., show every N logins until enrolled)
  • Define which user groups are in the "passkey rollout wave"
  • Set minimum passkey adoption target (shows progress bar toward goal)

Implementation approach: These metrics can be surfaced via a new Janssen Config API endpoint (e.g., GET /jans-config-api/api/v1/passkey/stats) that aggregates from SCIM and the auth event log. AdminUI calls this endpoint to render the dashboard.


3.3 FIDO Server / API Enhancements

3.3.1 Expose authenticator metadata in SCIM

Currently ScimFido2Helper drops entries with deviceData. This field contains authenticator type (platform/roaming), AAGUID, and transport hints. It should be:

  • Preserved and surfaced in the passkey list UI (show "Face ID", "Windows Hello", "Security Key" icons)
  • Used in AdminUI to break down adoption by authenticator type

3.3.2 Add lastAccessTime to Fido2Device

The SCIM Fido2Device schema should track when a passkey was last used for authentication. This enables:

  • Users to identify and remove stale passkeys
  • AdminUI to show "active" vs. "dormant" passkeys
  • Adoption metrics to distinguish enrolled-but-never-used from actively-used passkeys

3.3.3 Passkey adoption event logging

The Jans auth server should emit structured audit events for:

  • PASSKEY_ENROLLED — user enrolled a new passkey
  • PASSKEY_AUTH_SUCCESS — user authenticated with a passkey
  • PASSKEY_AUTH_FAILURE — passkey assertion failed (with reason)
  • PASSKEY_NUDGE_SHOWN — adoption nudge was displayed
  • PASSKEY_NUDGE_ACCEPTED / PASSKEY_NUDGE_DISMISSED

These feed the AdminUI dashboard and can be forwarded to SIEM.

3.3.4 Conditional UI support (WebAuthn autofill)

Add GET /.well-known/fido2-configuration response field conditionalMediationSupported: true and ensure the assertion endpoint supports mediation=conditional requests (no allowCredentials required when username is unknown).


3.4 Documentation Reframe

Reframe all user-facing and developer-facing docs around "passkey adoption" language.

Language changes

Current (FIDO jargon) Proposed (adoption language)
"FIDO2 device" "passkey"
"attestation" "passkey enrollment" / "adding a passkey"
"assertion" "signing in with a passkey"
"authenticator" "device" or "security key"
"relying party" "your app" or "your service"
"AAGUID" (hide from end users entirely)
"WebAuthn" (developer docs only)

New documentation pages needed

  1. "Getting Started with Passkeys" — operator guide, replaces "FIDO2 Configuration"
  2. "Passkey Adoption Playbook" — how to roll out passkeys to your users (mirrors the Corbado article's 11-step framework but Janssen-specific)
  3. "Measuring Passkey Adoption" — how to use the AdminUI dashboard and interpret metrics
  4. "Passkey User Guide" — end-user-facing, embeddable in help centers
  5. "Passkey Recovery Guide" — what to do when you lose your passkey

4. Prioritized GitHub Issues

P0 — Quick wins (fix existing project)

  • Remove debug alert() from passkey-add.ftlh — ships to production users
  • Fix dead code in FidoValidator.assertionRequest() — content string built then overwritten
  • Make nickname optional — default to device type or "My Passkey" if blank; remove required from nickname input
  • Stop filtering out deviceData entries in ScimFido2Helper — platform authenticators are being silently dropped

P1 — High impact adoption features

  • New Agama project: agama-passkey-adopt (post-login nudge)
  • Add Conditional UI support to main.ftlh login form (autocomplete="username webauthn")
  • AdminUI: Passkey Adoption Metrics panel
  • New Agama project: agama-passkey-first (passkey-first login)

P2 — Complete the ecosystem

  • New Agama project: agama-passkey-recovery
  • New Agama project: agama-passkey-step-up
  • Add lastAccessTime to Fido2Device SCIM schema
  • Passkey adoption event logging in auth server
  • AdminUI: Per-user passkey management tab
  • AdminUI: Rollout configuration panel

P3 — Documentation

  • Reframe all FIDO docs around passkey adoption language
  • Write Passkey Adoption Playbook for operators
  • Write end-user Passkey Guide

5. Success Metrics

Metric Baseline 3-month target 12-month target
Passkey adoption rate ~0% (no visibility) 10% 40%
Passkey login rate (of total logins) ~0% 5% 30%
Avg time to enroll passkey N/A < 60 seconds < 45 seconds
Account recovery tickets Baseline TBD -10% -40%

6. References

Clone this wiki locally