Definable uses Stytch as its authentication provider. JWT tokens are issued by Stytch and validated locally using JWKS (JSON Web Key Set). For detailed information about the Stytch integration, see the Stytch Integration guide.
What are JWTs?
JSON Web Tokens are an open standard (RFC 7519) for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. In Definable, JWTs are used to:- Authenticate users after login
- Maintain session state without server-side storage
- Pass user identity information securely between services
JWT Structure
JWTs consist of three parts separated by dots:Header
Contains the token type and signing algorithm:Definable uses RS256 (asymmetric encryption) via Stytch, not HS256. RS256 uses public/private key pairs for enhanced security.
Payload
Contains the claims or user data:sub(subject): Stytch user IDaud(audience): Stytch project IDiss(issuer): Stytch project identifierexp(expiration): Token expiration timestampiat(issued at): Token creation timestamp
Signature
Ensures the token hasnβt been tampered with using RS256 asymmetric encryption:Implementation in Definable
Token Generation
When a user logs in successfully via Stytch, the system receives a session JWT from Stytch:- Stytch user ID (
sub) - Stytch project ID (
aud) - Issuer information (
iss) - Expiration time (
exp) - default 24 hours - Issued at time (
iat) - No sensitive information like passwords
Definable also generates internal JWT tokens for API keys using
create_access_token() with HS256, but user session tokens come from Stytch and use RS256.Token Validation
Every protected endpoint uses theJWTBearer dependency for validation via Stytch JWKS:
- Extracts the token from the Authorization header
- Fetches Stytchβs public keys from JWKS endpoint (cached)
- Verifies the token signature using RS256 and Stytchβs public key
- Validates token claims (exp, iat, aud, sub, iss)
- Looks up the internal user using the
stytch_idfrom the token - Returns both the Stytch user ID and internal user ID
- Uses JWKS for public key retrieval (no shared secret)
- Validates against Stytch project ID (audience claim)
- Requires database lookup to map Stytch ID to internal user ID
- Supports both HTTP requests and WebSocket connections
Using JWT in Requests
Client applications must include the JWT in the Authorization header:JWT and RBAC Integration
JWTs work in conjunction with the Role-Based Access Control (RBAC) system:- The JWT establishes user identity
- The RBAC middleware uses this identity to determine:
- The userβs role in the requested organization
- Permissions associated with that role
- Whether the user can perform the requested action
JWT Configuration
Definableβs Stytch JWT implementation requires these environment variables:User session tokens come from Stytch and are validated via JWKS. The
JWT_SECRET is only used for internal API keys, not for user authentication.WebSocket Authentication
For WebSocket connections, JWTs are passed as query parameters:Security Considerations
Definableβs JWT implementation with Stytch follows these security best practices:- Asymmetric Encryption (RS256): More secure than symmetric HS256 - private key never leaves Stytch
- JWKS Key Rotation: Stytch can rotate keys without requiring code changes
- Public Key Caching: Keys cached for 10 minutes to balance security and performance
- Token Expiration: Stytch session tokens expire after 24 hours by default (configurable)
- No Sensitive Data: Tokens contain only user IDs and metadata, never passwords
- HTTPS Only: JWTs are only transmitted over encrypted connections
- Claim Validation: All required claims (exp, iat, aud, sub, iss) are verified
- Audience Validation: Ensures token was issued for your Stytch project
Troubleshooting
Invalid Token Error
Invalid Token Error
This usually means:
- The token has expired
- The token was signed with a different secret
- The token has been tampered with
Missing Authentication
Missing Authentication
Check that:
- The Authorization header is included
- The header uses the format
Bearer <token> - There are no extra spaces or characters
Token Expired
Token Expired
JWTs have a limited lifetime. When expired:
- The client needs to request a new token
- If using refresh tokens, use the refresh flow to get a new access token
Next Steps
- Stytch Integration: Detailed guide on Stytch integration and JWKS validation
- Authentication Overview: Learn about the complete authentication system
- Invitation Flow: How users join organizations via invitations
- Role-Based Access Control: Understanding permission management