Supabase Row Level Security guardrails — Hovvi
How Supabase bounds database exposure through a danger-level unprotected-table warning, deny-by-default RLS behavior, publishable versus secret key separation and a platform-enforced browser block on bypass credentials.
Published by Hovvi Research. Observed ; materially updated .
What happened
State the exposure cost of the unprotected default, flip auto-generated APIs to return nothing until explicit policies exist, split credentials into publicly exposable and full-bypass tiers, and enforce the elevated tier in the platform. Make the unsafe default explicit, start protected projects from zero access until policies exist, and separate publicly exposable credentials from full-access ones with platform-enforced limits.
Evidence
Every table starts one decision away from public read and write.
| State | Observed rule | Builder-visible consequence |
|---|---|---|
| Table without RLS in an exposed schema | Readable and writable by any role with a grant | Danger callout instructs enabling RLS on every exposed table |
| RLS enabled, no policies yet | No data returns through the Data API on a publishable key | Access stays closed until policies exist |
| Publishable key | Safe to expose in browsers, apps and source code | Key secrecy is not the control; RLS is |
| Secret key | Full access that bypasses RLS via BYPASSRLS | Backend-only; browser requests receive HTTP 401 |
Protection is deny-by-default, not an advisory.
Once RLS is enabled the API returns nothing until a policy exists, so the protected state is stricter than the unprotected default instead of merely recommended.
Bypass credentials carry documented blast radius and platform enforcement.
The full-access key is named, its BYPASSRLS behavior is documented beside the key, its browser use is blocked by the platform, and its handling rules travel with the credential itself.
Observed facts
- The Row Level Security guide opens with a danger warning that a table in an exposed schema without RLS is "readable and writable by any role with a grant on it" and instructs builders to enable RLS on every table in an exposed schema.
- Enabling RLS flips the auto-generated Data API to zero access for publishable keys: no data is accessible until at least one policy is created.
- On existing projects a new table in the public schema starts with privileges already granted to the anon, authenticated and service_role roles, and adding policies does not revoke those grants.
- The service_role role is documented as full access that bypasses RLS, and the guide says to keep it server-side.
- For builders who want protection applied without remembering each table, the guide points to event triggers that enable RLS automatically on every new table.
- Publishable keys are documented as safe to expose online across web pages, mobile or desktop apps, CLIs and source code; because public environments are always considered retrievable, data protection comes from enabling RLS on all tables rather than from key secrecy.
- Secret keys provide full access to project data and bypass Row Level Security through the underlying service_role's BYPASSRLS attribute, which skips every attached policy.
- Secret-key guidance forbids browser use even on localhost, restricts the keys to backend components, and the platform enforces part of this boundary itself by rejecting browser User-Agent requests with HTTP 401 while advising immediate replacement of any exposed key.
Editorial inference
- Data exposure becomes a bounded decision when the dangerous default is named, protection starts stricter than the default, and elevated credentials carry documented limits the platform itself enforces.
Evidence views
- Exposed-schema danger explanation
- Per-table RLS enablement decision
- Deny-until-policy API behavior
- Publishable versus secret key comparison
- Secret-key browser-use rejection
Founder takeaway
Name what the unsafe default exposes, make protection start stricter than the default, and give elevated credentials a documented blast radius the platform enforces.
Use when
- Auto-generated or client-facing APIs would otherwise expose database rows to anonymous clients
- The product can function under zero access until access rules are authored
- Credential tiers can be separated without breaking the developer workflow
Avoid when
- Content is genuinely public and default-deny would break the core experience
- Teams cannot realistically author access rules and would silently ship empty screens instead of protected ones
- Elevated server-side credentials cannot be kept out of client code or shared environments
Next implementation step
Design a data-exposure guardrail path that names the unsafe default, starts protected projects from deny-by-default and keeps elevated credentials visibly bounded.
Acceptance criteria
- A builder can state what happens if RLS is skipped before writing application code
- The interface shows that enabling RLS closes API access until a policy exists
- Browser-safe and bypass-everything keys appear as distinct tiers
- Bypass-key misuse produces an enforced failure rather than a documentation note
- No private project field appears in public evidence or Agent output
Related cases
- Stated boundaries replace assumed safety: Polymarket inline evidence trust pattern — Hovvi
Polymarket attaches resolution sources and fee formulas to every price so capital decisions rest on inspectable facts; Supabase states the exposure consequence of unprotected tables and flips APIs to deny-by-default so data goes live only behind explicit policies.
- Explicit stops on open-ended risk: Anthropic API prepaid credits and billing boundary — Hovvi
Anthropic bounds spending with prepaid credits, a hard zero-balance stop and opt-in reload; Supabase bounds data exposure with deny-by-default policies and a bypass tier whose browser use is blocked outright.
Version history
Current snapshot: snap_supabase_rls_guardrails_2026_08_26 — Added a bounded Supabase agent-trust Task Reference using public link-only documentation evidence; dashboard advisors, private project data and authenticated console state remain excluded.
Use with an Agent
Example read-only MCP query:
Retrieve the Hovvi Founder case fc_supabase_rls_guardrails_2026_08 with observed facts, evidence screens, applicability limits and citations.