fix(api): stable JWT_SECRET signing so restarts don't invalidate sessions #4065
ccantynzcommented Jun 12, 2026
Originally written by @vercel[bot] on GitHub.
The latest updates on your projects. Learn more about Vercel for GitHub.
| Project | Deployment | Actions | Updated (UTC) |
|---|---|---|---|
| alec-rae-com-admin | Preview, Comment | Jun 12, 2026 8:03am |
ccantynzcommented Jun 12, 2026
Originally written by @vercel[bot] on GitHub.
Deployment failed with the following error:
There is no GitHub account connected to this Vercel account.Cross-repo impact
See what breaks downstream if this PR merges.
⮌ Merged
This pull request was merged into main.
c comment · e edit title · m merge · a approve · r request changes · ? shortcuts
Originally written by @ccantynz-alt on GitHub.
Imported from https://github.com/ccantynz-alt/AlecRae.com/pull/66
Symptom
After logging in, an API call returns "Invalid or expired bearer token" — especially right after an
alecrae-apirestart/deploy.Root cause
jwt.tsresolved signing keys as: provided RS256 keypair → ephemeral RS256 generated at boot → HS256 fromJWT_SECRET(last resort). On Bun, ephemeral RS256 generation always succeeds, so:JWT_SECRET(which production has, for the OAuth state signer) never actually took effect for token signing.Fix
Reorder key resolution so a stable secret wins over ephemeral keys:
JWT_PRIVATE_KEY+JWT_PUBLIC_KEY)JWT_SECRET← deployed APIs land here; tokens now survive restartsNo JWKS endpoint exists (the API verifies its own tokens), so symmetric HS256 is safe. Avoids wrestling multiline RS256 PEMs into systemd
EnvironmentFile.Verify after deploy
bun run typecheck(api) ✅. After deploy: log in, restartalecrae-api, confirm the existing session still works (previously it broke). Boot log shows[jwt] Using HS256 with JWT_SECRET (stable across restarts).Follow-up (not in this PR)
Access tokens are 15 min; the Google sign-in flow doesn't persist a refresh token, so there's no silent re-auth — a separate fix for session longevity.
https://claude.ai/code/session_01McgJLnTbZG9mwhfwd5iAX3
Generated by Claude Code