Mockly

glossary

Schema USAGE Granted to PUBLIC

Granting USAGE on a schema to PUBLIC exposes everything inside it. This page explains it in plain English, then goes deeper into how it works in Supabase/Postgres, what commonly goes wrong, and how to fix it without relying on fragile client-side rules.

What “Schema USAGE Granted to PUBLIC” means (plain English)

Schema USAGE lets roles list or reference objects; giving it to PUBLIC lets attackers discover tables and functions.

How Schema USAGE Granted to PUBLIC works in Supabase/Postgres (technical)

Even when table-level grants are restricted, schema-level USAGE allows roles to see objects and bypass protections via public grants or RPCs.

Attack paths & failure modes for Schema USAGE Granted to PUBLIC

  • Schema USAGE Granted to PUBLIC: direct API bypass: The UI appears restricted, but schema USAGE was granted to PUBLIC, so attackers call the same endpoints directly with client credentials.
  • Schema USAGE Granted to PUBLIC: migration drift regression: A later schema migration added a new object while granting USAGE broadly, undoing earlier hardening.
  • Schema USAGE Granted to PUBLIC: direct API bypass: Schema-level grants let attackers see and execute tables or functions despite incomplete backend checks.
  • Schema USAGE Granted to PUBLIC: migration drift regression: Security guardrails were missing so the migration slipped a public schema grant back into production.
  • The configuration doesn’t match what the UI implies (direct API access bypasses the app).
  • Policies/grants drift over time and widen access without anyone noticing.
  • Fixes are applied without verification, leading to false confidence.

Why Schema USAGE Granted to PUBLIC matters for Supabase security

Attackers can enumerate schema contents and call objects that were never meant for public consumption. If Schema USAGE Granted to PUBLIC remains unresolved, attackers can automate enumeration and unauthorized writes at API speed. Treat it as a production reliability risk as well as a data security risk, because incidents spread quickly once clients discover weak access boundaries.

Common Schema USAGE Granted to PUBLIC mistakes that lead to leaks

  • Granting USAGE on the public schema to PUBLIC for convenience.
  • Assuming table-level protections override schema-level exposure.
  • Not auditing schema grants after migrations.
  • Schema USAGE Granted to PUBLIC: direct API bypass: Schema-level grants let attackers see and execute tables or functions despite incomplete backend checks.
  • Schema USAGE Granted to PUBLIC: migration drift regression: Security guardrails were missing so the migration slipped a public schema grant back into production.

Where to look for Schema USAGE Granted to PUBLIC in Supabase

  • Your grants, policies, and any direct client access paths.
  • Storage and RPC settings (common blind spots).

How to detect Schema USAGE Granted to PUBLIC issues (signals + checks)

Use this as a quick checklist to validate your current state:

  • Try the same queries your frontend can run (anon/authenticated). If sensitive rows come back, you have exposure.
  • Verify RLS is enabled and (for sensitive tables) forced.
  • List policies and look for conditions that don’t bind rows to a user or tenant.
  • Audit grants to anon / authenticated on sensitive tables and functions.
  • Schema USAGE Granted to PUBLIC: direct API bypass: Schema-level grants matter as much as table grants.
  • Schema USAGE Granted to PUBLIC: direct API bypass: Direct API tests reveal exposures that UI checks hide.
  • Schema USAGE Granted to PUBLIC: direct API bypass: Backend-only patterns keep sensitive schema objects locked down.
  • Re-test after every migration that touches security-critical tables or functions.

How to fix Schema USAGE Granted to PUBLIC (backend-only + zero-policy posture)

Mockly’s safest default is backend-only access: the browser should not query tables, call RPC, or access Storage directly.

  1. Decide which operations must remain client-side (often: none for sensitive resources).
  2. Create server endpoints (API routes or server actions) for required reads/writes.
  3. Apply hardening SQL: enable+force RLS where relevant, remove broad policies, and revoke grants from client roles.
  4. Generate signed URLs for private Storage downloads on the server only.
  5. Re-run a scan and confirm the issue disappears.
  6. Add a regression check to your release process so drift doesn’t reintroduce exposure. Fixes that worked in linked incidents:
  • Schema USAGE Granted to PUBLIC: direct API bypass: Revoke schema USAGE from PUBLIC, restrict object grants, and move sensitive logic behind backend-only endpoints.
  • Schema USAGE Granted to PUBLIC: migration drift regression: Add migration-time checks for schema grants, restrict USAGE, and document the intended privileges.

Verification checklist for Schema USAGE Granted to PUBLIC

  1. Attempt direct access using client credentials and confirm it fails.
  2. Apply a backend-only fix pattern and verify end-to-end behavior.
  3. Re-run a scan after changes and after the next migration.
  4. Schema USAGE Granted to PUBLIC: direct API bypass: Schema-level grants matter as much as table grants.
  5. Schema USAGE Granted to PUBLIC: direct API bypass: Direct API tests reveal exposures that UI checks hide.
  6. Schema USAGE Granted to PUBLIC: direct API bypass: Backend-only patterns keep sensitive schema objects locked down.
  7. Schema USAGE Granted to PUBLIC: direct API bypass: Re-run security checks after schema or grant changes.
  8. Schema USAGE Granted to PUBLIC: migration drift regression: Migrations can reintroduce schema-grant drift.

