GroviaDocs

Security checklist

What is already enforced, and what you must do before going live.

Before launch

  • JWT_SECRET is a fresh openssl rand -base64 32 — not the one from any example, demo or repository
  • .env is not committed, or the repository is private, or production values live only in the host's settings
  • The Atlas database user has a strong password and the IP allowlist is not 0.0.0.0/0
  • /setup has been completed — no unclaimed-administrator window is open
  • CLIENT_URL and ADMIN_URL are the exact production origins (the CORS allowlist is strict)
  • OAuth callback URLs point only at your production API
  • Stripe is on live keys and the webhook secret matches the live endpoint
  • The preview demo account, if you keep one, has a password nobody would guess
  • NODE_ENV=production on the API

Already enforced in code

  • Every write endpoint chains protect → role gate → preventReadOnlyActions.
  • Signups cannot choose a role; the body's role is never read.
  • The JWT never reaches client JavaScript — httpOnly, SameSite=Lax cookie only.
  • ?next= and Referer redirects are reduced to same-origin paths — no open redirect.
  • Order prices come from the catalogue; client prices and totals are ignored. Stock is reduced atomically.
  • Stripe webhooks are signature-verified over the raw body.
  • OAuth runs on the API with signed state and PKCE; Google ID tokens are verified against Google's JWKS — issuer, audience, email_verified.
  • Uploads are authenticated and scoped under your media root folder; the cleanup and bulk-delete tools are admin-only.
  • Passwords are stored only as bcrypt hashes; new email sign-ups verify their address before they can order.
  • Helmet, rate limiting, express-mongo-sanitize and hpp are on. Auth middleware never logs headers.

The full record of what was audited and fixed is in apps/api/SECURITY-AUDIT.md.

Known limits

  • No refresh-token rotation — a 30-day access token is the whole session. Revoking a role takes effect on the next request because protect reloads the user, but a stolen token is valid until expiry.
  • Social providers you have not configured stay hidden — there is no half-working button.
Buy GroviaFull source code$99.99