Environment & Secrets
Required env vars and how to rotate them.
The library reads no env vars itself — you pass everything via NestAuthModule.forRoot({ ... }). But you'll typically source those values from env vars. Here's the recommended set.
.env.example
Generating JWT_SECRET
Or:
256 bits is the floor. Don't reuse the same secret across environments.
Loading order
If import './load-env' isn't the first import, process.env.JWT_SECRET is undefined when NestAuthModule initializes and signed tokens won't validate.
Rotation
Rotating JWT_SECRET invalidates every outstanding access token. Plan around that:
- Pre-deploy: cap
accessTokenValidityto a low value (5–15 min) so the blast radius is small. - Deploy with the new secret.
- Active users see one extra
/auth/refreshround trip on their next request — refresh tokens still work because they're stored server-side, not signed-only.
For zero-downtime rotation, support a secondary secret for verify-only:
(Implement via the session.jwt.validateToken hook if you need this — the library doesn't ship it out of the box.)
OAuth secret rotation
OAuth client secrets rotate on a different schedule per provider:
- Google — generate a new client secret, deploy alongside the old, then revoke the old after 15 min.
- Apple — keys (
p8) don't auto-expire, but the JWT used to authenticate to Apple's token endpoint expires every 6 months. The library refreshes it automatically; you only need to rotate when you actively want to. - Facebook / GitHub — generate-and-swap, same as Google.
Secrets manager integration
Don't keep .env in production. Pull secrets from:
- AWS Secrets Manager / SSM Parameter Store
- HashiCorp Vault
- 1Password / Doppler / Infisical
The pattern: in load-env.ts, fetch from the manager and stuff into process.env before the rest of the app boots.
What's safe to log
- Public URLs, app name, port — yes.
- Public OAuth client IDs — yes.
JWT_SECRET, OAuth client secrets,ADMIN_CONSOLE_SECRET, Resend/SendGrid/Twilio API keys — never.
Audit your error reporters (Sentry, Datadog, etc.) and confirm they redact env vars by default.
Per-environment defaults
| Var | Dev | Production |
|---|---|---|
synchronize (TypeORM) | true | false |
cookieOptions.secure | false (HTTP localhost) | true |
mfa.required | false | depends on policy |
audit.enabled | false | true |
debug.enabled | true | false (turn on per-area when debugging) |