Back to blog

How to Audit Every Query Your AI Agent Runs

Spencer Pauly
Spencer Pauly
4 min read
How to Audit Every Query Your AI Agent Runs

The first time an AI agent does something surprising to your database, the question you'll ask is "what exactly did it run?" If you can't answer that quickly, you've got a real problem, and it's worth setting up the answer before you need it rather than during the incident.

Auditing agent queries isn't complicated. It's just one of those things everyone agrees is important and few people actually wire up, because the happy path works fine without it. Here's how to do it at a few levels of effort.

What you're actually trying to capture

For a useful audit trail you want, per query: the exact SQL that ran, when it ran, which agent or user triggered it, how long it took, and how many rows came back. That last pair matters more than people expect. A query that returned 400,000 rows or took 30 seconds is the one you want to find later, and a log that only records "a SELECT happened" won't help you find it.

Level one: Postgres can log it for you

If you just need a record and don't care about structure, the database will write one. Set log_statement = 'all' for the agent's role and Postgres logs every statement it runs:

alter role agent_readonly set log_statement = 'all';

Pair it with log_min_duration_statement to flag slow ones, and pg_stat_statements to see aggregate patterns over time. This is the cheap version and it works. The downside is that the logs are noisy, mixed in with everything else, and not easy to attribute back to a specific agent session or to slice by "show me everything this agent did Tuesday." Good enough for forensics, awkward for routine review.

Level two: log at the boundary, not the database

The better place to capture this is the layer between the agent and the database, if you have one. A proxy or MCP server sees every query before it runs, knows which session asked, and can write a clean structured record: timestamp, session id, the SQL, row count, duration, allowed or blocked.

The advantage over database logs is attribution and structure. You can answer "what did this agent do today" without grepping, you can see the queries that got blocked (which the database never sees, because they never ran), and you can build alerts on top of it. The blocked-query record is quietly the most useful part — it tells you when the agent tried to do something it shouldn't, which is exactly the signal you want before a real incident.

This is one of the reasons I built QueryBear to log every call by default, including the ones it rejects. But you can build the same thing with a small proxy of your own. The point is to capture it where the intent is visible, not after the database has already forgotten who asked.

Level three: make the log do something

A log nobody reads is just disk usage. The version that earns its keep is one that's wired to surface the things worth knowing.

Alert on queries that return more rows than any normal query should. Alert on a spike in blocked queries, because that often means a prompt-injection attempt or a misconfigured agent retrying something forbidden. Alert on queries hitting tables the agent has never touched before. None of these need to be fancy. A threshold and a notification covers most of the value, and it turns the audit log from a thing you consult after a problem into a thing that warns you before one.

The mindset shift

Here's the reframe that made me take this seriously. With a human running queries, you mostly trust intent and audit by exception. With an agent, you should assume you'll need the record, because the agent will eventually do something its prompt didn't quite mean, and "eventually" is not a question of if.

So set it up early, while it's a five-minute config change, not during an incident when you're trying to reconstruct what happened from database logs you didn't think to enable. The audit trail is the cheapest insurance in this whole stack. You just have to buy it before the fire, not after.

Database Access

Give Your AI Agents
Database Access. Securely.

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