Est.

PostgreSQL Permission Boundaries for Database-Connected Agents

Layered permission boundaries protect PostgreSQL from autonomous agent overreach.

· 9 min read
Cover illustration for “PostgreSQL Permission Boundaries for Database-Connected Agents”
Agent Authorization Patterns · November 3, 2026 · 9 min read · 2,013 words

Connecting AI agents to PostgreSQL safely requires more than a read-only password. It requires layered permission boundaries, including dedicated roles, curated views, row-level security, and query validation outside the agent’s control. The central rule is simple. The agent may decide how to pursue its assignment, but the database and execution boundary must decide what it can reach and do.

Why agents break the assumptions underneath PostgreSQL's human-scale permission model

A human opens a record through an interface and decides what to carry elsewhere. An agent can sweep every reachable record and pour the results into model context, where a hidden instruction can steer its next call. The password does not distinguish these two behaviors. Every request may be credential-valid even when the sequence exceeds the assignment.

Redpanda’s paper on policy enforcement describes this as a wrong-sized credential envelope. Credentials define what is reachable. A churn-analysis assignment, for example, may expose billing data, support history, and authentication tables if the role permits it. Analysis is not an access restriction.

That mismatch makes the agent’s judgment unsuitable as the final authority. Agents are non-deterministic, while security enforcement needs deterministic reliability. The structural problem stems from the human-scale access assumptions surrounding agents’ inherited credentials, which were never designed for this pattern of use.

What shared roles, broad grants, and read-only transactions actually leave exposed

Sharing one PostgreSQL role across agents combines their blast radius and erases useful attribution. A database log entry under that role cannot identify the responsible agent or workflow. Granting pg_read_all_data creates a different problem. It reaches every table, including tables created after the grant, making convenience a forward-looking claim on the data plane.

PostgreSQL 18 permits a superuser inside BEGIN READ ONLY to use COPY … TO <path> to write server-side files and COPY … TO PROGRAM <cmd> to execute commands as the database server’s OS user. SELECT pg_read_file() can also read server-side files. Read-only is not a sandbox with better stationery.

The predefined roles pg_read_server_files, pg_write_server_files, and pg_execute_server_program extend these capabilities to non-superusers. Two hops of inherited membership can deliver working program execution to a role with no direct grants or dangerous attributes. Safety therefore depends on checking the permissions behind the transaction mode and the role definition, even when both look safe.

How prompt injection at the MCP layer converts database trust into an attack surface

Indirect prompt injection begins when an attacker places instructions in data an agent reads. The agent may then treat that content as authority and make privileged tool calls using credentials the attacker does not possess. Database trust becomes borrowed power. The point of failure is where returned text becomes instruction.

CVE-2026-85787 in Amazon’s awslabs/postgres-mcp-server illustrates a related boundary failure. Its incomplete disallowed-input list, classified as CWE-184, permits a read-only bypass and unauthorized modification. Crafted SQL in content processed through the MCP workflow can pivot into writes. Remediation requires version 1.1.7 or later and read-only PostgreSQL role permissions.

The deprecated @modelcontextprotocol/server-postgres also passes user-provided SQL into query strings without parameterization, enabling SQL injection that bypasses read-only mode. The community alternative mcp-server-pg uses parameterized queries, but there is no single official replacement. Neither SQL validation nor instructions to “be careful” resolve the agent’s failure to separate trusted instructions from untrusted data.

The May 2026 Marimo incident shows the speed available after compromise, though its entry point was pre-auth RCE through CVE-2026-39987. An attacker used an LLM agent for autonomous post-exploitation, including network reconnaissance, AWS credential harvesting, and exfiltration of a complete PostgreSQL database in under two minutes.

Building the dedicated agent role — the minimal grant set that bounds the blast radius

The first construction step is a dedicated role for each agent workflow. PostgreSQL 18’s role controls provide the required attributes, namely NOSUPERUSER, NOBYPASSRLS, NOCREATEROLE, NOCREATEDB, NOREPLICATION, and a fixed CONNECTION LIMIT. The connection limit is checked during startup after authentication, so excess connections are refused before SQL executes.

Object grants should stop at CONNECT on the database, USAGE on one approved schema, and SELECT on specific named views. The role must not own tables, because owners bypass row-level security by default unless FORCE ROW LEVEL SECURITY is set. Ownership is a quiet escape hatch.

Permission review must also follow inherited membership chains. Access to the three server-file and program-execution roles should be treated as equivalent to superuser access for this purpose. Separate workflow roles then make permission reviews, incident scoping, and audit attribution tractable. Without that separation, later controls rest on an identity that is already too broad.

Using schemas and views to define the approved data surface

One approved schema can contain curated views, while raw application tables remain in a separate schema the agent cannot reach. Granting USAGE on the production schema undermines that separation by allowing schema inspection tools to expose a broader inventory of tables. Discovery itself can support reconnaissance during an injection attack.

Views make the intended exposure concrete and reviewable. A customer_health view can provide account ID, plan, renewal date, and usage trend without exposing password hashes, payment tokens, private notes, or unnecessary personal data. The agent receives business context rather than the application’s entire filing cabinet. This is more precise than granting raw-table access and expecting each generated query to omit sensitive columns.

Broad grants such as SELECT ON ALL TABLES IN SCHEMA analytics need close checks when used with default privileges, because they can give access to objects created later. For the named-view design, defaults must preserve that scope. Metadata inspection should also stay within the approved surface.

Row-level security as the data-plane boundary for multi-tenant and scoped workflows

A curated view can still span several tenants or workflow contexts. Row-level security, or RLS, supplies the next boundary by restricting the rows available for the current task. Three conditions must hold together. The agent must connect as a non-owner without BYPASSRLS, the table must have ENABLE ROW LEVEL SECURITY set, and every allowed command must have an explicit policy. With no policy defined, no rows are visible.

