Skip to Content
GuidesProduction checklist

Production checklist

The list to walk before flipping the DNS. Everything here matters at least a little; the bold items are the ones we’ve seen actually break a launch.

If you have read this page and verified each item, your Synq integration is production-ready by every standard Synq itself holds to. The reasoning behind each item is given in one line; the deep dive is linked.

Identity & sign-in

  • OIDC client credentials are not committed to source. SYNQ_CLIENT_SECRET lives in a secret manager (Vercel env, AWS Secrets Manager, Doppler, etc.), never .env.production checked into git.
  • SESSION_SECRET is at least 32 characters. Generate with openssl rand -base64 32. Rotate per Rotate everything.
  • Redirect URI is registered with the exact production host including scheme. https://app.example.com/api/auth/callback, not http://, not a wildcard, not the preview URL.
  • All BYO OAuth credentials are real production credentials. The dev / staging / prod Google project is not the same project. Google flags shared OAuth clients across environments and may throttle.
  • Apple Sign-In’s .p8 key is uploaded to Synq. Apple invalidates the JWT-as-client-secret if the key file goes missing — sign-ins start failing silently 24 hours later.
  • Session cookie Secure flag is on. Synq sets this by default; verify your reverse proxy isn’t stripping it.

Tokens & authorization

  • Every backend that accepts a Synq access token verifies the signature against the JWKS endpoint — not just the iss / aud claims by themselves. Use the JWT claims reference to map every claim you care about.
  • JWKS cache TTL is no longer than 24 hours. Synq rotates signing keys; a stale cache will fail verification.
  • aud is verified against the brand slug for access tokens and the client_id for ID tokens. The two audiences are deliberately different — don’t accept them interchangeably.
  • requireAccess(predicate) is at every protected route. No route that returns user-specific data relies solely on the proxy-level cookie check.
  • Server Actions and Route Handlers each verify the session. Per the Next.js auth guide , proxy.ts is not your authorization boundary.

Webhooks

  • Webhook endpoint is HTTPS only. Synq refuses to deliver to http:// in production.
  • Synq-Signature is verified with the per-endpoint secret on every delivery. Use verifyWebhookSignature from @synqid/js — do not roll your own HMAC.
  • Endpoint returns 2xx within 10 seconds. If processing takes longer, enqueue and ack. Synq’s retry policy is exponential backoff with auto-disable after 10 consecutive non-2xx responses.
  • Idempotency: deduplicate on the Synq-Delivery header. Retries reuse the delivery ID so you can safely no-op duplicates.
  • Auto-disable alerting is wired up. If your endpoint gets auto-disabled, you need to know within minutes — not when a user reports they didn’t get their welcome email.

Operational

  • At least two team members have access to the Synq dashboard. Single-bus-factor accounts have caused real outages. Add a backup admin.
  • Rate-limit headroom is monitored. The error reference lists the headers; alert on >80% usage so you have time to react.
  • Audit log is being consumed somewhere. A SIEM, a Slack channel, a quarterly review — pick one. The log existing isn’t the same as someone reading it.
  • Custom domain has cert renewal alerting. Synq’s cert-manager is robust but the DNS pre-condition (CNAME) lives on your side and can drift.
  • Secret rotation cadence is documented. Even if “rotate once a year” — write it down. See Rotate everything.

Resilience

  • Sign-in failures degrade gracefully. If Synq’s /userinfo returns 500, your getUser() returns null and the user sees a logged-out experience — not a 500 page.
  • Webhook ingest tolerates Synq being down. A failed Synq → webhook delivery should not surface as an error in your app. Synq’s retry covers it.
  • Iron-session cookie size is under the 4 KB budget. If you add custom claims to the user object that get stuffed into the session cookie, watch the size. Browsers reject oversized cookies silently.
  • The proxy matches /api/auth as public. If a misconfigured matcher excludes it, sign-in deadlocks.

Compliance / privacy

  • You have a DPA on file with Synq if your tenant requires one. Email legal@synq.id — turnaround is one business day.
  • Personal data fields are minimized in your custom claims. The JWT is sent to your backend on every request; it’s logged by your edge / CDN / observability platform. Don’t put a passport number in there.
  • prefer_username and email are scoped to the consent the user agreed to. Verify what the user consented to in Scopes and consent.
  • Account-delete webhooks are handled. When a user deletes their Synq account, your user.deleted handler should delete or anonymize their data in your DB within 30 days.

Performance

  • verifySession() is called inside server components, not client components. Server primitives are cached per-render (React.cache()); client-side fetches are not.
  • useUser() is seeded from a server getUser() in the root layout. Don’t fetch the user from the client on first render.
  • proxy.ts does not call any network endpoint. The proxy runs on every navigation and every prefetch — see the Next.js auth guide . Cookie presence only.
  • JWKS responses are cached. openid-client does this for you when you use @synqid/nextjs/handlers; if you’re verifying tokens in a non-Next backend, configure your verifier’s cache.

Browser & mobile clients

  • @synqid/react-native SecureStore is enabled. Default is AsyncStorage which is plaintext on disk on Android.
  • Deep link routing handles the /oauth/callback path on mobile. expo-linking config has it; verify the prefix and scheme match what’s registered with Synq.
  • CORS allowlist on your API includes the production app URL and only the production app URL. No *, no preview URL in production.

Final smoke test

After everything above is checked, run a clean-cookie sign-in flow end to end on production:

  1. Open the production app in an incognito window.
  2. Click “Sign in” → land on the Synq hosted login.
  3. Sign in via your most-used provider (Google for most teams).
  4. Land back on the app, signed in, with the correct user shown.
  5. Refresh the page — still signed in.
  6. Open dev tools → inspect the session cookie; verify name + Secure + HttpOnly + SameSite=Lax.
  7. Sign out via your sign-out flow.
  8. Re-open in incognito; sign in via a different provider (Apple, Discord, etc.) — verify the same sub is linked or that the flow correctly handles a different sub per your account-linking policy.

If steps 1–8 all pass, you’re production-ready.


Found something missing on this list? Email support@synq.id — we add to it after every incident, public or internal.

Last updated on