This guide will help you migrate from v1.x to v2.x, which introduces support for Supabase's new JWT signing keys.
Supabase has introduced a major security improvement by moving from symmetric to asymmetric JWT (JSON Web Token) signing. This change brings security and performance improvements in how your applications handle authentication.
Previously, Supabase used a single shared secret key for both creating and verifying tokens. This meant your app had to constantly call supabase.auth.getUser() to check if sessions were valid, creating network delays calling the Supabase Auth server.
The new system uses two separate keys:
Your application can now verify user sessions locally without contacting Supabase servers, making it faster and more reliable. This new key is named as publishable key on Supabase.
This upgrade eliminates authentication bottlenecks, improves security, and makes your applications work better at the edge (no extra calls to the Supabase Auth server).
useSupabaseUser Type ChangesuseSupabaseUser now returns JWT claims instead of the full User object.
useSupabaseUser returned the full User object from auth.getUser()useSupabaseUser returns Claims object from auth.getClaims() as a JWT Payload{
id: "11111111-1111-1111-1111-111111111111",
aud: "authenticated",
role: "authenticated",
email: "example@email.com",
email_confirmed_at: "2024-01-01T00:00:00Z",
phone: "",
confirmed_at: "2024-01-01T00:00:00Z",
last_sign_in_at: "2024-01-01T00:00:00Z",
app_metadata: {},
user_metadata: {},
identities: []
}
{
session_id: "11111111-1111-1111-1111-111111111111",
sub: "11111111-1111-1111-1111-111111111111",
aud: "authenticated",
role: "authenticated",
email: "example@email.com",
aal: "aal1",
amr: [],
exp: 1715769600,
iat: 1715766000,
is_anonymous: false,
iss: "https://project-id.supabase.co/auth/v1",
phone: "+13334445555",
app_metadata: {},
user_metadata: {},
// identities is missing
// last_sign_in_at is missing
// confirmed_at is missing
// email_confirmed_at is missing
}
auth.getUser() but if you only need basic info (email, role...) no changes are required.Remaining key → SUPABASE_KEY is now storing the publishable key instead of the anon key
New key → SUPABASE_SECRET_KEY is now storing the secret key of your Supabase project
Deprecated key → SUPABASE_SERVICE_KEY was previously storing the service_role key but is now deprecated in favor of SUPABASE_SECRET_KEY
The first thing you need to do is to ensure the useSupabaseUser changes do not affect your existing code.
The Good news ☀️ is that everything will continue to work as-is with your existing SUPABASE_KEY (aka anon key).
Same for SUPABASE_SERVICE_KEY, if you're using it to bypass Row Level Security, you will face a deprecation warning but it will still work.
SUPABASE_KEY and your secret key as SUPABASE_SECRET_KEY.Before migrating your environment variables, you need to enable JWT signing keys and thus create your JWT and API keys in your Supabase project:
.env fileSUPABASE_KEY=<your_publishable_key>
SUPABASE_SECRET_KEY=<your_secret_key>