Rotating API keys and the JWT secret
SupaHost projects use legacy anon and service_role keys, and key or JWT secret rotation isn't available in the dashboard. What that means, and what to do if a service_role key leaks.
Rotation isn't available in the SupaHost dashboard. Each project has one JWT secret and two keys signed with it, anon and service_role, and there's no button or API to replace them. If your service_role key has leaked, email [email protected] straight away with the project name, and follow the containment steps below while you wait.
How keys work on SupaHost
- Each project gets its own JWT secret when it's created. The
anonandservice_rolekeys are HS256 JWTs signed with it, valid for ten years. - There are no publishable (
sb_publishable_...) or secret (sb_secret_...) keys, and no signing-key rotation. - Users' access tokens are signed with the same secret, so changing it would sign every user out and invalidate both keys at once.
- You'll find both keys under Dashboard → your project → Connect → App. Only the instance owner can reveal
service_role.
Branches and new projects get their own secret and keys, so a key from one project never works on another.
If the anon key is exposed
That's expected. The anon key is meant to be public: it ships in every web and mobile app. It only gives the access your Row Level Security policies allow for the anon and authenticated roles. You don't need to rotate it. Check your policies instead:
-- Tables in public without RLS: anyone with the anon key can read and write them
select tablename from pg_tables
where schemaname = 'public' and not rowsecurity;
If the service_role key leaks
The service_role key bypasses RLS and can use the Auth admin API, so treat a leak as urgent.
Contact support. Email [email protected] with the project name, when and where the key was exposed, and whether you've seen misuse.
Remove it from where it leaked. Delete it from the client bundle, repository, logs or screenshot, and take down the affected build. If it was pushed to Git, deleting the file isn't enough, because it's still in the history. Treat it as known to others.
Stop shipping it. Search your codebase and environment settings for the key and make sure it's only in server-side variables.
Look for misuse. Check for unexpected users and recent changes:
select id, email, created_at, last_sign_in_at from auth.users order by created_at desc limit 50;Review recent rows in your important tables, and your Storage buckets. If data was changed, the Backups tab can restore the project's database from a daily backup, or to a point in time on plans with point-in-time recovery. Storage files aren't part of database backups.
Rotate secrets stored next to it. If the key leaked with other values (Stripe keys, email provider keys, Edge Function secrets), rotate those with their providers and update them on the Functions tab's Secrets card.
Prevent the next leak
- Keep
service_rolein server environment variables only: neverNEXT_PUBLIC_,VITE_or anything bundled for the browser or a mobile app. - In Edge Functions, use the injected
SUPABASE_SERVICE_ROLE_KEYinstead of pasting the key into code. - Add a secret scanner to your repository so a pushed key is caught early.