---
title: "Supabase Exposed Schemas: was die Liste freigibt"
description: "Was Exposed Schemas in Supabase bedeutet, wie mein Sicherheitscheck zusätzliche Schemas bewertet und welche SQL-Abfrage Tabellen ohne RLS in ihnen findet."
url: "https://madsalt.tech/de/notes/supabase-exposed-schemas/"
author: "Denys Zaichenko"
language: "de"
published: 2026-10-22
---

# Supabase Exposed Schemas: was die Liste freigibt

Kurz gesagt

Die Liste Exposed Schemas in Supabase legt fest, welche Schemas die Data API jedem liefert, der Ihren öffentlichen Key hat. Standard sind `public` und `graphql_public`. Jede Tabelle, jede View und jede Funktion in einem Schema auf dieser Liste braucht eigene Grants und RLS, jedes zusätzliche Schema ist also mehr Angriffsfläche, die Sie verteidigen müssen. Halten Sie die Liste kurz und prüfen Sie sie zuerst.

Ich habe einen kostenlosen [Supabase-Sicherheitscheck](https://madsalt.tech/de/tools/supabase-security-check/) gebaut, und die Liste der Exposed Schemas gehört zu den ersten Dingen, die er liest. Wenn jemand fragt, wie sicher ein Supabase-Projekt ist, fange ich bei dieser Einstellung an.

## Was bedeutet "exposed" in Supabase?

Supabase liefert Ihre Datenbank per REST über PostgREST aus. PostgREST antwortet nur für die Schemas in seiner `db_schema`-Liste, die Sie im Dashboard unter Project Settings → Data API → Exposed schemas bearbeiten. In der Projektkonfiguration, die ich mir angesehen habe, lautete der Wert `public,graphql_public`, und die [Anleitung zu Custom Schemas](https://supabase.com/docs/guides/api/using-custom-schemas) von Supabase sagt, dass `public` standardmäßig exponiert ist. Eine Anfrage für ein Schema außerhalb der Liste wird abgelehnt, und [PostgREST](https://docs.postgrest.org/en/stable/references/api/schemas.html) erlaubt `pg_catalog` und `information_schema` darin nie.

## Warum ist die Liste für die Sicherheit wichtig?

Alles in einem exponierten Schema ist mit dem öffentlichen Key erreichbar: Tabellen, Views und Funktionen. Der [RLS-Leitfaden](https://supabase.com/docs/guides/database/postgres/row-level-security) von Supabase ist da deutlich: Eine Tabelle in einem exponierten Schema ohne RLS ist für jede Rolle mit einem Grant darauf les- und schreibbar. Ein Schema, das nicht auf der Liste steht, ist über die API gar nicht erreichbar.

Ein zusätzliches Schema ist also keine neutrale Änderung. Nehmen Sie `storage` oder `vault` in die Liste auf, rücken interne Tabellen in Reichweite der Data API. Nehmen Sie ein eigenes Schema auf, braucht jede Tabelle darin dieselbe Sorgfalt wie `public`.

![Was ein zusätzliches exponiertes Schema öffnet. Eine anon-Anfrage, vor und nach dem Kürzen der Liste. Vorher: ein Extra-Schema ist exponiert: anon-Anfrage → Data API → Extra-Schema → Tabelle ohne RLS lesbar; Nachher: nur public und graphql_public: anon-Anfrage → Data API → nur Standard-Schemas → RLS auf allen Tabellen.](https://madsalt.tech/charts/de/supabase-exposed-schemas.svg)

*Aus den Regeln des Supabase-Sicherheitschecks und der Dokumentation der Supabase Data API, 22. Oktober 2026.*

## Wie bewertet der Check zusätzliche Schemas?

Der Check heißt `extra_exposed_schemas`. Alles außer `public` und `graphql_public` zählt als zusätzlich, dann gilt:

- Ein internes Supabase-Schema in der Liste (`auth`, `storage`, `realtime`, `vault`, `extensions` und ähnliche) ist ein **Problem mit hohem Schweregrad**.
- Nur eigene Schemas, zum Beispiel `api`, ergeben eine **Warnung mit mittlerem Schweregrad**.
- Keine zusätzlichen Schemas: bestanden.

Dieselbe Liste steuert weitere Prüfungen. Tabellen ohne RLS, Schreib-Grants für anon, Policies, die immer true sind, Views ohne `security_invoker` und `SECURITY DEFINER`-Funktionen, die anon aufrufen kann, werden nur für exponierte Schemas gemeldet, denn dort erreicht sie der öffentliche Key.

## Wie nutzen Sie ein eigenes Schema sicher?

Ein eigenes Schema ist ein legitimes Muster: Die Anleitung [Securing your API](https://supabase.com/docs/guides/api/securing-your-api) von Supabase beschreibt ein eigenes Schema wie `api` als Weg, die exponierte Oberfläche leichter erkennbar und prüfbar zu machen, während interne Tabellen in Schemas liegen, die nicht exponiert sind. Zwei Schritte machen es funktionsfähig, beide stehen in der [Anleitung zu Custom Schemas](https://supabase.com/docs/guides/api/using-custom-schemas): das Schema zu Exposed schemas hinzufügen, dann `usage` darauf an `anon`, `authenticated` und `service_role` vergeben, dazu Rechte auf seinen Objekten.

Das Beispiel der Anleitung vergibt `ALL` auf jede Tabelle. Diese Zeile würde ich nicht so übernehmen. Die Anleitung Securing your API sagt, jede Rolle soll das Minimum bekommen, das sie braucht, und RLS soll auf jeder Tabelle aktiv sein, die Sie exponieren. Grants entscheiden, ob eine Rolle eine Tabelle anfassen darf, Policies entscheiden, welche Zeilen.

Eine getrennte Änderung: Supabase [vergibt neue `public`-Tabellen nicht mehr automatisch an die Data API](https://supabase.com/changelog/45329-breaking-change-tables-not-exposed-to-data-and-graphql-api-automatically). Für neue Projekte ist das ab dem 30. Mai 2026 der Standard, auf bestehende Projekte wird es am 30. Oktober 2026 angewendet, und bestehende Tabellen behalten ihre Grants. Das ist die Grants-Ebene. Es ändert nichts daran, welche Schemas auf der Liste stehen.

## Wie prüfen Sie Ihr eigenes Supabase-Projekt?

Öffnen Sie Project Settings → Data API und lesen Sie Exposed schemas. Steht dort mehr als `public` und `graphql_public`, fragen Sie sich, wofür jedes zusätzliche Schema da ist.

Listen Sie dann die Tabellen in diesen Schemas auf, bei denen RLS aus ist, und ob `anon` sie schon lesen kann:

```sql
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;
```

Ich habe sie auf einem Wegwerf-Postgres 17 ausgeführt, mit einem Schema `api` mit einer Tabelle mit RLS und einer ohne sowie einer `public`-Tabelle ohne RLS. Zurück kamen nur die beiden ohne:

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

Jede Zeile mit `anon_can_select` true ist eine Tabelle, die jeder mit Ihrem öffentlichen Key lesen kann, bis Sie RLS aktivieren oder den Grant entziehen. Die Abfrage deckt nur Tabellen ab. Views und Funktionen brauchen einen eigenen Blick, den meine [Sicherheits-Checkliste für Lovable-Apps](https://madsalt.tech/de/blog/lovable-app-security-checklist/) durchgeht, und [wie ich Supabase RLS teste](https://madsalt.tech/de/blog/how-to-test-supabase-rls/) zeigt, wie Sie beweisen, dass die Policies funktionieren.
