Skip to content

refactor: replace passkey challenge structs with PasskeyCeremony - #362

Draft
livio-a wants to merge 8 commits into
mainfrom
ref-webauthn
Draft

refactor: replace passkey challenge structs with PasskeyCeremony#362
livio-a wants to merge 8 commits into
mainfrom
ref-webauthn

Conversation

@livio-a

@livio-a livio-a commented Jun 19, 2026

Copy link
Copy Markdown
Member

Summary

Refactors WebAuthn passkey ceremony handling to stop mirroring go-webauthn types in domain structs and rebuilding browser JSON by hand.

  • Introduces PasskeyCeremony: persists session_data + rp_origins for verify; keeps clientOptions in-memory only (not written to DB) and exposes them via ClientOptions() at issue time.
  • Replaces PasskeyChallenge, PasskeyRegistrationChallenge, and BuildPasskey* helpers with CreatePasskeyChallenge / VerifyPasskeyChallenge and CreatePasskeyRegistrationChallenge / VerifyPasskeyRegistrationChallenge.
  • Wires AuthChallengePasskey and PasskeyRegistration.Challenge to *PasskeyCeremony; service and flow adapters return ceremony options verbatim to the client.
  • Maps auth-attempt challenge payloads by unmarshaling stored ceremony ClientOptions into the API envelope (challengePayloadToAPI).
  • Sets registration WebAuthn defaults in domain: attestation: none, residentKey: preferred, excludeCredentials for existing passkeys; threads userVerification from service/flow into CreatePasskeyRegistrationChallenge.
  • Aligns domain errors with existing att.* codes (ErrAuthAttemptInvalidState, ErrInternal, raw go-webauthn verify errors wrapped as ErrAuthAttemptProofRejected at the service layer).

Motivation

The old model converted webauthn.SessionData field-by-field, discarded go-webauthn client options at issue, then rebuilt them for the browser — duplicating the library and risking drift. This stores what go-webauthn needs for verify and returns what it produced for the browser at issue time.

Out of scope (follow-ups)

  • Conditional UI / mediation: "conditional" (ADR 013 future work)
  • toFlowStepChallenge always emitting method: "passkey" — registration browser path still needs OpenAPI + API mapper fix
  • Policy-driven userVerification (required for MFA vs preferred for primary passkey) — flow still hardcodes "preferred"

Test plan

  • go test ./internal/domain/... ./internal/service/... ./internal/api/...
  • go test -tags postgres_integration ./internal/api/integration_test/... -run 'Passkey|Registration|Upsell'
  • go test -tags postgres_integration ./internal/storage/database/repository/... -run Passkey
  • Full corepack pnpm run check -- --full (blocked by unrelated cmd/server TestEmbeddedPostgresOptionsUseDataDir failure on this machine)

@vercel

vercel Bot commented Jun 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nextgen Ready Ready Preview, Comment Jul 7, 2026 1:24pm
nextgen-docs Ready Ready Preview, Comment Jul 7, 2026 1:24pm
nextgen-mock-zitadel Ready Ready Preview, Comment Jul 7, 2026 1:24pm

Request Review

@github-actions

github-actions Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

⚠️ No Changeset found

Latest commit: f1188e3

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@livio-a livio-a closed this Jun 25, 2026
@livio-a
livio-a deleted the ref-webauthn branch June 25, 2026 07:50
@livio-a
livio-a restored the ref-webauthn branch June 25, 2026 07:50
@livio-a livio-a reopened this Jun 25, 2026
Resolve conflicts by combining main's DisplayName registration labels
and CI tarball journey setup with the PasskeyCeremony refactor.

Co-authored-by: Cursor <cursoragent@cursor.com>
Update merged tests to assert persisted session data instead of removed
challenge username fields, and relax residentKey checks when go-webauthn
omits the preferred default from JSON.

Co-authored-by: Cursor <cursoragent@cursor.com>
@livio-a livio-a changed the title refactor(server): replace passkey challenge structs with PasskeyCeremony refactor: replace passkey challenge structs with PasskeyCeremony Jul 7, 2026
@fforootd

Copy link
Copy Markdown
Member

Is this still relevant?

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.

2 participants