test(webauthn): fake authenticator + ceremony-level integration tests (#162)#228
Merged
Conversation
This was referenced Jul 1, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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/verifyAuthenticationResponsewas 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-validRegistrationResponseJSONandAuthenticationResponseJSONin the@simplewebauthnshapes. Signs assertions with DER ECDSA overauthData || SHA256(clientDataJSON); builds the attestation object + COSE key with the library's ownisoCBORso the bytes decode identically in the verifier. Overrides forrpId/origin/uv/up/signCountenable negative tests.webauthn-ceremony-flow.test.ts— 9 tests over a thin per-test app (real in-memory SQLite + bearer gate + webauthn/hydra routes):POST /api/auth/register(self-register bootstrap → active credential, and the COSE→OpenSSHwebauthn-sk-ecdsaline 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).fake-hydra.ts— small addition:setLoginRequest(challenge)makesacceptLoginRequestresolve 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
actionwire value is snake_case (register_passkey, …) — theSTEPUP_ACTIONmap values — butopenapi.yamldocumented the camelCase keys (registerPasskey). Corrected both/stepup/optionsand/stepup/verifyenums in the spec, with a comment noting the ceremony test as the evidence. (Adapted the issue'sPOST /api/auth/loginto its current form, the Hydra login provider/api/hydra/login/verify, since login moved to Hydra in #217.)Validation
pnpm test:integration153/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.