JWT Claims Reference
Complete reference for claims appearing in JWTs created by Supabase Auth
This page provides a comprehensive reference for all JWT claims used in Supabase authentication tokens. This information is essential for server-side JWT validation and serialization, especially when implementing authentication in languages like Rust where field names like ref are reserved keywords.
JWT structure overview#
Supabase JWTs follow the standard JWT structure with three parts:
- Header: Contains algorithm and key information
- Payload: Contains the claims (user data and metadata)
- Signature: Cryptographic signature for verification
The payload contains various claims that provide user identity, authentication level, and authorization information.
Required claims#
These claims are always present in Supabase JWTs and cannot be removed:
Optional claims#
These claims may be present depending on the authentication context:
Special claims#
Field value constraints#
Authenticator assurance level (aal)#
Role values (role)#
Audience values (aud)#
Authentication methods (amr.method)#
JWT examples#
Authenticated user token#
1{2 "aal": "aal1",3 "amr": [4 {5 "method": "password",6 "timestamp": 16409916007 }8 ],9 "app_metadata": {10 "provider": "email",11 "providers": ["email"]12 },13 "aud": "authenticated",14 "email": "user@example.com",15 "exp": 1640995200,16 "iat": 1640991600,17 "iss": "https://abcdefghijklmnopqrst.supabase.co/auth/v1",18 "phone": "",19 "role": "authenticated",20 "session_id": "123e4567-e89b-12d3-a456-426614174000",21 "sub": "123e4567-e89b-12d3-a456-426614174000",22 "user_metadata": {23 "name": "John Doe"24 },25 "is_anonymous": false26}Anonymous user token#
1{2 "iss": "supabase",3 "ref": "abcdefghijklmnopqrst",4 "role": "anon",5 "iat": 1640991600,6 "exp": 16409952007}Service role token#
1{2 "iss": "supabase",3 "ref": "abcdefghijklmnopqrst",4 "role": "service_role",5 "iat": 1640991600,6 "exp": 16409952007}Language-Specific considerations#
Rust#
In Rust, the ref field is a reserved keyword. When deserializing JWTs, you'll need to handle this:
1use serde::{Deserialize, Serialize};23#[derive(Debug, Deserialize, Serialize)]4struct JwtClaims {5 iss: String,6 #[serde(rename = "ref")] // Handle reserved keyword7 project_ref: Option<String>,8 role: String,9 iat: i64,10 exp: i64,11 // ... other claims12}TypeScript/JavaScript#
1interface {2 : string3 : string | string[]4 : number5 : number6 : string7 : string8 : 'aal1' | 'aal2'9 : string10 : string11 : string12 : boolean13 ?: string14 ?: number15 ?: <string, any>16 ?: <string, any>17 ?: <{18 : string19 : number20 }>21 ?: string // Only in anon/service role tokens22}Python#
1from typing import Optional, Union, List, Dict, Any2from dataclasses import dataclass34@dataclass5class AmrEntry:6 method: str7 timestamp: int89@dataclass10class JwtClaims:11 iss: str12 aud: Union[str, List[str]]13 exp: int14 iat: int15 sub: str16 role: str17 aal: str18 session_id: str19 email: str20 phone: str21 is_anonymous: bool22 jti: Optional[str] = None23 nbf: Optional[int] = None24 app_metadata: Optional[Dict[str, Any]] = None25 user_metadata: Optional[Dict[str, Any]] = None26 amr: Optional[List[AmrEntry]] = None27 ref: Optional[str] = None # Only in anon/service role tokensGo#
1type AmrEntry struct {2 Method string `json:"method"`3 Timestamp int64 `json:"timestamp"`4}56type JwtClaims struct {7 Iss string `json:"iss"`8 Aud interface{} `json:"aud"` // string or []string9 Exp int64 `json:"exp"`10 Iat int64 `json:"iat"`11 Sub string `json:"sub"`12 Role string `json:"role"`13 Aal string `json:"aal"`14 SessionID string `json:"session_id"`15 Email string `json:"email"`16 Phone string `json:"phone"`17 IsAnonymous bool `json:"is_anonymous"`18 Jti *string `json:"jti,omitempty"`19 Nbf *int64 `json:"nbf,omitempty"`20 AppMetadata map[string]interface{} `json:"app_metadata,omitempty"`21 UserMetadata map[string]interface{} `json:"user_metadata,omitempty"`22 Amr []AmrEntry `json:"amr,omitempty"`23 Ref *string `json:"ref,omitempty"` // Only in anon/service role tokens24}Validation guidelines#
When implementing JWT validation on your server:
- Check Required Fields: Ensure all required claims are present
- Validate Types: Verify field types match expected types
- Check Expiration: Validate
exptimestamp is in the future - Verify Issuer: Ensure
issmatches your Supabase project - Check Audience: Validate
audmatches expected audience - Handle Reserved Keywords: Use field renaming for languages like Rust
Security considerations#
- Always validate the JWT signature before trusting any claims
- Never expose service role tokens to client-side code
- Validate all claims before trusting the JWT
- Check token expiration on every request
- Use HTTPS for all JWT transmission
- Rotate JWT secrets regularly
- Implement proper error handling for invalid tokens