-
Notifications
You must be signed in to change notification settings - Fork 548
feat: webauthn support schema changes, update openapi.yaml #2163
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
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
hf
approved these changes
Sep 15, 2025
Tested, works beautifully! Let's merge on Monday. |
hf
approved these changes
Sep 23, 2025
c0231f2
to
551dcd3
Compare
Pull Request Test Coverage Report for Build 17948586214Details
💛 - Coveralls |
551dcd3
to
ddc2d19
Compare
hf
added a commit
to supabase/auth-js
that referenced
this pull request
Sep 24, 2025
## What kind of change does this PR introduce? **Feature** - This PR introduces YubiKey support for Multi-Factor Authentication (MFA) via WebAuthn, enabling users to authenticate with hardware security keys. ## What is the current behavior? Currently, Supabase Auth JS supports two MFA methods: - TOTP (Time-based One-Time Password) authenticators - SMS-based verification ## What is the new behavior? This PR adds full WebAuthn support to the authentication library, the defaults enable yubikey support at the moment, but it allows the user to override some parameters client-side to use other types of passkey methods. The PR adds the 'webauthn' factor type, to `listFactors`, `enroll()`, `challenge()`, and `verify()` (De)serialization of the webauthn reponse/credential object is done behind the scenes via dedicated objects. it also adds a new `experimental` namespace `.mfa.webauthn` which has a `.register()` and `.authenticate()` methods, these methods allows **single click** yubikey 2FA addition with a single function call. additionally, we have `webauthn.{enroll|challenge|verify}()`, which abstract away some of the logic surrounding enrollment, interaction with the verifier, and have defaults for factortype etc. ### Two ways to use the new api: #### Single Step ```typescript const { data, error } = await client.mfa.webauthn.register({ friendlyName: `Security Key ${new Date().toLocaleDateString()}`, rpId: window.location.hostname, rpOrigins: [window.location.origin] }, { authenticatorSelection: { authenticatorAttachment: 'platform', residentKey: 'discouraged', userVerification: 'discouraged', requireResidentKey: false } }); if (error) throw error; console.log(data); // <- session ``` #### Multi Step Composition ```typescript const { enroll, challenge, verify } = new WebAuthnApi(client); return enroll({ friendlyName: params.friendlyName }) .then(async ({ data, error }) => { if (!data) { throw error; } console.log(`enrolled factor, id: ${data.id}`, 'success'); return await challenge({ factorId: data?.id, webauthn: { rpId: params.rpId, rpOrigins: params.rpOrigins }, signal: undefined }); }) .then(async ({ data, error }) => { if (!data) { throw error; } console.log(`challenged factor, id: ${data.factorId}`, 'success'); return await verify({ factorId: data.factorId, challengeId: data.challengeId, webauthn: { rpId: params.rpId, rpOrigins: params.rpOrigins, type: data.webauthn.type, credential_response: data.webauthn.credential_response } }); }) .then(({ data, error }) => { if (!data) { throw error; } console.log(`verified factor, id: ${data.access_token}`, 'success'); return data; }); ``` ## Additional context While this PR focuses on YubiKey support, the architecture is designed to accommodate additional authenticator types in future releases (platform authenticators, passkeys, etc.) without requiring significant refactoring. I've added `webauthn.dom.ts` and `webauthn.errors.ts` which attempt to augment the typescript interfaces for webauthn since they are out of date and there are some new features that its not aware of yet but are publicly available in all major browsers. For all such types, and due to the complexity of the API, I've added comprehensive jsdocs for each parameter with reference to the w3a spec for reference on their usage. in all webauthn related methods, I've added the ability to **override** any of the parameters we pass by default to the `credentials.{get|create}()` method for convenience. This PR is dependent on my previous PR for streamlining types #1116 and this PR for `auth` supabase/auth#2163 --------- Co-authored-by: Stojan Dimitrovski <[email protected]>
issuedat
pushed a commit
that referenced
this pull request
Sep 30, 2025
## What kind of change does this PR introduce? Feature improvement / API cleanup ## What is the current behavior? - The API returns credential_creation_options and credential_request_options as separate fields at the root level, requiring clients to check which is null - OpenAPI spec doesn't match actual server output (missing publicKey wrapper that go-webauthn library adds) - Field naming inconsistent with W3C spec (web_authn vs standard webauthn) ## What is the new behavior? 1. Challenge response structure changed to discriminated union: - Before: Check null fields {credential_creation_options?: ..., credential_request_options?: ...} - After: Single typed field {type: "create" | "request", credential_options: {publicKey: ...}} 2. Verify request structure unified: - Before: {creation_response?: ..., assertion_response?: ...} - After: {type: "create" | "request", credential_response: ...} 3. RPOrigins changed from comma-separated string to string array (matches go-webauthn v3 expectations) ## Additional context This makes the PR for the auth-js library easier.
mandarini
pushed a commit
to supabase/supabase-js
that referenced
this pull request
Oct 2, 2025
## What kind of change does this PR introduce? **Feature** - This PR introduces YubiKey support for Multi-Factor Authentication (MFA) via WebAuthn, enabling users to authenticate with hardware security keys. ## What is the current behavior? Currently, Supabase Auth JS supports two MFA methods: - TOTP (Time-based One-Time Password) authenticators - SMS-based verification ## What is the new behavior? This PR adds full WebAuthn support to the authentication library, the defaults enable yubikey support at the moment, but it allows the user to override some parameters client-side to use other types of passkey methods. The PR adds the 'webauthn' factor type, to `listFactors`, `enroll()`, `challenge()`, and `verify()` (De)serialization of the webauthn reponse/credential object is done behind the scenes via dedicated objects. it also adds a new `experimental` namespace `.mfa.webauthn` which has a `.register()` and `.authenticate()` methods, these methods allows **single click** yubikey 2FA addition with a single function call. additionally, we have `webauthn.{enroll|challenge|verify}()`, which abstract away some of the logic surrounding enrollment, interaction with the verifier, and have defaults for factortype etc. ### Two ways to use the new api: #### Single Step ```typescript const { data, error } = await client.mfa.webauthn.register({ friendlyName: `Security Key ${new Date().toLocaleDateString()}`, rpId: window.location.hostname, rpOrigins: [window.location.origin] }, { authenticatorSelection: { authenticatorAttachment: 'platform', residentKey: 'discouraged', userVerification: 'discouraged', requireResidentKey: false } }); if (error) throw error; console.log(data); // <- session ``` #### Multi Step Composition ```typescript const { enroll, challenge, verify } = new WebAuthnApi(client); return enroll({ friendlyName: params.friendlyName }) .then(async ({ data, error }) => { if (!data) { throw error; } console.log(`enrolled factor, id: ${data.id}`, 'success'); return await challenge({ factorId: data?.id, webauthn: { rpId: params.rpId, rpOrigins: params.rpOrigins }, signal: undefined }); }) .then(async ({ data, error }) => { if (!data) { throw error; } console.log(`challenged factor, id: ${data.factorId}`, 'success'); return await verify({ factorId: data.factorId, challengeId: data.challengeId, webauthn: { rpId: params.rpId, rpOrigins: params.rpOrigins, type: data.webauthn.type, credential_response: data.webauthn.credential_response } }); }) .then(({ data, error }) => { if (!data) { throw error; } console.log(`verified factor, id: ${data.access_token}`, 'success'); return data; }); ``` ## Additional context While this PR focuses on YubiKey support, the architecture is designed to accommodate additional authenticator types in future releases (platform authenticators, passkeys, etc.) without requiring significant refactoring. I've added `webauthn.dom.ts` and `webauthn.errors.ts` which attempt to augment the typescript interfaces for webauthn since they are out of date and there are some new features that its not aware of yet but are publicly available in all major browsers. For all such types, and due to the complexity of the API, I've added comprehensive jsdocs for each parameter with reference to the w3a spec for reference on their usage. in all webauthn related methods, I've added the ability to **override** any of the parameters we pass by default to the `credentials.{get|create}()` method for convenience. This PR is dependent on my previous PR for streamlining types supabase/auth-js#1116 and this PR for `auth` supabase/auth#2163 --------- Co-authored-by: Stojan Dimitrovski <[email protected]>
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.
What kind of change does this PR introduce?
Feature improvement / API cleanup
What is the current behavior?
What is the new behavior?
Additional context
This makes the PR for the auth-js library easier.