Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion capabilities/client.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ features:
group: authentication_integration
- id: client.authentication_integration.cross_client_token_sync
name: Cross-Client Token Synchronization
description: The client listens for auth state change events and automatically propagates the current JWT to all sub-clients (database, realtime, storage, functions) so requests stay authenticated without manual intervention.
description: Every sub-client (database, realtime, storage, functions) stays authenticated with the current JWT as the session signs in, refreshes, and signs out, without the caller updating any of them by hand. Whether the client pushes the token on auth state change events or each sub-client resolves it per request is an implementation detail.
group: authentication_integration
- id: client.authentication_integration.oauth_flow_type
name: OAuth Flow Type Selection
Expand Down
6 changes: 3 additions & 3 deletions capabilities/functions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ features:
name: Invoke Function
description: Call a deployed Edge Function by name with an optional request body.
group: invocation
- id: functions.invocation.set_auth_token
name: Set Auth Token
description: Update the authorization token sent with all subsequent function invocations.
- id: functions.invocation.auth_token
name: Invocation Auth Token
description: Supply the authorization token sent with function invocations, fixed at client construction, resolved per request from an access token provider, or overridden on a single call.
group: request_configuration
- id: functions.invocation.method_override
name: HTTP Method Override
Expand Down
28 changes: 28 additions & 0 deletions specs/functions/invocation/auth_token.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Invocation Auth Token

Determine which authorization token a function invocation sends, without requiring the SDK to hold a mutable token on the functions client.

## Behavior

An invocation sends an `Authorization` header resolved from the first of these that applies:

1. **Per-call override.** A header passed to a single invocation wins over everything else, and applies only to that call.
2. **Access token provider.** A token supplied by the client, resolved fresh on every request. For a functions client owned by a `SupabaseClient`, this is the current session token, so the header follows sign-in, refresh, and sign-out with no further action. For a standalone functions client, this is whatever provider the caller passed at construction.
3. **Construction-time header.** An `Authorization` header passed when the functions client is built, used when there is no provider.

If none apply, the invocation carries no `Authorization` header. The API key header, where the SDK sends one, is independent of this capability.

An SDK satisfies this capability through any combination of the three that covers per-call override plus one non-per-call source. A stateful `setAuthToken(token)` mutator is one such source, but it is not required, and is not the preferred shape where the SDK can resolve a token per request instead.

## Notes

- **A per-call override must beat a live session token.** An SDK whose auth layer unconditionally overwrites `Authorization` breaks point 1 even though it appears to implement the capability. This is worth an explicit test rather than an assumption.
- **A stateful setter is a shadowing hazard.** A token pinned by a mutator outlives the session that was current when it was set: it keeps being sent after that session refreshes or signs out, and nothing clears it. SDKs that resolve the token per request avoid this by construction.
- Where a mutator does exist, its scope is the functions client alone. Cross-client propagation is [Cross-Client Token Synchronization](client.authentication_integration.cross_client_token_sync).

## Related

- [Invoke Function](functions.invocation.invoke) — the call this configures
- [Set Auth Token](realtime.client.set_auth_token) — Realtime's equivalent, which *is* a mutator: it holds a live socket and pushes a new token over it rather than attaching one per request
- [Cross-Client Token Synchronization](client.authentication_integration.cross_client_token_sync) — how the umbrella client keeps this token current
- [Third-Party Auth](client.authentication_integration.third_party_auth) — the construction-time token callback that feeds the provider in point 2