fix(functions): stop sending API key in Authorization header for function calls#2511
Merged
Merged
Conversation
@supabase/auth-js
@supabase/functions-js
@supabase/postgrest-js
@supabase/realtime-js
@supabase/storage-js
@supabase/supabase-js
commit: |
kallebysantos
previously approved these changes
Jul 10, 2026
mandarini
marked this pull request as ready for review
July 10, 2026 12:29
Tr00d
previously approved these changes
Jul 10, 2026
grdsdev
previously approved these changes
Jul 10, 2026
spydon
reviewed
Jul 10, 2026
…ader logic Future-proof the sb_ key family per auth-team guidance (stojan): createClient() now validates the key format at construction and throws for a key that starts with sb_ but is not a recognized subtype (sb_publishable_ / sb_secret_), signalling that the SDK must be upgraded to support the new type. Legacy JWT keys (no sb_ prefix) and the two recognized subtypes are unaffected, so no key that works today starts failing — this is not a breaking change. Also addresses review feedback on fetch.ts: - rename the fetchWithAuth option isFunctionsClient -> omitApiKeyAsBearer so the generic util no longer knows about a "functions client" - compute the key-as-Bearer decision once at construction instead of per request - drop the accessToken === supabaseKey equality proxy; split a raw _getSessionToken() (null when no session) from the coalescing _getAccessToken(), and feed the raw getter to the fetch wrappers so Authorization fallback lives in one place - collapse the triplicated rationale comment to a single canonical location Realtime keeps using _getAccessToken(); PostgREST/Storage behavior is unchanged.
mandarini
dismissed stale reviews from grdsdev, Tr00d, and kallebysantos
via
July 13, 2026 13:19
7500549
spydon
approved these changes
Jul 13, 2026
This was referenced Jul 14, 2026
mandarini
pushed a commit
to supabase/ssr
that referenced
this pull request
Jul 14, 2026
This PR updates `@supabase/supabase-js` to v2.110.5. **Source**: supabase-js-stable-release --- ## Release Notes ## v2.110.5 ## 2.110.5 (2026-07-14) ### 🩹 Fixes - **supabase:** avoid edge runtime warning ([#2522](supabase/supabase-js#2522)) ### ❤️ Thank You - Vaibhav @7ttp ## v2.110.4 ## 2.110.4 (2026-07-14) ### 🩹 Fixes - **functions:** stop sending API key in Authorization header for function calls ([#2511](supabase/supabase-js#2511)) - **realtime:** encode broadcast header fields as UTF-8 ([#2516](supabase/supabase-js#2516)) ### ❤️ Thank You - Katerina Skroumpelou @mandarini - Pedro Henrique This PR was created automatically. Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com>
mandarini
pushed a commit
to supabase/supabase
that referenced
this pull request
Jul 14, 2026
This PR updates @supabase/*-js libraries to version 2.110.5. **Source**: supabase-js-stable-release **Changes**: - Updated @supabase/supabase-js to 2.110.5 - Updated @supabase/auth-js to 2.110.5 - Updated @supabase/realtime-js to 2.110.5 - Updated @supabase/postgest-js to 2.110.5 - Refreshed pnpm-lock.yaml --- ## Release Notes ## v2.110.5 ## 2.110.5 (2026-07-14) ### 🩹 Fixes - **supabase:** avoid edge runtime warning ([#2522](supabase/supabase-js#2522)) ### ❤️ Thank You - Vaibhav @7ttp ## v2.110.4 ## 2.110.4 (2026-07-14) ### 🩹 Fixes - **functions:** stop sending API key in Authorization header for function calls ([#2511](supabase/supabase-js#2511)) - **realtime:** encode broadcast header fields as UTF-8 ([#2516](supabase/supabase-js#2516)) ### ❤️ Thank You - Katerina Skroumpelou @mandarini - Pedro Henrique ## v2.110.3 ## 2.110.3 (2026-07-13) ### 🩹 Fixes - **auth:** preserve pkce verifier ([#2513](supabase/supabase-js#2513)) - **postgrest:** pin tstyche target off floating latest ([#2509](supabase/supabase-js#2509)) ### ❤️ Thank You - Katerina Skroumpelou @mandarini - Vaibhav @7ttp ## v2.110.2 ## 2.110.2 (2026-07-09) ### 🩹 Fixes - **auth:** clear local session on signout failures ([#2504](supabase/supabase-js#2504)) ### ❤️ Thank You - Luc Peng This PR was created automatically. Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com>
6 tasks
This was referenced Jul 15, 2026
mandarini
pushed a commit
to supabase/supabase
that referenced
this pull request
Jul 15, 2026
This PR updates @supabase/*-js libraries to version 2.110.6. **Source**: supabase-js-stable-release **Changes**: - Updated @supabase/supabase-js to 2.110.6 - Updated @supabase/auth-js to 2.110.6 - Updated @supabase/realtime-js to 2.110.6 - Updated @supabase/postgest-js to 2.110.6 - Refreshed pnpm-lock.yaml --- ## Release Notes ## v2.110.6 ## 2.110.6 (2026-07-15) ### 🩹 Fixes - **postgrest:** type hinted self-referencing embeds as arrays ([#2520](supabase/supabase-js#2520)) - **realtime:** forward opts to send() in track() ([#2490](supabase/supabase-js#2490)) - **supabase:** warn instead of throw for unrecognized sb_ API key subtypes ([#2526](supabase/supabase-js#2526)) ### ❤️ Thank You - Franco Kaddour @FrancoKaddour - Katerina Skroumpelou @mandarini ## v2.110.5 ## 2.110.5 (2026-07-14) ### 🩹 Fixes - **supabase:** avoid edge runtime warning ([#2522](supabase/supabase-js#2522)) ### ❤️ Thank You - Vaibhav @7ttp ## v2.110.4 ## 2.110.4 (2026-07-14) ### 🩹 Fixes - **functions:** stop sending API key in Authorization header for function calls ([#2511](supabase/supabase-js#2511)) - **realtime:** encode broadcast header fields as UTF-8 ([#2516](supabase/supabase-js#2516)) ### ❤️ Thank You - Katerina Skroumpelou @mandarini - Pedro Henrique ## v2.110.3 ## 2.110.3 (2026-07-13) ### 🩹 Fixes - **auth:** preserve pkce verifier ([#2513](supabase/supabase-js#2513)) - **postgrest:** pin tstyche target off floating latest ([#2509](supabase/supabase-js#2509)) ### ❤️ Thank You - Katerina Skroumpelou @mandarini - Vaibhav @7ttp ## v2.110.2 ## 2.110.2 (2026-07-09) ### 🩹 Fixes - **auth:** clear local session on signout failures ([#2504](supabase/supabase-js#2504)) ### ❤️ Thank You - Luc Peng This PR was created automatically. Co-authored-by: supabase-workflow-trigger[bot] <266661614+supabase-workflow-trigger[bot]@users.noreply.github.com>
This was referenced Jul 16, 2026
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
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.
Description
Edge Function calls (
supabase.functions.invoke()) no longer put the project API key in theAuthorizationheader when there is no user session. The key is sent only in theapikeyheader, andAuthorizationis reserved for a real user (or custom) session token, matching the Server SDK pattern.What changed?
packages/core/supabase-js/src/lib/fetch.ts:fetchWithAuthaccepts a new optional{ isFunctionsClient }flag. When set, it no longer falls back to sending the API key asAuthorization: Bearer <key>, but only for new-format keys (sb_publishable_.../sb_secret_...). A real session/custom token is still sent, and theapikeyheader is unchanged.packages/core/supabase-js/src/SupabaseClient.ts: added a dedicatedfunctionsFetchbuilt with{ isFunctionsClient: true }. Thefunctionsgetter uses it; REST (PostgREST), Storage, and Realtime keep the sharedfetchand are unaffected.packages/core/functions-js/src/FunctionsClient.ts: updated theinvokeJSDoc to describe theapikeyvsAuthorizationheader semantics.docs/MIGRATION.md: added an "Edge Functions auth headers" section documenting the behavior and the one edge case that is affected.fetch.test.tsfor theisFunctionsClientoption and an integration case inSupabaseClient.test.tsproving functions omitAuthorizationfor a new-format key with no session while other services do not.Why was this change needed?
New-format API keys (
sb_publishable_.../sb_secret_...) are not JWTs, so sending them asAuthorization: Bearer <key>caused the gateway to reject the request with "invalid token format." A platform apikey-compatibility patch (now GA) letsverify_jwt=truefunctions be called with only theapikeyheader, so the SDK no longer needs to duplicate the key intoAuthorization. This aligns Functions with the Server SDK convention:Authorizationis for user/custom tokens only.Closes SDK-1050.
Screenshots/Examples
Unauthenticated function call with a new-format key:
Before:
After:
Authenticated call (unchanged):
Breaking changes
The change is scoped to Edge Functions only, and legacy JWT keys keep their existing behavior (still sent in
Authorizationfor backward compatibility), so this is not a breaking change in practice. The only impacted case is code that reads the API key out of theAuthorizationheader inside an Edge Function; those should read theapikeyheader instead, or migrate to@supabase/server.Checklist
<type>(<scope>): <description>pnpm nx formatto ensure consistent code formattingAdditional notes
Scope is intentionally limited to new-format keys so there is zero regression risk for self-hosted or legacy-key users on older gateways. Moving to an unconditional drop for all key types later is a one-line change (removing the key-format guard in
fetch.ts), best done on v3 or once apikey-compatibility is universal.