Gå til indhold

Supabase exposed schemas: hvad listen åbner for

Supabase

Vis som MarkdownÅbn i ClaudeÅbn i ChatGPTÅbn i Perplexity

Spørgsmålet kopieres også. Hvis chatten åbner tom, så indsæt det.

TL;DR

Listen Exposed schemas i Supabase afgør, hvilke schemas Data API’et leverer til enhver, der har din offentlige nøgle. Standarden er public og graphql_public. Hver tabel, view og funktion i et schema på listen skal have sine egne rettigheder og sin egen RLS, så hvert ekstra schema er mere overflade at forsvare. Hold listen kort, og tjek den først.

Jeg har bygget et gratis Supabase-sikkerhedstjek, og listen Exposed schemas er en af de første ting, det læser. Når nogen spørger, hvor sikkert et Supabase-projekt er, er det her, jeg starter.

Hvad betyder “exposed schemas” i Supabase Data API?

Supabase leverer din database over REST med PostgREST. PostgREST svarer kun for de schemas, der står i dens db_schema-liste, og den redigerer du i Dashboard under Project Settings → Data API → Exposed schemas. I den projektkonfiguration, jeg så på, var værdien public,graphql_public, og Supabases guide til custom schemas siger, at public er eksponeret som standard. En anmodning om et schema uden for listen bliver afvist, og PostgREST tillader aldrig pg_catalog eller information_schema i den.

Hvorfor betyder listen noget?

Alt i et eksponeret schema kan nås med den offentlige nøgle: tabeller, views og funktioner. Supabases RLS-guide er tydelig: en tabel i et eksponeret schema uden RLS kan læses og skrives af enhver rolle med en rettighed på den. Et schema, der ikke står på listen, kan slet ikke nås gennem API’et.

Så et ekstra schema er ikke en neutral ændring. Tilføj storage eller vault til listen, og du har lagt interne tabeller inden for Data API’ets rækkevidde. Tilføj dit eget schema, og hver tabel i det kræver samme omhu som public.

Hvad et ekstra exposed schema åbner for. Én anon-anmodning før og efter, at listen er beskåret. Før: et ekstra schema er exposed: anon-anmodning → Data API → ekstra schema → tabel uden RLS kan læses; Efter: kun public og graphql_public: anon-anmodning → Data API → kun standard-schemas → RLS på alle tabeller.
Fra Supabase-tjekkets regler og Supabases Data API-dokumentation, 22. oktober 2026.

Hvordan vurderer tjekket ekstra schemas?

Tjekket hedder extra_exposed_schemas. Alt undtagen public og graphql_public tæller som ekstra, og derefter gælder:

  • Et internt Supabase-schema på listen (auth, storage, realtime, vault, extensions og lignende) er en fejl med høj alvorlighed.
  • Kun egne schemas, for eksempel api, giver en advarsel med middel alvorlighed.
  • Ingen ekstra schemas giver bestået.

Den samme liste styrer andre tjek. Tabeller med RLS slået fra, skriverettigheder til anon, policies der altid er sande, views uden security_invoker og SECURITY DEFINER-funktioner, som anon kan kalde, bliver kun rapporteret for eksponerede schemas, fordi det er dér, den offentlige nøgle når dem.

Hvordan bruger du et eget schema sikkert?

Et eget schema er et legitimt mønster: Supabases guide Securing your API beskriver et dedikeret schema som api som en måde at gøre den eksponerede overflade lettere at identificere og gennemgå, mens interne tabeller bliver i schemas, der ikke er eksponeret. To trin får det til at virke, og guiden til custom schemas beskriver begge: tilføj schemaet til Exposed schemas, og giv derefter usage på det til anon, authenticated og service_role, plus rettigheder på dets objekter.

Guidens eksempel giver ALL på hver tabel. Den linje ville jeg ikke kopiere, som den står. Guiden Securing your API siger, at hver rolle kun skal have det mindste, den har brug for, og at du skal aktivere RLS på hver tabel, du eksponerer. Rettigheder afgør, om en rolle overhovedet kan røre en tabel, policies afgør hvilke rækker.

Én særskilt ændring: Supabase holder op med automatisk at give Data API’et adgang til nye public-tabeller. Det blev standard for nye projekter fra 30. maj 2026 og bliver indført for eksisterende projekter den 30. oktober 2026, og eksisterende tabeller beholder deres rettigheder. Det er rettighedslaget. Det ændrer ikke, hvilke schemas der står på listen.

Hvordan tjekker du, hvor sikkert dit eget Supabase-projekt er?

Åbn Project Settings → Data API, og læs Exposed schemas. Hvis der står mere end public og graphql_public, så spørg, hvad hvert ekstra schema skal bruges til.

List derefter de tabeller i de schemas, der har RLS slået fra, og om anon allerede kan læse dem:

select n.nspname as schema,
       c.relname as "table",
       has_table_privilege('anon', c.oid, 'select') as anon_can_select
from pg_class c
join pg_namespace n on n.oid = c.relnamespace
where n.nspname in ('public', 'api')  -- your Exposed schemas
  and c.relkind in ('r', 'p')
  and not c.relrowsecurity
order by 1, 2;

Jeg kørte den på en midlertidig Postgres 17 med et api-schema med én tabel med RLS og én uden, plus en public-tabel uden RLS. Den returnerede kun de to uden:

 schema | table  | anon_can_select
--------+--------+-----------------
 api    | orders | t
 public | logs   | t

Hver række, hvor anon_can_select er sand, er en tabel, som enhver med din offentlige nøgle kan læse, indtil du aktiverer RLS eller trækker rettigheden tilbage. Forespørgslen dækker kun tabeller. Views og funktioner kræver deres eget eftersyn, og det gennemgår min sikkerhedstjekliste til Lovable-apps, mens sådan tester jeg Supabase RLS viser, hvordan du beviser, at policies virker.

© 2026 Denys Zaichenko. Original artikel: https://madsalt.tech/da/notes/supabase-exposed-schemas/