Skip to content

test(webauthn): fake authenticator + ceremony-level integration tests (#162)#228

Merged
rado0x54 merged 2 commits into
developfrom
test/webauthn-fake-authenticator
Jul 1, 2026
Merged

test(webauthn): fake authenticator + ceremony-level integration tests (#162)#228
rado0x54 merged 2 commits into
developfrom
test/webauthn-fake-authenticator

Conversation

@rado0x54

@rado0x54 rado0x54 commented Jul 1, 2026

Copy link
Copy Markdown
Owner

Summary

Closes #162. Adds a reusable in-memory fake WebAuthn authenticator and ceremony-level integration tests that drive the actual attestation/assertion crypto through every WebAuthn endpoint — closing the gap where successful verifyRegistrationResponse / verifyAuthenticationResponse was covered only by @simplewebauthn's own tests. This is item 4 of the #225 pre-Go-migration prep, and it unlocks the ceremony goldens deferred in #227.

What's included

src/test/helpers/fake-authenticator.ts — holds a P-256 (ES256 / alg -7) keypair, produces real, cryptographically-valid RegistrationResponseJSON and AuthenticationResponseJSON in the @simplewebauthn shapes. Signs assertions with DER ECDSA over authData || SHA256(clientDataJSON); builds the attestation object + COSE key with the library's own isoCBOR so the bytes decode identically in the verifier. Overrides for rpId / origin / uv / up / signCount enable negative tests.

webauthn-ceremony-flow.test.ts — 9 tests over a thin per-test app (real in-memory SQLite + bearer gate + webauthn/hydra routes):

  • Happy paths: POST /api/auth/register (self-register bootstrap → active credential, and the COSE→OpenSSH webauthn-sk-ecdsa line derives), POST /api/hydra/login/verify (login-provider assertion + counter bump), POST /api/webauthn/stepup/verify (mints a usable token), POST /api/webauthn/register (step-up-gated in-account add), POST /api/passkey-invite/register (pending credential).
  • Negatives: counter rollback, UV-required-but-not-set, origin mismatch, RP-ID mismatch.

fake-hydra.ts — small addition: setLoginRequest(challenge) makes acceptLoginRequest resolve for seeded challenges (mirrors the existing consent/logout seeding), enabling a genuine end-to-end login-provider happy path. Default reject behavior is unchanged, so existing 400-not-500 guard tests are unaffected.

Characterization finding (fixed here)

The test caught a spec bug from #226: the step-up action wire value is snake_case (register_passkey, …) — the STEPUP_ACTION map values — but openapi.yaml documented the camelCase keys (registerPasskey). Corrected both /stepup/options and /stepup/verify enums in the spec, with a comment noting the ceremony test as the evidence. (Adapted the issue's POST /api/auth/login to its current form, the Hydra login provider /api/hydra/login/verify, since login moved to Hydra in #217.)

Validation

  • New suite 9/9; full pnpm test:integration 153/153 (no regressions from the shared fake-hydra change).
  • pnpm typecheck ✓, pnpm api:lint ✓, pnpm spdx:check ✓.

Relates to #159, #217, #225 (item 4); unblocks ceremony goldens for #227's harness.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant