# Benutzer / Rolle nur Read-Only anlegen?

**URL:** <https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170>\
**Category:** Konfiguration & Verwaltung\
**Created:** [14. September 2025 um 09:22 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170 "2025-09-14T09:22:10Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![oelk](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/o/7993a0/32.png) [@oelk](https://www.pg-forum.de/u/oelk)\
**Post date:** [14. September 2025 um 09:22 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/1 "2025-09-14T09:22:10Z")

</div>

Moin,

Ich habe folgende Aufgabenstellung:  
es gibt ein Schema ‘Schema1’ und einen Benutzer/Rolle ‘User1’, dem dieses Rolle Schema gehört.  
Er hat die Rechte  
SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication FROM pg\_roles;

User1: rolsuper=false  
rolinherit=true  
rolcreaterole=false  
roleceratedb=false  
rolcanlogin=true  
rolreplication=fal

Jetzt soll ein Benutzer/Rolle angelegt werden, der auf dieses Schema zugreifen darf und Nur-Lese-Rechte auf diese Schema hat.

Wie bewerkstellige ich das?  
Über ‘\dgS+’ habe ich die Rolle ‘pg\_read\_all\_data’ gefunden.

Kann mit diesem Benutzer/dieser Rolle ein Schema ausgelesen werden?  
Oder sollte man einen Benutzer anlegen, der nur auf ein bestehendes Schema zugreifen darf  
und das nur lesend?

Oder anders herum gefragt:

Kann ich ‘pg\_read\_all\_data’ benutzen, um die Daten aus ‘Schema1’ auszulesen?

OS ist Debian 11, PostgreSQL 16

Meine Idee wäre jetzt gewesen:

CREATE ROLE PowerBi;  
GRANT CONNECT ON DATABASE Schema1 TO PowerBi GRANTED BY pg\_read\_all\_data;  
GRANT SELECT ON ALL TABLES IN SCHEMA Schema1 GRANTED BY pg\_read\_all\_data;

Ich hab zur Zeit (noch) keine Test-Instanz, um das mal aus zu probieren.

Braucht der Benutzer / die Rolle zwingend ein Login/Passwort, um die Daten aus zulesen?

MfG

---

<div class="post-metadata">

**Author:** ![castorp](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/c/e99b99/32.png) [@castorp](https://www.pg-forum.de/u/castorp)\
**Post date:** [14. September 2025 um 15:27 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/2 "2025-09-14T15:27:06Z")

</div>

> [@oelk](#):
>
> Kann mit diesem Benutzer/dieser Rolle ein Schema ausgelesen werden?

Ja, wie [im Handbuch erklärt](https://www.postgresql.org/docs/current/predefined-roles.html) darf ein User mit dieser Rolle **alles** lesen und er hat auch das USAGE Recht auf **alle** Schemata. Es reicht dem Benutzer die Rolle zu “granten”:

```auto
grant pg_read_all_data to powerbi;

```

Wenn Du den Zugriff aber wirklich _nur_ auf dieses eine Schema einschränken möchtest, dann musst Du das manuell machen:

```sql
create role read_only;
grant usage on schema schema1;
grant select on all tables in schema schema1;

```

> [@oelk](#):
>
> Braucht der Benutzer / die Rolle zwingend ein Login/Passwort, um die Daten aus zulesen?

```sql
grant user powerbi password ' *****';
grant connect on database reporting_database to powerbi;
grant read_only to powerbi;

```

Datenbank und Schema sind zwei verschiedene Dinge. `GRANT CONNECT ON DATABASE Schema1 ` macht deswegen wenig Sinn - es sei denn Du hast eine _Datenbank_ die ` schema1` heißt.

---

<div class="post-metadata">

**Author:** ![oelk](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/o/7993a0/32.png) [@oelk](https://www.pg-forum.de/u/oelk)\
**Post date:** [14. September 2025 um 20:27 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/3 "2025-09-14T20:27:28Z")

</div>

Hallo Castorp,  
danke für Deine Antwort.

Wenn ich Dich richtig verstehe, dann müsste das dann zusammen gefasst so aussehen:

CREATE ROLE PowerBi;  
GRANT USER PowerBi PASSWORD ‘\*\*\*\*\*’;

CREATE ROLE read\_only;  
GRANT USAGE ON SCHEMA Schema1;  
GRANT SELECT ON ALL TABLES IN SCHEMA Schema1;

Ich muss das morgen nochmal genau überprüfen ob das ein Schema oder eine Datenbank ist.

Die Rechte für den eigentlichen Benutzer ‘User1’ bleiben aber erhalten?

Ich möchte ja nur das read\_only für den Benutzer PowerBi und nur den Zugriff auf Schema1.

User1 soll weiterhin seine Rechte auf Schema1 behalten.

MfG

---

<div class="post-metadata">

**Author:** ![castorp](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/c/e99b99/32.png) [@castorp](https://www.pg-forum.de/u/castorp)\
**Post date:** [14. September 2025 um 20:41 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/4 "2025-09-14T20:41:38Z")

</div>

` GRANT USER` gibt es nicht. Einen Benutzer der sich anmelden darf, legt man an mit:

```auto
create user powerbi password ' ****';

```

Du musst die read\_only Rolle dann noch dem Benutzer geben:

```auto
grant read_only to powerbi;

```

---

<div class="post-metadata">

**Author:** ![oelk](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/o/7993a0/32.png) [@oelk](https://www.pg-forum.de/u/oelk)\
**Post date:** [15. September 2025 um 08:31 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/5 "2025-09-15T08:31:37Z")

</div>

Moin castorp,

ok, es ist eine Datenbank, kein Schema.

Also das funktioniert schon mal in einem Testsystem ( Klon des produktiven):

> CREATE USER powerbi WITH LOGIN PASSWORD ‘\*\*\*\*\*’ NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;  
> GRANT CONNECT ON DATABASE database1 TO powerbi;  
> GRANT pg\_read\_all\_data TO powerbi;

Es gibt keine weiteren Datenbanken ausser postgres, template0, template1 und database1.

Anmelden klappt auch:

```auto
psql -h <hostname> -p 5432 -U powerbi -d database1

```

Das zeigt mir auch ensprechende Tabellen an:

```auto
\dtS+

```

Und Benutzer wieder löschen:

```auto
REVOKE CONNECT ON DATABASE database1 FROM powerbi;
DROP USER powerbi;

```

Einverstanden?

So, eine Tabelle kann er aber trotzdem anlegen:

CREATE TABLE ak\_test (brand VARCHAR(255), model VARCHAR(255),year INT);

Genau das soll verhindert werden.

Und das löschen von Tabellen soll auch verhindert werden.

MfG

---

<div class="post-metadata">

**Author:** ![castorp](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/c/e99b99/32.png) [@castorp](https://www.pg-forum.de/u/castorp)\
**Post date:** [15. September 2025 um 09:33 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/6 "2025-09-15T09:33:08Z")

</div>

In Postgres 15 hatte die Rolle `public` noch das `usage` Recht auf dem Schema `public`. Das wurde mit Postgres 16 geändert. Wenn Deine Datenbank aber von 15 auf 16 migriert wurde, wurde das beibehalten, das gilt nur für neue Datenbanken.

Versuch mal:

```sql
revoke usage on schema public from public;

```

Das Gleiche gilt glaube ich auch für das `connect` Privileg:

```sql
revoke connect on database database1 from public; 

```

---

<div class="post-metadata">

**Author:** ![oelk](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/o/7993a0/32.png) [@oelk](https://www.pg-forum.de/u/oelk)\
**Post date:** [15. September 2025 um 11:46 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/7 "2025-09-15T11:46:29Z")

</div>

Nach vielem hin und her kann ich den Benutzer nciht mehr löschen:

DROP USER powerbi;

Privilegien für Vorgabeprivilegien für neue Relationen von Rolle postgres in Schema public

MfG

---

<div class="post-metadata">

**Author:** ![castorp](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/c/e99b99/32.png) [@castorp](https://www.pg-forum.de/u/castorp)\
**Post date:** [15. September 2025 um 12:05 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/8 "2025-09-15T12:05:58Z")

</div>

Du hast vermutlich ein ALTER DEFAULT PRIVILEGES gemacht. Wenn ich das richtig im Kopf habe, dann muss man die zurücksetzen bevor man den User löschen kann.

---

<div class="post-metadata">

**Author:** ![laurenz](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/l/bc79bd/32.png) [@laurenz](https://www.pg-forum.de/u/laurenz)\
**Post date:** [15. September 2025 um 15:32 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/9 "2025-09-15T15:32:35Z")

</div>

Das `CONNECT`-Recht auf die Datenbank würde ich nicht entziehen, das ist noch immer standardmäßig bei `PUBLIC`.

Das `CREATE`-Recht auf das Schema `public` zu entziehen ist eine gute Idee.

Um alle Rechte eines Users zu löschen (inkl. `DEFAULT PRIVILEGES`):

```auto
DROP OWNED BY powerbi; -- in allen Datenbanken
DROP ROLE powerbi;

```

---

<div class="post-metadata">

**Author:** ![oelk](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/o/7993a0/32.png) [@oelk](https://www.pg-forum.de/u/oelk)\
**Post date:** [16. September 2025 um 09:09 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/10 "2025-09-16T09:09:49Z")

</div>

Moin castorp,  
danke das hat geholfen.

Ja, in der Tat, das ist ein Upgrade von Postgre 14 auf Postgre 16.

Neues Spiel, neues Glück:  
CREATE ROLE powerbi WITH LOGIN PASSWORD ‘\*\*\*\*\*’ NOSUPERUSER NOCREATEDB NOCREATEROLE NOREPLICATION;  
REVOKE ALL ON DATABASE database1 FROM powerbi;  
GRANT CONNECT ON DATABASE database1 TO powerbi;  
GRANT SELECT ON ALL TABLES IN SCHEMA public TO powerbi;

Anmeldung als powerbi:  
psql -h server1 -p 5432 -U powerbi -d database1

Ein \dtS+ kann er machen, aber kein SELECT einer Tabelle.  
Obwohl ein GRANT SELECT ON ALL TABLES durch geführt wurde.

Was mich irritiert ist das GRANT SELECT auf das SCHEMA public,  
wo wir doch von einer Datenbank sprechen.

Und wenn er eine Tabelle anlegt geht das trotzdem:  
CREATE TABLE ak\_test (brand VARCHAR(255), model VARCHAR(255),year INT);  
Die ist dann im Schema public und powerbi ist der Eigentümer.

Da er mit der Datebank database1 verbunden ist, nehme ich an, das er die Tabelle  
auch darein geschrieben hat.

MfG

---

<div class="post-metadata">

**Author:** ![laurenz](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/l/bc79bd/32.png) [@laurenz](https://www.pg-forum.de/u/laurenz)\
**Post date:** [16. September 2025 um 10:29 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/11 "2025-09-16T10:29:24Z")

</div>

Ich empfehle, einmal ein bißchen Dokumentation zu lesen.

Jede PostgreSQL-Instanz hat mehrere Datenbanken, in jeder Datenbank gibt es Schemas, in den Schemas sind Tabellen, Funktionen, Views und anderes mehr. Bitte Datenbank nicht mit Schema verwechseln.

Um in einem Schema ein Objekt anzulegen, brauche ich das `CREATE`-Recht auf das Schema. Um ein Objekt in einem Schema zu verwenden, brauche ich das `USAGE`-Recht auf das Schema.

Was gibt das:

```auto
SELECT nspacl FROM pg_namespace WHERE nspname = 'public';

```

Das zeigt die Berechtigungen dieses Schemas an.

---

<div class="post-metadata">

**Author:** ![castorp](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/c/e99b99/32.png) [@castorp](https://www.pg-forum.de/u/castorp)\
**Post date:** [16. September 2025 um 11:01 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/12 "2025-09-16T11:01:53Z")

</div>

> [@oelk](#):
>
> Und wenn er eine Tabelle anlegt geht das trotzdem:

Ich vermute mal, da gibt es noch ein GRANT CREATE für die Rolle PUBLIC.

Versuche mal ein

`revoke create,usage on schema public from public;`

---

<div class="post-metadata">

**Author:** ![oelk](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/o/7993a0/32.png) [@oelk](https://www.pg-forum.de/u/oelk)\
**Post date:** [16. September 2025 um 11:20 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/13 "2025-09-16T11:20:50Z")

</div>

> [@laurenz](#):
>
> `SELECT nspacl FROM pg_namespace WHERE nspname = 'public';`

Mit den Grundlagen hatte ich mich schon befasst.

Als Benutzer powerbi ergibt das:

```auto
           nspacl

```

* * *

{postgres=UC/postgres,=UC/postgres}  
(1 Zeile)

MfG

---

<div class="post-metadata">

**Author:** ![oelk](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/o/7993a0/32.png) [@oelk](https://www.pg-forum.de/u/oelk)\
**Post date:** [16. September 2025 um 11:21 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/14 "2025-09-16T11:21:44Z")

</div>

> `revoke create,usage on schema public from public;`

Als Benutzer postgres? Würde das dann nicht allen Benutzern entzogen?

MfG

---

<div class="post-metadata">

**Author:** ![castorp](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/c/e99b99/32.png) [@castorp](https://www.pg-forum.de/u/castorp)\
**Post date:** [16. September 2025 um 11:50 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/15 "2025-09-16T11:50:19Z")

</div>

> [@oelk](#):
>
> Als Benutzer postgres? Würde das dann nicht allen Benutzern entzogen?

Ja, natürlich. Jedes Privileg welches der Rolle “public” gegeben wurden bekommen alle Benutzer egal, welche andere Privilegien sie haben. Nachdem Du Dich gewundert hast, dass der `powerbi` Benutzer trotzdem weiterhin Tabellen anlegen kann, liegt der Verdacht nahe, dass er das über die Rolle `public` bekommt.

Nachdem das letztendlich ein Sicherheitsrisiko ist, sollte man das auf jeden Fall entfernen - deswegen wurde das ab Postgre **s** 15 ja auch für neue neue Datenbanken entfernt.

---

<div class="post-metadata">

**Author:** ![laurenz](https://www.pg-forum.de/letter_avatar_proxy/v4/letter/l/bc79bd/32.png) [@laurenz](https://www.pg-forum.de/u/laurenz)\
**Post date:** [16. September 2025 um 12:01 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/16 "2025-09-16T12:01:25Z")

</div>

… wobei ich das `SELECT`-Recht belassen würde, aber das ist Geschmackssache.

---

<div class="post-metadata">

**Author:** ![system](https://www.pg-forum.de/uploads/default/original/1X/dc97a981dd26692d5fb52e8b8fc7c090d7b9559a.png) [@system](https://www.pg-forum.de/u/system)\
**Post date:** [15. November 2025 um 12:02 UTC](https://www.pg-forum.de/t/benutzer-rolle-nur-read-only-anlegen/13170/17 "2025-11-15T12:02:09Z")

</div>

Dieses Thema wurde automatisch 60 Tage nach der letzten Antwort geschlossen. Es sind keine neuen Antworten mehr erlaubt.
