Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vTOVa-000iCp-2u for pgsql-admin@arkaria.postgresql.org; Wed, 10 Dec 2025 18:01:51 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vTOUa-000OvE-2l for pgsql-admin@arkaria.postgresql.org; Wed, 10 Dec 2025 18:00:49 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1vTOUa-000Ov4-1E for pgsql-admin@lists.postgresql.org; Wed, 10 Dec 2025 18:00:49 +0000 Received: from mail-oi1-x230.google.com ([2607:f8b0:4864:20::230]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vTOUZ-0000la-1q for pgsql-admin@lists.postgresql.org; Wed, 10 Dec 2025 18:00:48 +0000 Received: by mail-oi1-x230.google.com with SMTP id 5614622812f47-45358572a11so63498b6e.3 for ; Wed, 10 Dec 2025 10:00:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1765389646; x=1765994446; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=IdU2nRvKthY8xORKv4P/bQ8qqYOxBE24NMd7qVRROP8=; b=hemYnO62P6ZK4VTmsnxQHU32gsG7h4l/gRpLw7W50l6EfY7x59byzzpm8oWumqQIkh 7WpZmRHYQ1N3fznn3V/WeD5bU/CE8YPnaoW5RR7CGJyTiD+N7JNV+fpzZzE//cDIh9s2 6PbK0M+qUD6cHmsQMVSER+HAbZsWsDTgGGTTb3Arzgls8agAtWa8/5j0rkInV+JINufB oO1oRz4YMf8oFZGFrgVJnqjjnoEmAOtoXZBFT139SGDFfEPU+gxnmQIFJ4UbWMUsWfYX SNgXkBs/hQ9eZ2Iz4vkgnF9vqqtbdWKI1aai4DHnE/FJdRhrtxIBbD6tX1y/8nHpT2gR i5JA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1765389646; x=1765994446; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=IdU2nRvKthY8xORKv4P/bQ8qqYOxBE24NMd7qVRROP8=; b=RzwbW7GgodGADOeVIkswYUeilVM4W2Pbiy/I3BiSqBpG+D9pjCDl0+i0jyqMM4u4y/ DNHhaNbfI3ZtTXCU+tmjHW24PeBAOZYtyJCKy2amViIX/G3xI+Zta2BhHfRt0Kj6fq/d Qxzs7/xObcYXPJdA8LWq8l1++z7EvXFKTOBd3GHBBzu5F/u6jI68HoifitGine6mETSb G847/Ptl61wjkZ4tJYHGVdiN8RGYTw0we3n8//9Ql1+/Mn0tGSzzSIvcYHKAm2Mpce+R ewWajEzhl3GOp9Ilrb7wkcZrw4YIjPCKcsPYmUm8uR/IiRnwip/ORLeSNU9Etmd09ijg 84HQ== X-Forwarded-Encrypted: i=1; AJvYcCWqp18lpOeNBaKHxh3tdgVRBCEjV6W00RxhyczA4J3//sHx9xr6hlmyBebW6MGCucQefQUo7yFl+o6Elg==@lists.postgresql.org X-Gm-Message-State: AOJu0YyWIuN7Wu/uE9GaeJXWYNutQ+lf/al+KRcIYTDui3RJrBNh4xHJ eiHyYCtMtTBmLBNVEYdZqMWdXkJG5Eh7Lgvd3k1NXUaiqmMItxfO2lCGoWZRSRafNS9kYGNvlr0 axDasQZevWp4Z0oiNWD24wUTZTwg1aqXgig== X-Gm-Gg: ASbGncvskaVWZlfQODDxEY6n1aFzsTD2Epx8OQCncoLMlhHF2p31UNUCT8NzsY2Odky YBdCG2xRsUseZJTtcj2wI4S/X+ptSLzCOsgo20oM7f7jX2S/NN++wO6XZOqW5KL/LtihcDnjGvt 7kU8WA4JBDEss7loTbnDuTlloq29/sZpIaGfzW2hhgHw4+KE7l9UJnahBOrtqN9vwLS2v62/AYE aCJXAm8FoZ5BS4vGrmp9w5m5HjnHrG7K+KWoqSpMPkUEuAJMDG0rAR07m7MyBwSCZGqJ77uAfKL KOnHto66GagHKs4GDWLVSyI/DMQTS4pOZqpXuYtA+tyja/1CXKSjZsyj X-Google-Smtp-Source: AGHT+IF/KV02qRWti2zzv10LePJ7na/8TDnWq8bgBoeZXgvGPbFyFXPCRdQsmNHgzHeMVRNIVJlNnRkblVBiXAWz6uY= X-Received: by 2002:a05:6808:1247:b0:450:b8da:b816 with SMTP id 5614622812f47-455869344c5mr1917194b6e.61.1765389646125; Wed, 10 Dec 2025 10:00:46 -0800 (PST) MIME-Version: 1.0 References: <72acf8ae4e56886081b9f632569f290d3246c33b.camel@cybertec.at> <8536f893e79693bd0a23d4cea7dbe0b6366378df.camel@cybertec.at> <647281.1765388029@sss.pgh.pa.us> In-Reply-To: <647281.1765388029@sss.pgh.pa.us> From: richard coleman Date: Wed, 10 Dec 2025 13:00:35 -0500 X-Gm-Features: AQt7F2rKDu6A1txFR2QJRqklOL3TseJSU8PU_t2Jhr4aVMZXBsJvNTGQCe3oxuY Message-ID: Subject: Re: database specific pg_read_all_data / pg_write_all_data To: Tom Lane Cc: "David G. Johnston" , Laurenz Albe , Pgsql-admin Content-Type: multipart/alternative; boundary="000000000000bf6b0106459cce35" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --000000000000bf6b0106459cce35 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Tom, You are *almost* there I think. By my understanding, which admittedly might be flawed, "pg_read_all_data" once given allows the role with that privlidge to litterally "read all data" across all databases in that cluster. So while one can revoke public connect privs to a database and keep a role with pg_read_all_data privs from connecting to it, you're otherwise pretty much out of luck. That option is unavailable in the situation where users have differing privs on the same cluster. For example, if user0 needs to have "read_all" privs in database0, "read_all" and "write_all" privs in database1, and various privs in database2 on the same cluster, you can't use the CONNECT nor pg_hba.conf workarounds. As soon as a role who's a member of "pg_read_all_data" can connect to a database in that cluster, it's game over. Doubly so for roles with the "pg_write_all_data" priv. These built-in roles are a much welcomed addition in PostgreSQL. Unfortunately in PostgreSQL, unlike other RDBMSs, roles are cluster wide not database specific. This leads to some interesting things in multi-database tools such as DBeaver which includes a seperate Roles folder in each PostgreSQL database connection containing copies of the exact same roles. Use the GUI to alter a role in the Roles folder for database0, potentially be amazed that database1, and every other database in that cluster, magically reflects the change. I'm not saying that is is nessicarrilly a bad thing, just different. What it does mean though is that cluster wide roles and privs can and do much more than one might suspect. This discussion of pg_read_all_data being a prime example. Basically I think that because of the reliance on cluster wide roles in PostgreSQL, it's potentially dangerous to introduce built-in roles with far ranging privs without having a machinaism to limit them to specific databases in that cluster. The only realistic way to take advantage of the extrodinarilly useful abilites they enable is to limit them to the relatively rare instances where there is only a single database on a cluster, or when the users can have the same access to all of the databases on that cluster. Hopefully I've made my self clear enough in this matter and have demonstrated how being able to limit built-in cluster specific privs in a per database way would be very useful. Thanks for taking the time, everyone, to read my missives and contribute your thoughts in this. rik. On Wed, Dec 10, 2025 at 12:33=E2=80=AFPM Tom Lane wrote= : > "David G. Johnston" writes: > > Fundamentally making group-role memberships per-database is a fundament= al > > change that seems quite unappealing to attempt without a solid use case > > that it will enable. > > Yeah, I think this would be bad from both the intellectual-complexity > and implementation-difficulty standpoints. > > However ... we've had multiple requests in the past to invent > database-specific roles. I wonder if it'd suffice for Richard's > purposes to create such roles and grant them pg_read_all_data. > > You can sort of do that today, in that you can muck with pg_hba.conf > or database CONNECT privileges to limit which DBs a role can log into. > But either answer works only at initial login; they don't constrain > SET ROLE, so they're not really adequate for permissions-limiting > purposes. I'm imagining a feature whereby a database-specific role > is flat out not available in other databases; can't SET ROLE to it, > can't GRANT privileges (at least on non-shared objects) to it. > Probably role membership would still be nominally global, but it > wouldn't matter if you couldn't use the role. > > This might still not pass the too-much-complexity test, but it > has the advantage of being something that there's been multiple > requests for. > > regards, tom lane > --000000000000bf6b0106459cce35 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Tom,=C2=A0

You are *almost* there I thi= nk.=C2=A0 By my understanding, which admittedly might be flawed, "pg_r= ead_all_data" once given allows the role with that privlidge to litter= ally "read all data" across all databases in that cluster.=C2=A0 = So while one can revoke public connect privs to a database and keep a role = with pg_read_all_data privs from connecting to it, you're otherwise pre= tty much out of luck.=C2=A0 That option is unavailable in the situation whe= re users have differing privs on the same cluster.=C2=A0 For example, if us= er0 needs to have "read_all" privs in database0, "read_all&q= uot; and "write_all" privs in database1, and various privs in dat= abase2 on the same cluster, you can't use the CONNECT nor pg_hba.conf w= orkarounds.=C2=A0 As soon as a role who's a member of=C2=A0
"pg= _read_all_data" can connect to a database in that cluster, it's ga= me over.=C2=A0 Doubly so for roles with the "pg_write_all_data" p= riv.

These built-in roles are a much welcomed addi= tion in PostgreSQL.=C2=A0 Unfortunately in PostgreSQL, unlike other RDBMSs,= roles are cluster wide not database specific.=C2=A0 This leads to some int= eresting things in multi-database tools such as DBeaver which includes a se= perate Roles folder in each PostgreSQL database connection containing copie= s of the exact same roles.=C2=A0 Use the GUI to alter a role in the Roles f= older for database0, potentially be amazed that database1, and every other = database in that cluster, magically reflects the change.=C2=A0 I'm not = saying that is is nessicarrilly a bad thing, just different.=C2=A0 What it = does mean though is that cluster wide roles and privs can and do much more = than one might suspect.=C2=A0 This discussion of pg_read_all_data being a p= rime example.=C2=A0 Basically I think that because of the reliance on clust= er wide roles in PostgreSQL, it's potentially dangerous to introduce bu= ilt-in roles with far ranging privs without having a machinaism to limit th= em to specific databases in that cluster.=C2=A0 The only realistic way to t= ake advantage of the extrodinarilly useful abilites they enable is to limit= them to the relatively rare instances where there is only a single databas= e on a cluster, or when the users can have the same access to all of the da= tabases on that cluster.

Hopefully I've made m= y self clear enough in this matter and have demonstrated how being able to = limit built-in cluster specific privs in a per database way would be very u= seful.

Thanks for taking the time, everyone, to re= ad my missives and contribute your thoughts in this.
rik.

On Wed, Dec 10, 2025 at 12:33=E2=80=AFPM Tom Lane <<= a href=3D"mailto:tgl@sss.pgh.pa.us">tgl@sss.pgh.pa.us> wrote:
"David G. Johnsto= n" <david.g.johnston@gmail.com> writes:
> Fundamentally making group-role memberships per-database is a fundamen= tal
> change that seems quite unappealing to attempt without a solid use cas= e
> that it will enable.

Yeah, I think this would be bad from both the intellectual-complexity
and implementation-difficulty standpoints.

However ... we've had multiple requests in the past to invent
database-specific roles.=C2=A0 I wonder if it'd suffice for Richard'= ;s
purposes to create such roles and grant them pg_read_all_data.

You can sort of do that today, in that you can muck with pg_hba.conf
or database CONNECT privileges to limit which DBs a role can log into.
But either answer works only at initial login; they don't constrain
SET ROLE, so they're not really adequate for permissions-limiting
purposes.=C2=A0 I'm imagining a feature whereby a database-specific rol= e
is flat out not available in other databases; can't SET ROLE to it,
can't GRANT privileges (at least on non-shared objects) to it.
Probably role membership would still be nominally global, but it
wouldn't matter if you couldn't use the role.

This might still not pass the too-much-complexity test, but it
has the advantage of being something that there's been multiple
requests for.

=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 regards, tom lane
--000000000000bf6b0106459cce35--