PostgreSQL-Fehler: permission denied for table / schema

ERROR:  permission denied for table orders

-- variante a livello di schema:
ERROR:  permission denied for schema app

Der Rolle, mit der Sie verbunden sind, fehlt das Recht, das die Anweisung benötigt: SELECT/INSERT/UPDATE/DELETE auf einer Tabelle, USAGE oder CREATE auf einem Schema, USAGE auf einer Sequenz. (Ältere PostgreSQL-Versionen formulieren das erste als "permission denied for relation".) Die Lösung ist immer ein GRANT — der interessante Teil ist, warum der Grant fehlte.

Was dieser Fehler bedeutet

PostgreSQL-Berechtigungen sind pro Objekt und kaskadieren nicht: um app.orders zu lesen, brauchen Sie sowohl USAGE auf dem Schema app als auch SELECT auf der Tabelle. Eigentümer halten implizit alle Rechte auf ihren Objekten — was genau der Grund ist, warum alles in der Entwicklung funktioniert (wo die App als Eigentümer verbindet) und in der Produktion bricht (wo sie es nicht tut).

Zwei benachbarte Varianten, die man kennen sollte: permission denied for sequence orders_id_seq bedeutet, die Rolle darf die Tabelle schreiben, aber keine IDs aus ihrer Sequenz ziehen; permission denied for schema public begann mit PostgreSQL 15 breit aufzutauchen, das aufhörte, jedem Benutzer standardmäßig das Erstellen von Objekten in public zu erlauben.

Häufige Ursachen

So diagnostizieren Sie ihn

SELECT current_user;                -- wer Sie wirklich sind (Vorsicht bei Poolern)

\dp orders                          -- Rechte und Eigentümer der Tabelle
\dn+                                -- Rechte auf den Schemas

SELECT has_table_privilege('app_user', 'app.orders', 'SELECT');

Lesen Sie die \dp-Ausgabe gnadenlos: eine leere Spalte "Access privileges" bedeutet, nur der Eigentümer hat Zugriff. Und prüfen Sie, wer der Eigentümer ist — das erklärt meist, wie die Situation entstand.

So beheben Sie ihn

-- Das typische Minimalset für eine Anwendungsrolle:
GRANT USAGE ON SCHEMA app TO app_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA app TO app_user;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA app TO app_user;

-- Und für ZUKÜNFTIGE Tabellen, die von der Migrations-Rolle erstellt werden:
ALTER DEFAULT PRIVILEGES FOR ROLE migrator IN SCHEMA app
  GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_user;
ALTER DEFAULT PRIVILEGES FOR ROLE migrator IN SCHEMA app
  GRANT USAGE, SELECT ON SEQUENCES TO app_user;

-- PostgreSQL 15+, falls Objekte in public erstellt werden müssen:
GRANT CREATE ON SCHEMA public TO app_user;