Re: Grant read-only access to exactly one database amongst many

From: Graham Leggett <minfrin(at)sharp(dot)fm>
To: "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com>
Cc: pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: Grant read-only access to exactly one database amongst many
Date: 2024-02-05 08:51:50
Message-ID: 6B60E58E-2E34-4360-808B-5A74C2564C86@sharp.fm
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 05 Feb 2024, at 00:54, David G. Johnston <david(dot)g(dot)johnston(at)gmail(dot)com> wrote:

> I have a postgresql 15 instance with two databases in it, and I have a need to grant read-only access to one of those databases to a given user.
>>
>> To do this I created a dedicated role for readonly access to the database db1:
>>
>> CREATE ROLE "dv_read_db1"
>> GRANT CONNECT ON DATABASE db1 TO dv_read_db1
>
> This grant is basically pointless since by default all roles can connect everywhere via the PUBLIC pseudo-role. You need to revoke that grant, or even alter it being given out by default.

More on this point at the end…

>> Trouble is, I can create tables in db1 which is write access.
>
> Since in v15 PUBLIC also gets CREATE on the public schema.

…ouch…

>> I can also connect to db2 (bad),
>
> See my comment regarding the pointless grant in a default setup.
>
>> and I can enumerate the tables in db2 (bad),
>
> Connect privilege grants reading all catalog data by design.
>
>>
>> I appears the mechanism I am using above has insecure side effects.
>
> It has, from your expectation, insecure defaults which you never changed. We changed public schema in v16 but the ease-of-use database connecting remains.

It looks like changing these defaults is likely to be difficult, which is why I posted here.

I want to optionally allow user minfrin to access both databases by doing this:

CREATE USER minfrin LOGIN;
GRANT dv_read_db1 TO minfrin;
GRANT dv_read_db2 TO minfrin;

If I am understanding you correctly to prevent dv_read_db1 from connecting to db2, I need to actively revoke access to db2. Also, to prevent dv_read_db2 from connecting to db1, I need to actively revoke access to db1.

Would the two grants above dv_read_db1 and dv_read_db2 not cause the unintended side effect of revoking access to each other, resulting in no access being allowed at all?

Also, how do you handle the race condition between the time a database db3 is created, and the the time all readonly users have their access revoked to db3?

Regards,
Graham

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Sutou Kouhei 2024-02-05 09:05:15 Re: Make COPY format extendable: Extract COPY TO format implementations
Previous Message Alvaro Herrera 2024-02-05 08:51:33 Re: cataloguing NOT NULL constraints