The bypass paths deserve attention because they are quiet. BYPASSRLS defeats row policies unconditionally, while table owners bypass them unless FORCE ROW LEVEL SECURITY is set. A shared service account without tenant-scoped policies can therefore read across tenants without an authorization error.

PostgreSQL’s documentation identifies a subtler limit in referential integrity checks. Unique and foreign-key constraints bypass row security, so the schema must be designed with the risk of covert-channel leaks through those checks in mind. RLS depends on role architecture and schema design to enforce, in the data plane, the scope that the role layer declared.

Enforcing the query boundary — what must be validated before SQL reaches the database

The next construction step is an execution boundary between generated SQL and PostgreSQL. Role grants and RLS restrict access, but they do not establish an acceptable query shape or bound result volume. Every generated statement needs parsing or inspection before execution. The boundary should permit only a single SELECT, reject writes, DDL, COPY, state-mutating functions, and multi-statement execution, and impose row and execution-time limits.

Regex hooks can supplement that boundary. CTEs, writable views, and indirect SQL constructions defeat simple text matching. Parameterized queries are also required throughout. The deprecated MCP server’s injection vulnerability shows why calling a server read-only does not make unsafe query construction safe.

How the agent connects sets how much freedom this boundary must keep in check. Direct driver access is appropriate only in controlled environments with a dedicated read-only role. Fixed API endpoints are safest for high-risk workflows because the application owns the SQL and validates parameters, but each query requires engineering work. Managed natural-language query layers offer broader self-service analytics coverage with enforced read-only controls, while introducing trust in the layer performing that enforcement.

Why static database permissions are not enough when agent tasks change mid-execution

Even an action with the right limits can become unauthorized while an agent is working. A budget may be consumed by another agent, an approval rescinded, or a risk signal changed between authorization and execution. The permission was valid when checked. Its supporting facts were not frozen.

The MasuGate paper calls this stale authorization. It defines policy-state serializability as the requirement that committed effects be explainable as authorized against the policy state immediately before they occur. A decision made for one request cannot ensure that condition holds when state that matters changes outside the database session. Static grants say what the principal is allowed to do, but do not show whether every business condition still holds.

The paper’s PostgreSQL-backed prototype prevents stale authorizations missed by baseline request-local governance in a scripted procurement workflow involving shared budgets and inventory. Agents issuing refunds, reserving inventory, initiating transfers, or modifying operational state need governance that tracks mutable facts across concurrent sessions.

Enforcing the policy boundary outside the agent's reasoning loop

The architectural requirement tying these layers together is independence from the agent. Enforcement must run where the agent session cannot change it. The OBPE paper formalizes a trusted tool boundary that authorizes operations and resources, narrows queries or shapes arguments, and filters returned records and fields before they enter model context. The guard does not take instructions from the guarded.

The owner of the data policy sets the largest grant allowed. Agent-specific policy can only narrow it, never widen it. Semantic gating adds another check, allowing an otherwise authorized call to be denied or held for external approval because of argument values or changing state. A cumulative limit or risk signal can stop an action without asking the agent to police itself.

The paper reports that observed trace failure was near-zero with the enforcement bundle it tested across thousands of trials, four models, and 20 response-adaptive red-team tasks. Safe-useful completion rose by 21.8 points in the paired, cluster-weighted analysis. The limits are equally instructive. Four final answers reconstructed an exact value that never entered context, and another trial used filtered row counts as an oracle. Removing a field does not prove noninterference, meaning that protected information cannot influence an observable result.

Framework-level privilege control and what the research shows about dynamic policy enforcement

Framework-level controls also enforce rules on tool names, arguments, and the scope of a task as it changes. Progent, last revised in May 2026, represents privileges as symbolic rules and uses monotonic confinement. A solver can prove that an automatic policy change narrows access, but a change that widens access needs external approval. On AgentDojo, Progent reduces attack success to 1.0%.

SkillScope’s 2026 research addresses a related problem of context. An action necessary for one user prompt may be over-privileged for another. Across real-world skills, it reports that it detects over-privileged actions well and triggers far fewer of them while still allowing legitimate tasks to be completed.

The unresolved edge is policy quality itself. Progent’s symbolic policies are LLM-generated, so deterministic enforcement does not make the policy inputs deterministic or correct. Framework controls are therefore useful for constraining which tools and arguments an agent may use, while roles, RLS, and query validation remain necessary boundaries around database execution.

Observability across the full agent execution path, not just the database log

Database logs show only part of an agent’s behavior. An investigation also needs to connect the role and executed query to returned rows, preceding and subsequent tool calls, and any response content that should have been filtered. Otherwise, the SQL can look legitimate while the surrounding trajectory explains the violation. Attribution needs the whole chain.

Harvard’s 2026 TrajectoryDB paper treats these trajectories as a distinct data-management workload. They combine ordered, nested execution with repeated text and lineage between decisions and their supporting messages or tool results. Reconstructing the context visible to a model invocation or tracing a judgment to its evidence requires application-specific processing in existing systems. That gap complicates investigation even when database logging is intact.

For operational practice, complete audit records provide more than a retrospective explanation. They make it possible to detect an approached or crossed boundary, attribute the action to an agent and task, and tighten policy before another occurrence. Runtime monitoring and enforceable controls serve different jobs, and each needs the other.

Sources

  1. Stateful Governance for Concurrent Agentic Systems
  2. If Agents Were Angels, No Governance Would Be Necessary: Out-of-Band Policy Enforcement at a Trusted Tool Boundary
  3. TrajectoryDB: A New Database for Agent Trajectories

More in Agent Authorization Patterns