What is JWKS?
JWKS is defined in RFC 7517 as a JSON structure representing a set of cryptographic keys. It allows your backend to fetch public keys dynamically without requiring shared secrets or manual key distribution.JWKS Endpoint
Better Auth exposes public keys at:Example JWKS Response
Key Fields
| Field | Description |
|---|---|
kty | Key type (OKP for Edwards-curve, RSA for RSA) |
use | Intended use (sig for signature verification) |
kid | Key ID (used to match against JWT header) |
alg | Algorithm (EdDSA for Ed25519, RS256 for RSA) |
crv | Curve name (for elliptic curve keys like Ed25519) |
x | Public key (base64url encoded) |
Better Auth uses Ed25519 by default, which is a modern, fast, and secure elliptic curve signature algorithm. It provides better security than RSA-2048 with smaller key sizes.
How JWT Verification Works
When your backend receives a JWT, it follows these steps to verify it:Extract the Key ID
The JWT header contains a
kid (Key ID) field that identifies which key was used to sign the token.Verify Signature
Use the public key to verify the JWT signature. If verification succeeds, the token is authentic and hasn’t been tampered with.
Database Storage
Better Auth stores JWKS keys in the database in thejwks table:
Key Rotation
Key rotation is an important security practice that limits the impact of a compromised signing key. Better Auth supports automatic key rotation.How Key Rotation Works
Both Keys Active
The new key is added to the JWKS endpoint alongside the old key. New JWTs are signed with the new key, but the old key remains valid for verification.
Why Key Rotation Matters
Limit Exposure
If a key is compromised, rotation limits the window of vulnerability.
Zero Downtime
Your backend doesn’t need to be updated. It automatically picks up new keys from the JWKS endpoint.
Compliance
Many security standards (PCI-DSS, HIPAA) require periodic key rotation.
Defense in Depth
Regular rotation is a best practice that adds an extra layer of security.
Caching Strategies
Fetching JWKS keys on every request is inefficient and can introduce latency. Implement smart caching:Time-Based Caching
Cache JWKS keys with a reasonable TTL (e.g., 1 hour):Error-Based Refresh
If verification fails with “unknown key ID”, refresh the JWKS cache:Library-Based Caching
Most JWKS libraries implement caching automatically:Testing JWKS Verification
You can test the JWKS endpoint using curl:Common Issues
”Invalid signature” errors
Cause: Using wrong JWKS URL
Cause: Using wrong JWKS URL
Ensure your backend is fetching keys from the correct Better Auth URL. Check that
BETTER_AUTH_URL matches your auth server.Cause: Issuer/Audience mismatch
Cause: Issuer/Audience mismatch
Ensure your
iss and aud validation matches the BETTER_AUTH_URL:Cause: Stale key cache after rotation
Cause: Stale key cache after rotation
If keys have rotated, clear your JWKS cache or wait for it to expire. Most libraries handle this automatically.
”Token expired” errors
JWTs have a limited lifetime (default 1 hour). Ensure your frontend refreshes tokens before they expire:Next Steps
Go Implementation
Complete Go backend example with JWKS verification
Python Implementation
Flask backend with PyJWT and JWKS middleware
Express Implementation
Express.js backend with jose library