Skip to content

Accept the auth server issuer in edge function JWT verification - #375

Open
thomasbergernz wants to merge 1 commit into
marmelab:mainfrom
Confluenceservice:fix/functions-jwt-issuer
Open

thomasbergernz wants to merge 1 commit into
marmelab:mainfrom
Confluenceservice:fix/functions-jwt-issuer

Conversation

@thomasbergernz

Copy link
Copy Markdown

Problem

Edge functions that use AuthMiddleware (users, merge_contacts, delete_note_attachments, update_password) verify the user's JWT against a single issuer: SB_JWT_ISSUER, or SUPABASE_URL/auth/v1 when it is unset. supabase/functions/.env sets it to http://127.0.0.1:54321/auth/v1.

When the local Supabase stack is reached through another URL, the auth server signs tokens with that public URL as iss. This happens when [auth] external_url / API_EXTERNAL_URL is set, for example behind a reverse proxy or tunnel. Every request then fails with 401 JWTClaimValidationFailed: unexpected "iss" claim value, so managing users from the Settings page fails.

Solution

Also accept the issuer that the auth server advertises in /auth/v1/.well-known/openid-configuration. Only the accepted iss values change:

  • the signature is still verified against the project JWKS
  • the configured issuer is still accepted
  • discovery is cached, and retried on the next request if the auth server was unreachable

The logic lives in a small helper (_shared/jwtIssuer.ts) with unit tests.

This doesn't touch the MCP function, which #373 rewrites.

How To Test

  1. In supabase/config.toml, set [auth] external_url to a URL other than http://127.0.0.1:54321/auth/v1, and serve the stack through it.
  2. make start, log in, then edit a user in Settings → Users (PATCH /functions/v1/users).
  3. Before this change the request returns 401 unexpected "iss" claim value. After it, the request succeeds.

Unit tests: npm run test:unit:functions -- supabase/functions/_shared.

I also checked the helper against a running auth server with a public external_url. A token with the public issuer is rejected with the current configured issuer and accepted with the new list.

Additional Checks

  • The documentation is up to date (no user-facing change)
  • Tested with fakerest provider (not applicable: edge functions only)
  • Tested with Mobile resolution (not applicable)

Edge functions verify user tokens against SB_JWT_ISSUER, which
supabase/functions/.env sets to http://127.0.0.1:54321/auth/v1. When the
local stack is served under another URL (auth.external_url, e.g. behind a
reverse proxy), the auth server issues tokens with that public URL as
"iss", so AuthMiddleware rejects every request with
unexpected iss claim value and user management fails.

Also accept the issuer advertised by the auth server itself
(/auth/v1/.well-known/openid-configuration). The signature is still
checked against the project JWKS. Discovery is cached, and retried on the
next request if the auth server could not be reached.

This branch has not been deployed

No deployments
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.

1 participant