| From: | Andrei Lepikhov <lepihov(at)gmail(dot)com> |
|---|---|
| To: | Jack Bonatakis <jack(at)bonatak(dot)is>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org> |
| Subject: | Re: Read-only connection mode for AI workflows. |
| Date: | 2026-03-16 21:01:22 |
| Message-ID: | fab6a5f3-df9f-4bd7-b2ac-434a17303547@gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
On 16/3/26 20:28, Jack Bonatakis wrote:
> On Mon, Mar 16, 2026, at 2:08 PM, Andrei Lepikhov wrote:
>> I believe the pg_readonly [1] extension does what you're looking for, so
>> you might want to give it a try.
>
> Hi Andrei,
>
> Please correct me if I am mistaken, but it looks like pg_readonly
> operates at the database or cluster level.
Exactly. It works cluster-wide at the moment. But it is very simple to
allow it to establish a read-only mode in a backend. That's exactly why
I requested a full picture.
> If I understand Mat's
> proposal correctly, and based on my own experience integrating LLM-based
> tools with databases, one might desire to set a particular connection to
> be read-only while leaving the rest of the connections to operate
> normally (read/write). Now, I would hope that someone building an AI
> integration that is not intended to write to or manage the system would
> be doing so off of a read-replica where pg_readonly would make more
> sense, but I would wager that this will not always be the case.
>
>> Connection setup is usually not AI controlled while the SQL executed
>> sometimes is. That's why being able to control read-only mode on the
>> connection level would be useful.
Ok, such a mode will reduce minor pg_readonly overhead down to almost
zero. The practical questions I need to know in advance:
1. Is it OK to call the LOAD command at the beginning of connection
establishment (make it dynamically loadable and strictly
connection-dependent)
2. Should it be able to change the mode inside such a read-only session
(let's say, under a superuser).
>
> Additionally, I believe this is the key point. Setting read-only at the
> connection level alleviates any concern about an AI agent exploiting
> misconfigured permissions to escalate its privileges (e.g. `select
> unset_cluster_readonly(); drop table users;`).
>
>> Also, which commands do you want to restrict? For instance, vacuum
>> isn't a DML command, but it can still change the state of table pages
>> and pg_catalog.
This functionality is now out of the Postgres core logic. It is not hard
to add to the extension, though, let's say as a string GUC, where you
may add any utility command you want to reject in read-only mode. So,
depends on specific cases.
>
> From my perspective, many AI integrations would want to limit just
> about anything that can change the state of the database. So yes,
> vacuum, checkpoint, likely analyze (although I can see an argument for
> allowing a read-only connection to run analyze), and other similar
> commands, as well as of course traditional DML and DDL.
>
As I've said, it is easy unless you want to suspend internal services as
well (like autovacuum). It is also doable within (I envision) the SMGR
plugin, but a little more dangerous; this feature just needs more design
and coding effort for a certain answer.
> That said, once you start thinking about the precise scope of what
> should be allowed or disallowed, the design space becomes quite large.
> It may be worth clarifying the intended guarantees of such a feature
> before discussing implementation details.
Right now as an extension pg_readonly guarantees standard core
XactReadOnly behaviour.
>
> I do think the underlying problem of safely exposing databases to
> automated agents is becoming increasingly common, so it seems like a
> useful area to explore.
Thanks for your profound feedback!
--
regards, Andrei Lepikhov,
pgEdge
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Masahiko Sawada | 2026-03-16 21:03:39 | Re: Patch for migration of the pg_commit_ts directory |
| Previous Message | Andrew Dunstan | 2026-03-16 20:59:56 | Re: Emitting JSON to file using COPY TO |