Sandbox an AI Agent's Postgres Access from Host Files
Lock the role, block file functions, isolate the process, and audit egress before an agent touches production data.

In restricted mode, the tool will execute a FROM-clause call to pg_read_file('/etc/passwd') and return the file, but it still blocks the same function when called directly. The gap is a parser coverage problem. For an operator, that is a host boundary failure, not a database-only bug.
A 2026 Synvestable report puts the MCP ecosystem at 97 million monthly SDK downloads, more than 10,000 active public servers, and 28 percent of Fortune 500 companies running MCP servers in production. That scale makes a database tool a serious exposure. The report describes a production environment, not a lab. An agent with database access can become a path to host files if the sandbox is thin.
The bypass turns a query into a file read
The Postgres MCP Pro flaw is tracked as CVE-2026-85620 and carries a CVSS v4.0 score of 9.2. George Chen reported it on June 6, 2026. The safe_sql.py layer misses FROM-clause functions because its allowlist check applies only to FuncCall AST nodes, not to RangeFunction nodes.
With the flaw, an attacker can pull files that the database server can reach, such as configuration data, credentials, and TLS keys, extending access from the database to the host filesystem. At the time of the article, no patched release beyond version 0.3.0 had been published, and a fix was under review as an open pull request in the crystaldba/postgres-mcp repository. If you are running that package, verify the patch and parser behavior before trusting the control and document the result. Treat the control as unverified until you confirm both.
Five controls close the gap
Start with the role, then tighten the parser, isolate the process, and audit egress. The order matters because each control covers a different escape path. Treat the agent as untrusted inside the database. The role sets the boundary. The parser narrows it. The host boundary closes it. Egress audit is the record that shows which control failed. The record also gives the next audit a starting point.
- Create a least-privilege database role for the agent. Grant only the tables, schemas, and operations the agent needs. Done looks like a role that cannot read system catalogs, create objects, or call administrative functions.
- Strip file and superuser functions from the agent's reachable surface. Revoke execute on file functions and any other function that touches the filesystem. Done looks like a query that names a file function returning a permission error, not a result set.
- Enforce a parser-level allowlist, not a string filter. Your parser must reject unknown functions wherever they appear, including table functions, subqueries, and set-returning calls. Done looks like a file read failing before it reaches the database.
- Isolate the database process from the host. Run the agent-facing database instance in a container, VM, or dedicated host with a minimal filesystem, no mounted secrets, and no credentials outside the database. Done looks like a process that cannot see host files even if a file function executes.
- Audit egress and query logs. Capture every statement the agent sends, every function it calls, and every network path the database process can reach. Done looks like an alert when a file function, an outbound connection, or a data export appears in the log.
Verification is part of the sandbox
Run the sandbox through a red-team pass. Ask the agent to read a file, list a directory, copy data out, and call a function it should not have. The test should fail at the role, the parser, or the host boundary. If it succeeds, the sandbox is not done. Keep the test results next to the deployment record. Treat the results as evidence, not a checkbox. Keep them current. If a new tool or a new database grant changes the surface, rerun the same checks.