How to give an AI agent read-only database access

Handing an AI agent your database is a real risk if you do it naively. Here's what read-only should actually mean — and the layers that make it hold.

"Just make it read-only" is the right instinct and the wrong stopping point. A read-only Postgres role does stop writes — but it doesn't cap an expensive query, doesn't limit which tables the agent sees, doesn't give you a way to cut off one misbehaving agent, and leaves no record of what ran. For an autonomous agent that can generate and execute SQL on its own, you want more than one control.

The layers that make "read-only" real

1. A read-only database role

Start here. Create a dedicated Postgres user with SELECT-only grants — ideally against a replica. This is your floor, not your ceiling.

2. Statement classification before execution

Parse and classify each statement and reject writes, DDL and dangerous functions before they reach the database. This matters because read-only transactions alone have been bypassed: the archived official Postgres MCP server shipped a documented SQL-injection that escaped its read-only transaction. Classify first, then run — defense in depth.

3. A read-only transaction

Execute inside a read-only transaction as a second wall, so anything the classifier misses still can't mutate data.

4. Resource limits

Cap result size and set a query timeout. "Read-only" doesn't stop a SELECT that scans a billion rows — limits do.

5. Revocable, per-agent keys

Give each agent its own key so you can revoke one without touching the others, and never expose the database password to the agent at all.

6. An audit trail

Log every query with the key that ran it. When someone asks "what has the AI touched?", you need an answer.

Doing all six without building it yourself

The AI2SQL Gateway is these layers as a hosted service. You add a database, get a revocable key, and your agent connects over MCP — read-only enforced two ways, results bounded, every call logged. No server to run.

Claude Code — terminal
$ claude mcp add --transport http ai2sql \
    https://builder.ai2sql.io/api/mcp \
    --header "x-ai2sql-key: $AI2SQL_KEY" \
    --header "x-ai2sql-connection: $CONNECTION_ID"
✓ ai2sql connected — 3 tools available
  run_query · describe_schema · list_connections

Get $AI2SQL_KEY and $CONNECTION_ID from the AI2SQL Gateway — connect a database and the setup wizard generates both for you.

If you'd rather run it yourself, self-hosted options like Postgres MCP Pro and DBHub implement several of these layers in open source — the trade-off is that you operate and secure the process. See how the choices compare in AI2SQL Gateway vs a raw Postgres MCP server.

Frequently asked

Isn't a read-only database user enough? +

It's a good first layer, and you should use one. But a read-only role still allows expensive queries, still exposes every table the role can see, and gives you no per-agent revocation or audit trail. A gateway adds statement classification, row limits, timeouts, revocable keys and logging on top.

How does the gateway enforce read-only? +

Two layers. First, every statement is classified before execution — INSERT, UPDATE, DELETE, DDL and dangerous functions are rejected. Second, the query runs inside a read-only transaction, so even a statement that slipped past the classifier cannot write.

Why does statement classification matter if there's a read-only transaction? +

Because read-only transactions alone have been bypassed in the wild — the archived official Postgres MCP server had a documented SQL-injection that escaped its read-only transaction. Classifying statements first is defense in depth.

Can I still let the agent write later? +

The gateway is read-only by design — that's the safety guarantee. Write workflows belong to change-management tools with review and approval, not to an autonomous agent's query path.

Give your agent a database it can't break

Connect a database, grab a key, paste one config. Read-only, logged and revocable from the first query.

Start free →

Related guides