Production Safety
RLS, grants, checkout claims, webhook idempotency, cron auth, outbox workers, request ids, and retention jobs are the production guardrails to preserve.
On this page
Implementation reference5 areas
These Product code locations explain how the documented behavior is implemented. Expand them when you are ready to customize or maintain this area.
Database security baseline
The baseline migration owns grants, RLS enablement, policies, RPC functions, and service-role privileges for the Supabase schema.
supabase/migrations/20260426000000_init.sql
Webhook request guard
Webhook utilities centralize rate limiting, raw body reading, payload size limits, structured logging, and request id context.
src/lib/security/webhooks/request.tssrc/lib/security/webhooks/processing.ts
Cron guard
Cron services reject missing or placeholder secrets, compare authorization safely, rate-limit scheduler calls, and log job outcomes.
src/lib/security/secrets/cron-secret.tssrc/features/notifications/server/outbox/services/cron.ts
Outbox and retention operations
Background workers claim batches, retry safely, dead-letter exhausted work, and run retention cleanup behind protected cron routes.
src/features/notifications/server/outbox/services/worker.tssrc/features/compliance/server/retention/service.ts
Supabase server boundaries
Server helpers keep user-scoped Supabase access separate from service-role work; proxy route policy avoids unnecessary fresh-user round trips while preserving request context.
src/lib/supabase/server.tssrc/lib/supabase/proxy.tssrc/lib/request-proxy/route-policy.ts
Reference paths are relative to the Shipflash-Product checkout.
Production safety flow
- 1
Define durable database invariants
Create tables, constraints, grants, RLS policies, RPC functions, and service-role access in migrations instead of relying on runtime assumptions.
Relevant Product code
supabase/migrations/20260426000000_init.sql
- 2
Preserve request context
Browser requests receive request context through the proxy, while excluded webhook and scheduled routes establish and return their own request ids.
Relevant Product code
src/proxy.tssrc/lib/observe/request/request-id.tssrc/app/api/notifications/webhooks/resend/route.ts
- 3
Claim before processing external events
Webhook handlers verify signatures, store event rows, reject duplicate processed events, and reclaim only stale processing leases.
Relevant Product code
src/lib/security/webhooks/request.tssrc/lib/security/webhooks/processing.ts
- 4
Reserve a single-purchase checkout
Attempt-scoped checkout claims reserve a profile and plan before opening a provider session, then prevent stale or duplicate attempts from overwriting newer checkout state.
Relevant Product code
src/features/billing/server/checkout/persistence/claims.tssupabase/migrations/20260426000000_init.sql
- 5
Protect scheduled work
Cron services validate CRON_SECRET, reject placeholder values, compare authorization without leaking timing, and rate-limit scheduler calls.
Relevant Product code
src/lib/security/secrets/cron-secret.tssrc/features/notifications/server/outbox/services/cron.ts
- 6
Retry through outbox state
Workers claim a bounded batch, record success or failure, back off transient errors, and dead-letter rows after repeated failures.
Relevant Product code
src/features/notifications/server/outbox/services/worker.ts
Cron secrets fail closed
Use this example as a starting point, then adapt it to your product's rules and configuration.
A configured but obvious placeholder secret is treated the same as a missing secret.
export function readValidatedCronSecret(value: string | undefined = process.env.CRON_SECRET): string | null {
const secret = value?.trim();
if (!secret) {
return null;
}
if (PLACEHOLDER_CRON_SECRETS.has(secret.toLowerCase())) {
return null;
}
return secret;
}Source reference
src/lib/security/secrets/cron-secret.ts
Webhook stale lease
Use this example as a starting point, then adapt it to your product's rules and configuration.
A processing row can be retried only after the lease timeout, which protects against duplicate live workers and crashed workers.
const WEBHOOK_PROCESSING_STALE_AFTER_MS = 15 * 60 * 1000;
export function isWebhookProcessingStale(
processingStartedAt: string | null | undefined,
nowMs: number = Date.now(),
staleAfterMs: number = WEBHOOK_PROCESSING_STALE_AFTER_MS,
): boolean {
if (!processingStartedAt) {
return true;
}
const startedAtMs = Date.parse(processingStartedAt);
if (!Number.isFinite(startedAtMs)) {
return true;
}
return nowMs - startedAtMs >= staleAfterMs;
}Source reference
src/lib/security/webhooks/processing.ts
Recipe: add a production-safe table
Add a Supabase table that works in production without accidental public access, broken generated types, or missing operational docs.
Implementation locations
Inspect
- supabase/migrations/20260426000000_init.sql
- src/lib/supabase/server.ts
- src/lib/supabase/proxy.ts
Edit
- supabase/migrations/<timestamp>_<change>.sql
- src/lib/supabase/types.ts
- src/features/<domain>/server/persistence/<table>.ts
Steps
- Create the table, indexes, foreign keys, and durable constraints in a migration.
- Enable RLS and write policies before exposing user-scoped reads or writes.
- Grant only the roles that need access, and keep service-role writes server-only.
- Regenerate Supabase types and route all access through feature-owned persistence helpers.
- Document any env vars, cron routes, webhooks, or retention behavior introduced by the table.
Verify
- pnpm run contract:migrations
- pnpm run supabase:types
- pnpm run test:features
- pnpm run quality
Common mistakes
- Do not add a table without RLS decisions.
- Do not put service-role reads in client-reachable code.
- Do not skip generated type refresh after schema changes.
AI prompt: production safety review
Review this change for production safety. Inspect migrations, RLS, grants, webhook/event idempotency, cron authentication, outbox retry behavior, request id logging, generated Supabase types, tests, and deployment checklist impact. Fail closed on auth, billing, admin, webhook, and cron boundaries.Inspect first
supabase/migrations/20260426000000_init.sqlsrc/lib/security/webhooks/request.tssrc/lib/security/secrets/cron-secret.ts
Verify
- pnpm run contract:migrations
- pnpm run test:features
- pnpm run quality