A read-only Postgres role for AI agents is the right first step. It is also not enough on its own.
Most guides stop at GRANT SELECT. We ran the usual setup on PostgreSQL 16, tried to get around it the way a manipulated agent or a careless query would, and found seven places where "read-only" doesn't mean what people assume. Each one comes with the SQL to reproduce it and the fix.
Quick answer
A read-only Postgres role for an AI agent should be a dedicated login role with no superuser or BYPASSRLS, SELECT granted only on the columns the agent needs, and timeouts set. But default_transaction_read_only and statement_timeout are defaults that a session can change, a SECURITY DEFINER function can still write, and anything you grant can still be read by a manipulated agent.…