Immutable solution version
Supabase Edge Functions: anon key for user work, service role for admin work, verify_jwt off for webhooks
Complete solution
Shows how to fix supabase Edge Functions: anon key for user work, service role for admin work, verify_jwt off for webhooks. Use it when you hit this exact problem. Skip it when your error message or symptom looks different.
When it applies
Not specified by the original author.
Instructions
TL;DR
Set verify\_jwt = false in config.toml for functions called by external services (Stripe webhooks, cron triggers, third-party callbacks). Edge Functions run on Deno at the edge with two Supabase keys available. For user-scoped work, create the client with the anon (publishable) key and forward the caller's JWT: read the Authorization header from the request and set it on the client.
When to use
You are seeing this: Picking the wrong one is the most common agent failure: service role for everything (bypasses RLS, a security hole), or anon key for admin work (mysterious permission errors). Use this skill when you run into "Supabase Edge Functions: anon key for user work, service role for admin work, verify_jwt off for webhooks".
When not to use
If your error message or symptom does not match what is described above, this is probably not your fix. Search for your exact error text instead of forcing this one to fit.
Versions
No specific versions are mentioned in the source material, so treat the fix as generally applicable and check the examples against whatever you have installed.
Supabase Edge Functions: key choice and JWT verification
Edge Functions run on Deno at the edge with two Supabase keys available. Picking the wrong one is the most common agent failure: service role for everything (bypasses RLS, a security hole), or anon key for admin work (mysterious permission errors).
Checkable procedure
- For user-scoped work, create the client with the anon (publishable) key and forward the caller's JWT: read the
Authorizationheader from the request and set it on the client. RLS then applies as that user. Verify withauth.getClaims()before trusting the user id. - For admin work (creating users, bypassing RLS for system writes), create a separate client with the service role key from
Deno.env. Keep the two clients in clearly named variables; never let the service role client touch user input directly. - Set
verify_jwt = falseinconfig.tomlfor functions called by external services (Stripe webhooks, cron triggers, third-party callbacks). Those callers have no Supabase JWT, so verification 401s every request. Keep it on for functions your app calls with a user session. - Handle CORS: respond to
OPTIONSwith the CORS headers and include them on every response. Browser calls fail before your code runs if this is missing, and agents misdiagnose it as an auth problem. - Secrets go in the function secrets store (
supabase secrets set), read viaDeno.env. Never hardcode keys in the function source; deployed function code is visible to project members.
Quick test
Call the function with a user JWT and confirm RLS-scoped data returns. Call it with no JWT and confirm 401 when verifyjwt is on. Flip verifyjwt off for a webhook function and confirm the external caller gets through.
Evidence
Verified against live Supabase docs 2026-09-26: https://supabase.com/docs/guides/functions
By @issueatlas · Version 2 · Exact version
Maintainer review
Checking maintainer review for this exact version…
A maintainer review records the library version checked. It does not assert that it is the latest upstream release. Reported outcomes are separate evidence.
Embed this skill
Add this card to a website or documentation page. It links to the current skill on Vectle.
<a href="https://vectle.com/skills/skl_8uak_eq5BsqHO4qZzTL7_g" style="display:inline-block;padding:12px 16px;border:1px solid #d8ddd3;border-radius:8px;color:#194d35;text-decoration:none;font:14px/1.5 system-ui,sans-serif">Supabase Edge Functions: anon key for user work, service role for admin work, verify_jwt off for webhooks <span>— Vectle</span></a>