From 7df1b930fce34457cc82efc54765faa8b2425613 Mon Sep 17 00:00:00 2001 From: Miranda Limonczenko Date: Thu, 24 Sep 2026 17:08:17 -0700 Subject: [PATCH] docs(functions): regroup the Edge Function auth guide by information type Group the page's seven flat sections into three, so the top level fits the 5 +/- 1 chunking limit and the action path runs uninterrupted. - Open with a concept group, Choose an auth mode, holding the mode table - Gather the six patterns under Secure your function - Keep Environment variables last as the fact group - Add an intro outline linking the three groups, and a group introduction - Move the Authorization headers link below the mode table, so the table's introduction sits next to the table Every heading text is unchanged, so every slug is preserved and the in-page link to External webhooks still resolves. --- apps/docs/content/guides/functions/auth.mdx | 26 ++++++++++++++------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/apps/docs/content/guides/functions/auth.mdx b/apps/docs/content/guides/functions/auth.mdx index 511dfe9ce9a..4ab0d76a578 100644 --- a/apps/docs/content/guides/functions/auth.mdx +++ b/apps/docs/content/guides/functions/auth.mdx @@ -7,9 +7,13 @@ subtitle: 'Authentication patterns for Edge Functions' Secure an Edge Function by declaring which credentials it accepts. The `withSupabase` wrapper from the [`@supabase/server` package](https://github.com/supabase/server) on GitHub checks each caller against the `auth` mode you set. Your handler receives a preconfigured Supabase client on `ctx`. -For how authorization headers and the `verify_jwt` platform check work, see [Authorization headers](/docs/guides/functions/auth-headers). +- [Choose an auth mode](#choose-an-auth-mode) compares the four modes. Start here if you aren't sure which one your function needs. +- [Secure your function](#secure-your-function) has an example for each mode, plus how to combine modes and shape your own error response. +- [Environment variables](#environment-variables) lists what `@supabase/server` reads from the environment. -The wrapper accepts four `auth` modes: +## Choose an auth mode + +Each mode names the credential a caller must present. `withSupabase` accepts four: | Mode | Accepts | | --------------- | ------------------------------------------ | @@ -18,7 +22,13 @@ The wrapper accepts four `auth` modes: | `'publishable'` | A publishable key on `apikey` | | `'none'` | Any caller, no check (for signed webhooks) | -## Authenticated user calls +For how authorization headers and the `verify_jwt` platform check work, see [Authorization headers](/docs/guides/functions/auth-headers). + +## Secure your function + +Each of the following sections covers one mode, then how to combine modes and shape your own error response. Every example wraps the handler in `withSupabase` and reads its Supabase client from `ctx`. + +### Authenticated user calls When a signed-in user calls a function, the request carries the user's session JWT on the `Authorization` header. Your app usually makes that call through `supabase.functions.invoke`. The default is `verify_jwt = true`. The platform validates the JWT before your handler runs. Use `auth: 'user'` to get a `ctx.supabase` scoped to the caller's Row Level Security (RLS) policies. @@ -40,7 +50,7 @@ export default { } ``` -## Service-to-service calls +### Service-to-service calls Cron jobs, workers, `pg_net`, and other Edge Functions make calls with a secret key on the `apikey` header rather than a user JWT. Disable `verify_jwt` and use `auth: 'secret'`. The wrapper validates the key against any secret key in your [project's API keys](/dashboard/project/_/settings/api-keys), and gives your handler `ctx.supabaseAdmin` for privileged work. @@ -63,7 +73,7 @@ To accept only one specific key, use `auth: 'secret:'`. For example, `auth -## Public functions +### Public functions For a genuinely public function, such as a health check, use `auth: 'none'` with `verify_jwt = false` so anonymous callers can reach the handler. @@ -85,7 +95,7 @@ export default { `auth: 'none'` accepts every caller. For a function that authenticates callers itself, see the [External webhooks](#external-webhooks) section of this page. -## External webhooks +### External webhooks External providers such as Stripe or GitHub don't send Supabase credentials. They sign the request body with their own shared secret. Use `auth: 'none'` to skip the wrapper's credential check, then verify the provider's signature inside the handler. Keep `verify_jwt = false`. @@ -131,7 +141,7 @@ export default { -## Combining modes +### Combining modes Functions that answer both users and internal callers take an array on `auth`. The wrapper tries each mode in order and uses the first one that matches. `ctx.authMode` tells you which mode matched. @@ -151,7 +161,7 @@ export default { } ``` -## Custom error responses +### Custom error responses To shape the 401 response yourself, use `createSupabaseContext` instead of `withSupabase`. It returns a `{ data, error }` tuple instead of rejecting the request for you.