Back to blog

I Gave an AI Agent Database Access for a Month. Here's the Log.

Spencer Pauly
Spencer Pauly
5 min read
I Gave an AI Agent Database Access for a Month. Here's the Log.

I gave a coding agent standing access to a real (non-production, but real-data-shaped) database for a month, through the same read-only, logged, capped setup I'd recommend to anyone. Then I read every query it ran. The goal was to find out what actually happens when an agent has database access day to day, not in a demo, not in a threat-model thought experiment, but in the boring reality of a month of use.

Here's what the log actually showed, including the parts I didn't expect.

The boring majority

The overwhelming finding is anticlimactic: most of what the agent did was fine, useful, and exactly what I'd want. It answered questions, pulled counts, checked specific records while debugging, and helped me understand data shapes before writing code against them. The median query was a simple, scoped SELECT that a junior engineer would write. Hundreds of those, doing real work, saving real time.

If you were hoping for a horror story, the headline is that there mostly isn't one, and that's the actual point. With the guardrails on, a month of agent database access is uneventful in the way you want infrastructure to be uneventful. The drama is all in the setups that skip the guardrails.

The handful of moments that mattered

But "mostly fine" isn't "entirely fine," and the log caught the exceptions, which is the whole reason to have a log.

A few times, the agent wrote a query that would have been a problem without the caps. The clearest one: I asked it to "look at the events for this user," and it wrote an unbounded SELECT * from events where user_id = ... against a user who happened to have an enormous event history. Without a row cap, that pulls back a wall of data, floods the agent's own context, and does real I/O. With the cap, it returned the first slice and moved on. No harm, but the log made it visible that the instinct toward "just select everything" is always there.

Twice it tried something the read-only role rejected. Not maliciously — I'd asked it to "clean up" some test data, and its plan included a DELETE. The role refused, the agent adapted and instead showed me what it would have deleted so I could decide. That's exactly the failure mode I wanted to confirm: the agent's plan was wrong, the boundary caught it, and nothing bad happened. Read it in the log and it's a non-event. Imagine it without the boundary and it's a restore-from-backup afternoon.

What surprised me

The thing I didn't predict was how the agent behaved when it was uncertain. A capable agent, when it can't get the data one way, tries another. I watched it, blocked from a DELETE, pivot to a SELECT to show me the rows instead. I watched it, when a query returned a capped result, write a COUNT to find out how big the full set actually was. It's resourceful, and resourcefulness cuts both ways. The same persistence that makes it useful is the thing that, without limits, would have it retrying a heavy query in a loop at 3am. The guardrails aren't there because the agent is dumb. They're there because it's persistent.

The other surprise was how much I valued the log even though almost nothing went wrong. I didn't read it because I was worried. I read it because it was genuinely informative — it showed me how the agent thinks about my data, which queries it reaches for, where my schema confused it. The log turned out to be a feedback loop on my own data model, not just a security artifact. The places the agent wrote a weird query were usually places my schema was unclear, and I fixed a few column descriptions because of it.

What I'd tell someone before they try this

Three things, and they're the same three I'd put on any checklist.

Cap the results before you do anything else. The single most common rough edge wasn't malice, it was width — the agent's habit of selecting everything. A row cap turns that from a problem into a shrug.

Enforce read-only at the role, not the prompt. The two times the agent's plan included a write, the role is what saved it. A prompt instruction would have been a coin flip.

And keep the log, then actually read it. Not because you expect disaster. Because it's the only way to know what the month actually contained, and because reading it taught me more about my own data than about the agent.

A month in, my honest summary is that supervised, guard-railed agent database access is far more boring than the discourse suggests, and the boringness is earned entirely by the guardrails. Take them away and every uneventful query in my log becomes a coin flip. That's the trade, and it's a good one. The setup I used is essentially what QueryBear does by default, but a hand-rolled read-only role with caps and logging gets you the same boring, useful month. Boring is the goal. Boring is what safe looks like from the inside.

Database Access

Give Your AI Agents
Database Access. Securely.

Connect any database. Control permissions. Audit every query. All running locally on your machine.