Configure Passkey Authentication
Set up passkey authentication for self-hosted Supabase.
Overview#
Passkeys are passwordless, phishing-resistant credentials built on the WebAuthn standard. This guide covers the server-side configuration to enable passkey authentication in a self-hosted Supabase instance. For how passkeys work and how to use them from a client, see the Passkey authentication guide.
Enable passkey authentication#
For self-hosted Supabase, passkey authentication is configured through environment variables passed to the auth service in docker-compose.yml. The variables below control passkey authentication and WebAuthn configuration.
| Variable | Description | Default |
|---|---|---|
GOTRUE_PASSKEY_ENABLED | Enables passkey authentication. | false |
GOTRUE_PASSKEY_MAX_PASSKEYS_PER_USER | Maximum number of passkeys a single user can register. | 10 |
GOTRUE_WEBAUTHN_RP_ID | The bare domain name for your application (the WebAuthn relying party ID). Do not include a scheme, port, or path. This determines which passkeys can be used. Required when passkey auth is enabled. | - |
GOTRUE_WEBAUTHN_RP_DISPLAY_NAME | A human-readable name for your application, shown during the passkey prompt. Required when passkey auth is enabled. | - |
GOTRUE_WEBAUTHN_RP_ORIGINS | Comma-separated list of allowed origins (for example, https://example.com,https://app.example.com). Required when passkey auth is enabled. | - |
GOTRUE_WEBAUTHN_CHALLENGE_EXPIRY_DURATION | How long a WebAuthn challenge remains valid. If the ceremony isn't completed within this window, the client must request a new challenge. | 5m |
Configure the Auth service#
Add the environment variables to the auth service in your docker-compose.yml:
services: auth: environment: # ... existing variables ... GOTRUE_PASSKEY_ENABLED: true GOTRUE_PASSKEY_MAX_PASSKEYS_PER_USER: 10 # optional - default is 10 GOTRUE_WEBAUTHN_RP_ID: example.com GOTRUE_WEBAUTHN_RP_DISPLAY_NAME: my-app GOTRUE_WEBAUTHN_RP_ORIGINS: https://example.com,https://app.example.com GOTRUE_WEBAUTHN_CHALLENGE_EXPIRY_DURATION: 5m # optional - default is 5 minutesWebAuthn requires a secure context, so when setting GOTRUE_WEBAUTHN_RP_ORIGINS, keep the following requirements in mind:
- Origins must use HTTPS, except for loopback addresses (
localhost,127.0.0.1,[::1]). - Each origin's hostname must match or be a subdomain of
GOTRUE_WEBAUTHN_RP_ID. - Android native apps can use an app origin of the form
android:apk-key-hash:<base64url SHA-256 of the signing certificate>.
For local testing, set GOTRUE_WEBAUTHN_RP_ID to localhost and use http://localhost:3000 as the origin.
Changing the Relying Party ID invalidates existing passkeys
Passkeys are cryptographically bound to the Relying Party (RP) ID they were registered against. Changing the RP ID makes every existing passkey unusable for sign-in, and users will need to register a new one. Pick the RP ID carefully before users start enrolling, and keep it stable once they do.
Relaunch the Auth service#
After updating the environment variables, relaunch the auth service for the changes to take effect:
sh run.sh recreate authVerify passkeys are enabled#
Request an authentication challenge to confirm the auth service picked up the configuration:
curl -X POST 'http://<your-domain>/auth/v1/passkeys/authentication/options' \ -H 'apikey: your-supabase-publishable-key'A 200 response containing a challenge_id confirms that passkey authentication is enabled. A passkey_disabled error means the auth service did not pick up the configuration.
Manage a user's passkeys#
Use the Auth admin API to inspect or revoke a user's passkeys from a trusted server, for example to remove a lost device. These calls require your project's secret key, SUPABASE_SECRET_KEY, from your .env file and must never run in client code.
The Management API covered in the client guide targets api.supabase.com and isn't available for self-hosted deployments. Configure passkeys with the environment variables above, and manage individual passkeys with the admin endpoints below.
List a user's passkeys#
curl 'http://<your-domain>/auth/v1/admin/users/{user_id}/passkeys' \ -H 'apikey: your-supabase-secret-key'Delete a user's passkey#
curl -X DELETE 'http://<your-domain>/auth/v1/admin/users/{user_id}/passkeys/{passkey_id}' \ -H 'apikey: your-supabase-secret-key'Deleting a user's last passkey removes their ability to sign in with a passkey until they register a new one.
Next steps#
After you enable passkeys in your self-hosted Auth service, configure the client exactly as you would for a hosted project: opt in when you create the Supabase client, register a passkey, and sign in. See Enable in the client.