SecureStartKit is the Next.js + Supabase template for B2B back-office tools, admin panels, and partner portals where multiple organizations share one database without ever seeing each other's data.
Internal tools start as small dashboards used by one team. They grow into shared platforms used by partners, contractors, and customers' customers. The architectural mistake is treating them as single-tenant until the first cross-tenant leak forces a rewrite. The fix is to ship with multi-tenancy and RBAC wired in from the first commit, even when there is only one tenant.
SecureStartKit treats every isolated table as tenant-scoped by default. Adding the second tenant is a configuration change, not an architectural migration.
Each pattern below makes a class of cross-tenant or privilege-escalation bugs structurally impossible. The constraints are at the database layer, so the application code cannot bypass them.
A Custom Access Token Hook injects tenant_id and role into every issued JWT. RLS policies on every isolated table read those claims directly. Adding a tenant_id check inside controller code is the path to one missing branch and a cross-tenant leak; doing it at the database is the path to architectural correctness.
Multi-tenancy + RBAC pattern →Role lives in the JWT as well. Restrictive RLS policies on sensitive tables AND together: the row passes only if the user belongs to the tenant AND has the required role. The application layer reads the same claim via getClaims for fast-path checks before the database query runs.
JWT + session management →Admin operations require AAL2 (a verified second factor for the current session). The check happens twice: in the Server Action via getClaims, and at the database via restrictive RLS policies that require auth.jwt() to carry an aal2 claim. A forgotten Server Action check fails closed because the database denies the row.
OAuth, magic links, MFA →Every admin-relevant Server Action writes an audit row before returning. Actor, target, action, timestamp, and outcome land in an append-only audit_log table. Sentry catches the unexpected errors that audit logs miss. Internal tools without audit trails are post-incident forensic dead ends.
Error handling + observability →Google Workspace and Microsoft Entra ID are the realistic SSO providers for internal-tool access. The OAuth callback ships with PKCE, redirect URL allowlist hardening, and validated next-parameter handling. No bespoke session code; the Supabase Auth surface handles the parts that go wrong most often.
Secure OAuth implementation →One purchase. Lifetime access. Cross-tenant leaks are denied at the database, not by hoping a code reviewer caught the missing clause.