Přejít na obsah

Supabase exposed schemas: co všechno seznam zpřístupní

Supabase

Zobrazit jako MarkdownOtevřít v ClaudeOtevřít v ChatGPTOtevřít v Perplexity

Otázka se zkopíruje také. Pokud se chat otevře prázdný, vložte ji.

TL;DR

Seznam Exposed schemas v Supabase určuje, která schémata Data API nabízí každému, kdo má váš veřejný klíč. Výchozí jsou public a graphql_public. Každá tabulka, view a funkce ve schématu na tomto seznamu musí mít vlastní granty a RLS, takže každé další schéma je další plocha k obraně. Držte seznam krátký a kontrolujte ho jako první.

Postavil jsem zdarma bezpečnostní checker pro Supabase a seznam Exposed schemas je jedna z prvních věcí, které čte. Když se mě někdo zeptá, jak bezpečný je jeho projekt na Supabase, začínám právě tímto nastavením.

Co v Supabase znamená „exposed” schema?

Supabase vystavuje vaši databázi přes REST pomocí PostgREST. PostgREST odpovídá jen za schémata ze svého seznamu db_schema, který upravíte v Dashboardu v Project Settings → Data API → Exposed schemas. V konfiguraci projektu, kterou jsem prohlížel, byla hodnota public,graphql_public a průvodce vlastními schématy od Supabase uvádí, že public je vystavené ve výchozím stavu. Požadavek na schéma mimo seznam je odmítnut a PostgREST v něm nikdy nepovolí pg_catalog ani information_schema.

Proč na tom seznamu záleží?

Všechno uvnitř vystaveného schématu je dosažitelné veřejným klíčem: tabulky, views i funkce. Průvodce RLS od Supabase to říká bez obalu: tabulka ve vystaveném schématu bez RLS je čitelná i zapisovatelná pro jakoukoli roli, která na ni má grant. Schéma, které na seznamu není, přes API dosažitelné není vůbec.

Další schéma tedy není neutrální změna. Přidáte-li na seznam storage nebo vault, dostanou se interní tabulky na dosah Data API. Přidáte-li vlastní schéma, každá tabulka v něm potřebuje stejnou péči jako public.

Co otevře extra vystavené schéma. Jeden anon požadavek, před úpravou seznamu a po ní. Před: extra schéma je vystavené: anon požadavek → Data API → extra schéma → tabulka bez RLS čitelná; Po: jen public a graphql_public: anon požadavek → Data API → jen výchozí schémata → RLS na všech tabulkách.
Z pravidel bezpečnostního checkeru Supabase a dokumentace Supabase Data API, 22. října 2026.

Jak checker seznam hodnotí?

Kontrola se jmenuje extra_exposed_schemas. Za extra se počítá všechno kromě public a graphql_public, a potom:

  • Interní schéma Supabase na seznamu (auth, storage, realtime, vault, extensions a podobná) je fail, vysoká závažnost.
  • Jen vlastní schémata, například api, dají varování, střední závažnost.
  • Bez extra schémat kontrola projde.

Seznam řídí i další kontroly. Tabulky s vypnutým RLS, zápisové granty pro anon, politiky, které vždy platí, views bez security_invoker a funkce SECURITY DEFINER, které anon může volat, se hlásí jen pro vystavená schémata, protože právě tam na ně veřejný klíč dosáhne.

Jak bezpečně používat vlastní schéma?

Vlastní schéma je legitimní vzor: průvodce Securing your API od Supabase popisuje samostatné schéma, třeba api, jako způsob, jak vystavenou plochu snáz rozpoznat a auditovat, zatímco interní tabulky zůstanou ve schématech, která vystavená nejsou. Funguje to na dva kroky a průvodce vlastními schématy uvádí oba: přidejte schéma do Exposed schemas a pak dejte rolím anon, authenticated a service_role oprávnění usage na schéma a oprávnění na jeho objekty.

Příklad v průvodci uděluje ALL na každou tabulku. Takový řádek bych nekopíroval tak, jak je. Průvodce Securing your API říká, aby každá role dostala jen minimum, které potřebuje, a aby se RLS zapnulo na každé tabulce, kterou vystavíte. Granty rozhodují, jestli se role tabulky může dotknout, politiky rozhodují, které řádky uvidí.

Jedna samostatná změna: Supabase přestává nové tabulky v public automaticky zpřístupňovat Data API. Pro nové projekty je to výchozí od 30. května 2026 a na stávající projekty se použije 30. října 2026, přičemž stávající tabulky si granty ponechají. To je vrstva grantů. Na tom, která schémata jsou na seznamu, to nic nemění.

Jak zkontrolovat vlastní projekt?

Otevřete Project Settings → Data API a přečtěte si Exposed schemas. Je-li tam víc než public a graphql_public, zeptejte se, k čemu je každé extra schéma.

Pak vypište tabulky v těchto schématech, které mají RLS vypnuté, a zjistěte, jestli je anon už teď může číst:

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;

Spustil jsem ho na zkušebním Postgresu 17 se schématem api, kde byla jedna tabulka s RLS a jedna bez, a s tabulkou v public bez RLS. Vrátil jen ty dvě bez RLS:

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

Každý řádek, kde je anon_can_select pravda, je tabulka, kterou může číst kdokoli s vaším veřejným klíčem, dokud nezapnete RLS nebo nevezmete grant zpět. Dotaz pokrývá jen tabulky. Views a funkce chtějí vlastní kontrolu, kterou provádí můj checklist zabezpečení aplikace z Lovable, a jak testuji Supabase RLS ukazuje, jak dokázat, že politiky fungují.

© 2026 Denys Zaichenko. Původní článek: https://madsalt.tech/cs/notes/supabase-exposed-schemas/