Skip to main content
Email/password, magic links and one-time codes work against a fresh local stack with no credentials at all. Everything below needs something only the project owner can supply.
For a local stack these values live in supabase/config.toml, which is read only at boot. After any change, run supabase stop && supabase start.

GitHub sign-in

Create an OAuth app at github.com/settings/developers. Set its Authorization callback URL to GoTrue, not to the plugin:
For a hosted project that is https://<project>.supabase.co/auth/v1/callback.
Then enable the provider:
supabase/config.toml

Google sign-in

Same shape, from console.cloud.google.comOAuth client ID, type Web application, with the same GoTrue callback URL.
supabase/config.toml
skip_nonce_check = true is required for loopback sign-in. The nonce cannot be verified over a local redirect.

Apple sign-in

Apple does not fit the shape above, and the differences are the kind that cost an afternoon.
Apple sign-in cannot be tested against a local stack. Apple rejects a Return URL that is http:// or points at localhost / 127.0.0.1, so http://127.0.0.1:54321/auth/v1/callback — the callback GitHub and Google use — cannot be registered on the Apple side at all. You need a hosted project, or an HTTPS tunnel terminating in front of GoTrue.
From developer.apple.com, create a Services ID — not an App ID. Its identifier is what GoTrue sends as client_id; the bundle ID of a native app is a different thing and will fail with invalid_client. Set its Return URL to GoTrue:
The client secret is not a string. Apple wants an ES256-signed JWT built from a .p8 signing key, with iss set to your Team ID, sub to the Services ID, and aud to https://appleid.apple.com.
supabase/config.toml
The secret expires. Apple refuses a client secret JWT dated more than six months out, so sign-in works for months and then starts failing with no code change and no deploy to blame. Rotate it on a calendar reminder, and keep the .p8 — you need it to mint each replacement.
Two smaller differences worth knowing. Apple sends the user’s name only on the very first authorization for a given Apple ID, and never in the identity token — so there is nothing for GoTrue to populate user_metadata from on any later sign-in. Deleting the user server-side does not reset this: the authorization still exists on Apple’s side, so they come back nameless. Only the user can restore it, by revoking the app under Settings → Apple Account → Sign in with Apple and authorizing again. If you need a display name, capture it on first sign-in or ask for it during onboarding. Users may also sign in with Hide My Email, which mints a per-app …@privaterelay.appleid.com address that forwards to their real inbox. It is deliverable, but it is not their real address and the user can switch forwarding off per app at any time. Treat it as an identifier, not as a way to match an existing account by email.

Redirect URLs

Every provider depends on additional_redirect_urls. The plugin binds the first free port from oauth.callbackPorts and asks GoTrue to redirect to http://127.0.0.1:<port>/callback. The list is matched exactly, so every candidate port must be present. This is the hop after the provider, so the loopback address is fine here even for Apple — GoTrue redirects to it, Apple never sees it.
supabase/config.toml
Change oauth.callbackPorts in tauri.conf.json and this list has to change with it, or the round-trip dies after the consent screen with a redirect error that is not a structured plugin error.

Account linking

supabase/config.toml
Off by default. Without it, useIdentities() can list identities but link() fails with a configuration error.

Passkeys

The server side needs [auth.passkey] enabled = true plus the relying-party settings described in Passkeys. What you supply beyond that is platform-dependent:

Local development

The mail UI catches confirmation and recovery messages, so email flows are testable end to end without a real inbox.