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


Reply via email to