HOW TO USE JWT SECRET
I'm in a world of config hell.
I have lost 3 days straight to trying to figure this out.
My code is failing having introduced Supabase RLS policy that depends on clerk auth for jwt tokens.
My Supabase JWT token is verified in the logs as correctly transposed into clerk. I think the reason for failure might be the hyphens in Current key in JWT Signing Keys. Chat GPT thinks thats why it's failing:
Your own logs show this smoking gun:
SUPABASE_JWT_SECRET length: 36 → that’s a KID/UUID, not the HS256 shared secret.
Tokens signed with a KID will always fail with JWSError JWSInvalidSignature.
there is no optin to generate a key without hyphens.
Supabase support comes with a disclaimer saying they are over capaacity with support requests.
Chat GPT says:
There are only two ways forward:
Use the real HS256 secret
In Supabase JWT Signing Keys, create a new HS256 standby key → copy the Shared secret it shows (this is a long, random string, not 36 chars) → promote it to current.
Put that exact shared secret in:
SUPABASE_JWT_SECRET (Vercel + your .env used at runtime)
Clerk → JWT template (supabase-prod) → Custom signing key
Redeploy and re-run your ping. The length you log should not be 36 anymore.
If you’ve already done (1) and still see 401s
Send Supabase support the sb-request-id from your response headers (you logged one), saying: “gateway rejecting tokens signed with the dashboard’s current HS256 secret.” That indicates a key-sync issue on their side.
has anyone figured out how to move from Legacy JWT Secret to JWT Signing Keys?
I have lost 3 days straight to trying to figure this out.
My code is failing having introduced Supabase RLS policy that depends on clerk auth for jwt tokens.
My Supabase JWT token is verified in the logs as correctly transposed into clerk. I think the reason for failure might be the hyphens in Current key in JWT Signing Keys. Chat GPT thinks thats why it's failing:
Your own logs show this smoking gun:
SUPABASE_JWT_SECRET length: 36 → that’s a KID/UUID, not the HS256 shared secret.
Tokens signed with a KID will always fail with JWSError JWSInvalidSignature.
there is no optin to generate a key without hyphens.
Supabase support comes with a disclaimer saying they are over capaacity with support requests.
Chat GPT says:
There are only two ways forward:
Use the real HS256 secret
In Supabase JWT Signing Keys, create a new HS256 standby key → copy the Shared secret it shows (this is a long, random string, not 36 chars) → promote it to current.
Put that exact shared secret in:
SUPABASE_JWT_SECRET (Vercel + your .env used at runtime)
Clerk → JWT template (supabase-prod) → Custom signing key
Redeploy and re-run your ping. The length you log should not be 36 anymore.
If you’ve already done (1) and still see 401s
Send Supabase support the sb-request-id from your response headers (you logged one), saying: “gateway rejecting tokens signed with the dashboard’s current HS256 secret.” That indicates a key-sync issue on their side.
has anyone figured out how to move from Legacy JWT Secret to JWT Signing Keys?
Your runtime log shows SUPABASE_JWT_SECRET length: 36.
A 36-char string is a UUID/KID (the thing like b92xxxx) - this value has hyphens in it.
That is not the HS256 signing secret.
If you sign with the KID, Supabase will always return JWSError JWSInvalidSignature.