Context
SpringUserFramework is adding an opt-in WebAuthn step-up primitive (library issue: devondragon/SpringUserFramework#328, finding SUF-02). When user.security.stepUp.enabled=true, sensitive operations on passwordless (passkey-only) accounts require a fresh WebAuthn assertion ("step-up") within a short TTL before they are allowed:
POST /user/setPassword
- passkey delete / rename (
WebAuthnManagementAPI)
The library ships the server endpoints; the consuming app (this demo) must add the client-side ceremony and UI so the feature can be exercised and so we have a reference implementation.
What the demo app needs
- Client ceremony JS driving the step-up flow before a sensitive call:
POST /user/stepup/options (with the action, e.g. set-password) → receives PublicKeyCredentialRequestOptions.
navigator.credentials.get() with those options → produces an assertion.
POST /user/stepup/verify with the assertion + action → server stamps a single-use, action-bound, TTL'd session marker.
- Call the sensitive endpoint (
/user/setPassword, passkey delete/rename) within the TTL.
- Handle the
step-up-required response (HTTP 401 + distinct code) returned by sensitive endpoints when no valid marker exists — trigger the ceremony, then retry.
- UI wiring on the relevant pages (set-password on a passwordless account; passkey management delete/rename) to launch the ceremony.
- Playwright E2E test for the enabled path (
user.security.stepUp.enabled=true): passwordless account → attempt sensitive op → ceremony → success; and the negative path (no ceremony → 401).
Notes
- Default is
stepUp.enabled=false, so existing demo flows are unaffected until the flag is turned on.
- This is required to validate the library feature end-to-end (the library unit/integration tests cover the server side; the browser ceremony can only be validated here).
- Endpoint contract and marker semantics will be finalized in the library spec/PR (see #328); this issue tracks the demo-side work so it isn't lost.
Filed alongside the library-side SUF-02 design.
Context
SpringUserFramework is adding an opt-in WebAuthn step-up primitive (library issue: devondragon/SpringUserFramework#328, finding SUF-02). When
user.security.stepUp.enabled=true, sensitive operations on passwordless (passkey-only) accounts require a fresh WebAuthn assertion ("step-up") within a short TTL before they are allowed:POST /user/setPasswordWebAuthnManagementAPI)The library ships the server endpoints; the consuming app (this demo) must add the client-side ceremony and UI so the feature can be exercised and so we have a reference implementation.
What the demo app needs
POST /user/stepup/options(with the action, e.g.set-password) → receivesPublicKeyCredentialRequestOptions.navigator.credentials.get()with those options → produces an assertion.POST /user/stepup/verifywith the assertion + action → server stamps a single-use, action-bound, TTL'd session marker./user/setPassword, passkey delete/rename) within the TTL.step-up-requiredresponse (HTTP 401 + distinct code) returned by sensitive endpoints when no valid marker exists — trigger the ceremony, then retry.user.security.stepUp.enabled=true): passwordless account → attempt sensitive op → ceremony → success; and the negative path (no ceremony → 401).Notes
stepUp.enabled=false, so existing demo flows are unaffected until the flag is turned on.Filed alongside the library-side SUF-02 design.