2.6 KiB
The backend currently verifies Supabase JWTs using an HS256 shared secret (SUPABASE_JWT_SECRET). Supabase recommends migrating to asymmetric keys (RS256) for better security.\n\nInstead of storing a shared secret, the backend would fetch public keys from Supabase's JWKS endpoint (https://<project>.supabase.co/.well-known/jwks.json) and verify tokens against those.\n\n## Changes needed\n\n- [ ] Update backend/src/app/core/auth.py to fetch and cache JWKS public keys\n- [ ] Change jwt.decode from HS256 to RS256 with the fetched public key\n- [ ] Remove SUPABASE_JWT_SECRET from config, docker-compose, deploy workflow, and .env files\n- [ ] Update tests\n\n## References\n\n- https://supabase.com/docs/guides/auth/signing-keys\n- https://supabase.com/docs/guides/auth/jwts
status: completed type: task priority: low created_at: 2026-03-21T11:14:29Z updated_at: 2026-03-22T08:14:34Z
The backend currently verifies Supabase JWTs using an HS256 shared secret (SUPABASE_JWT_SECRET). Supabase recommends migrating to asymmetric keys (RS256) for better security.\n\nInstead of storing a shared secret, the backend would fetch public keys from Supabase's JWKS endpoint (https://<project>.supabase.co/.well-known/jwks.json) and verify tokens against those.\n\n## Changes needed\n\n- [x] Update backend/src/app/core/auth.py to fetch and cache JWKS public keys\n- [x] Change jwt.decode from HS256 to RS256 with the fetched public key\n- [x] Remove SUPABASE_JWT_SECRET from config, docker-compose, deploy workflow, and .env files\n- [x] Update tests\n\n## References\n\n- https://supabase.com/docs/guides/auth/signing-keys\n- https://supabase.com/docs/guides/auth/jwts
Summary of Changes
Migrated JWT verification from HS256 shared secret to RS256 asymmetric key verification using JWKS:
- auth.py: Added
PyJWKClientthat fetches and caches public keys from Supabase's JWKS endpoint (SUPABASE_URL/.well-known/jwks.json). Keys are cached for 1 hour. - config.py: Removed
supabase_jwt_secretsetting - pyproject.toml: Changed
PyJWTtoPyJWT[crypto]for RS256 support - docker-compose.yml: Configured local GoTrue for RS256 with mounted dev key
- docker-compose.prod.yml: Replaced
SUPABASE_JWT_SECRETwithSUPABASE_URL - deploy.yml: Updated to pass
SUPABASE_URLinstead ofSUPABASE_JWT_SECRET - tests: Updated to use mocked JWKS client with RSA key pairs
Stashed changes