SQL sanity checks for Schema USAGE Granted to PUBLIC (optional, but high signal)

If you prefer evidence over intuition, run a small set of SQL checks after each fix.

The goal is not to memorize catalog tables — it’s to make sure the access boundary you intended is the one Postgres actually enforces:

  • Confirm RLS is enabled (and forced where appropriate) for tables tied to this term.
  • List policies and read them as plain language: who can do what, under what condition?
  • Audit grants for anon/authenticated and PUBLIC on the tables, views, and functions involved.
  • If Storage is involved: review bucket privacy and policies for listing/reads.
  • If RPC is involved: review EXECUTE grants for functions and whether privileged functions are server-only.

Pair these checks with a direct API access test using client credentials. When both agree, you can ship the fix with confidence.

Over time, keep a small “query pack” for the checks you trust and run it after every migration. That’s how you prevent quiet regressions.

Prevent Schema USAGE Granted to PUBLIC drift (so it doesn’t come back)

  • Add a repeatable checklist and re-run it after schema changes.
  • Prefer backend-only access for sensitive resources.
  • Keep one reusable verification test for “Schema USAGE Granted to PUBLIC: direct API bypass” and rerun it after every migration that touches this surface.
  • Keep one reusable verification test for “Schema USAGE Granted to PUBLIC: migration drift regression” and rerun it after every migration that touches this surface.

Rollout plan for Schema USAGE Granted to PUBLIC fixes (without breaking production)

Many hardening changes fail because teams revoke direct access first and only later discover missing backend paths.

Use this sequence to reduce both risk and outage pressure:

  1. Implement and verify the backend endpoint or server action before permission changes.
  2. Switch clients to that backend path behind a feature flag when possible.
  3. Then revoke direct client access (broad grants, permissive policies, public bucket reads, or broad EXECUTE).
  4. Run direct-access denial tests and confirm authorized backend flows still succeed.
  5. Re-scan after deployment and again after the next migration.

This turns security fixes into repeatable rollout mechanics instead of one-off emergency changes.

Incident breakdowns for Schema USAGE Granted to PUBLIC (real scenarios)

Schema USAGE Granted to PUBLIC: direct API bypass

Scenario: The UI appears restricted, but schema USAGE was granted to PUBLIC, so attackers call the same endpoints directly with client credentials.

What failed: Schema-level grants let attackers see and execute tables or functions despite incomplete backend checks.

What fixed it: Revoke schema USAGE from PUBLIC, restrict object grants, and move sensitive logic behind backend-only endpoints.

Why the fix worked: Without schema USAGE, client credentials can no longer discover or execute the objects that power the bypass.

Key takeaways:

  • Schema-level grants matter as much as table grants.
  • Direct API tests reveal exposures that UI checks hide.
  • Backend-only patterns keep sensitive schema objects locked down.
  • Re-run security checks after schema or grant changes.

Read full example: Schema USAGE Granted to PUBLIC: direct API bypass

Schema USAGE Granted to PUBLIC: migration drift regression

Scenario: A later schema migration added a new object while granting USAGE broadly, undoing earlier hardening.

What failed: Security guardrails were missing so the migration slipped a public schema grant back into production.

What fixed it: Add migration-time checks for schema grants, restrict USAGE, and document the intended privileges.

Why the fix worked: With automated checks, drift no longer reopens the schema to public clients.

Key takeaways:

  • Migrations can reintroduce schema-grant drift.
  • CI should validate schema and grant changes.
  • Document intended grants per schema.
  • Track security state before and after schema changes.

Read full example: Schema USAGE Granted to PUBLIC: migration drift regression

Real-world examples of Schema USAGE Granted to PUBLIC (and why they work)

Related terms

  • Default Privilege Drift → /glossary/default-privilege-drift
  • Exposed Materialized Views → /glossary/exposed-materialized-views

FAQ

Is Schema USAGE Granted to PUBLIC enough to secure my Supabase app?

It’s necessary, but not sufficient. You also need correct grants, secure Storage/RPC settings, and a backend-only access model for sensitive operations.

What’s the quickest way to reduce risk with Schema USAGE Granted to PUBLIC?

Remove direct client access to sensitive resources, enable/force RLS where appropriate, and verify via a repeatable checklist that anon/authenticated cannot query what they shouldn’t.

How do I verify the fix is real (not just a UI change)?

Attempt direct API queries using the same client credentials your app ships. If the database denies access (401/403) and your backend endpoints still work, your fix is effective.

Next step

Want a quick exposure report for your own project? Run a scan in Mockly to find public tables, storage buckets, and RPC functions — then apply fixes with verification steps.

Explore related pages

parent

Glossary

/glossary

sibling

Default Privilege Drift

/glossary/default-privilege-drift

sibling

Exposed Materialized Views

/glossary/exposed-materialized-views

cross

Lock down a public table (backend-only access)

/templates/access-control/lock-down-public-table

cross

Remove over-permissive RLS policies (adopt deny-by-default)

/templates/access-control/remove-over-permissive-policies

cross

Pricing

/pricing