Knowledge Engineering · Action

Your Team's SQL Gets Reviewed. Your Agent's Goes Straight to the Database.

Every query your engineers write passes a review before it reaches production. Then you connect an AI agent to the same database, and the SQL it writes runs the moment it is written. So the one query nobody reads is the one written by the component you should trust least. Why? Because a model that can be talked into anything is now composing statements against your live data. A governed data layer puts the review back: every statement the agent writes is parsed and proven safe before a cursor ever opens.

Infozense Knowledge Engineering · CIO · CISO · Head of Data · ~6 minutes

This is the Action piece of the Infozense Knowledge Engineering library. The data layer beneath your agent has five gates: Input (who may ask) · Egress (what may leave) · Output (safe and true) · Action (who approves) · Operational (prove it later). This piece is about the fourth: Action, the gate that decides what your AI is allowed to actually do to a live system.

Two paths to the same database: an engineer's SQL passes through a review before it reaches the database, while an AI agent's SQL passes through nothing at all.
Both paths end at the same data. Only one is read by someone first.

Your engineers do not write SQL straight into production. Someone reviews it. There is a pull request, or a DBA, or at minimum a second pair of eyes. You built that habit because a query is not a question. A query is an instruction, and instructions against live data deserve a look before they run.

Then you connect an AI agent to the same database, because documents and tables answer different questions. A document tells you what the policy says. Only a query tells you what the numbers did last quarter.

And the SQL that agent writes runs the moment it is written.

No pull request. No DBA. No second pair of eyes. The one query in your organization that nobody reads is the one written by the component you should trust least, because it is the only one that can be talked into writing something it was never meant to write.

Who this is for

Most teams do not have this problem yet, because their AI only reads documents. If nothing you have connected to a model can reach a live database, you can stop here.

You have this problem the moment an agent holds a database connection. Text to SQL over a warehouse. A copilot that answers from operational tables. Any assistant wired to a reporting replica so it can quote real numbers. If a stranger can put text in front of that agent, and the agent turns text into SQL, then a stranger is composing statements against your data. That stranger needs no exploit and no SQL of their own, only the words that make the agent write it. That is the whole risk.

The model is not the attacker. It is the instrument.

Text arrives from two sources: your user's question, and text from elsewhere such as a document, a ticket, or a page the agent was asked to read. The model turns instructions written in text into SQL and cannot tell which text was yours. The agent runs what the model wrote and holds the connection and the credentials. One statement reaches your database.
Every part does its job. That is why a better model does not fix this.

It is tempting to treat this as a question of how good the model is. It is not. A better model writes better SQL, and it will still write whatever a sufficiently persuasive prompt asks it to write, because following instructions written in text is precisely what it is for.

So the useful assumption is the uncomfortable one: treat every statement your agent produces as though an attacker wrote it. Not because the model is hostile, but because the text it read might have been, and from the inside there is no reliable way to tell those two cases apart.

Once you assume that, the question stops being "is the model trustworthy" and becomes "what is this statement allowed to do". The second question has an answer.

What checking it properly actually means

The Action gate proves the agent's statement before any connection opens: exactly one statement, it only reads, every table and column resolves to the card, every function is on the allow-list, and it is refused unless all of it is provable. Only then does a cursor open on the database.
The statement is proved first. Until it is, no cursor opens.

The tempting shortcut is to scan the SQL for dangerous words. Look for DROP, look for DELETE, block anything with a semicolon. This is worse than useless, because it creates confidence without safety. SQL has too many ways to say the same thing, and a string that survives a keyword scan can still do damage.

Real checking means parsing. In a governed data layer the agent's SQL is handed to a real SQL parser and the resulting syntax tree is walked, before any connection to the database is opened. The check proves a specific set of things and refuses anything it cannot prove:

  • It is exactly one statement. Not two, and not a statement with a comment hiding a third. Everything below is proven about a single statement, so a second one riding in behind the first would arrive proven of nothing.
  • That statement only reads. A SELECT, a UNION, or a WITH. Anything that adds, changes, or removes data (an INSERT, an UPDATE, a DELETE, a DROP) is a rejection, not a warning, and it is caught wherever it sits in the statement, including inside a WITH body.
  • Every table and every column resolves against the catalog card for that connection. A name that cannot be resolved to exactly one real table and column is refused, which means the agent cannot reach a table simply by naming one that was never offered to it.
  • Every function is on an allow-list. Aggregates, arithmetic, string and date handling: the things analysis genuinely needs. A function that is not on the list is a rejection. It is an allow-list rather than a block-list because functions are where database engines keep their escape hatches. Some can read files or reach the network from inside an innocent looking read, and an allow-list refuses the dangerous functions nobody has heard of yet along with the ones everybody has.
  • Tricks are refused by name, including the executable comment markers that some engines quietly run as real SQL. Those are thrown out before parsing even starts, because a parser reads a comment as nothing while the engine would run it as code, and a proof about the parsed statement is worth nothing if the engine executes a different one.

The whole check runs as a pure function: a calculation that takes the statement in, hands a verdict back, and touches nothing else. It opens no connection and reads no data. It cannot be made to leak by being asked the wrong question, because it has nothing to leak.

The rule underneath all of it: anything the layer cannot prove is safe is refused. A parse failure is a refusal. A name it cannot resolve is a refusal. An internal error inside the checker itself is a refusal. There is no branch where confusion means proceed.

The permission to run is not a piece of paper

There is a failure mode worth naming, because it is where a home-built version of this usually breaks. If approval is a token, a flag, or a row in a table saying "this query was checked", then approval can be copied, replayed, or forged. The check becomes theatre the first time something reuses yesterday's approval on today's query.

In a governed data layer the approval is not data at all. It is a live object that only the checker can create, and that deliberately cannot be written down or sent anywhere. The component that opens the database connection refuses to open one without being handed that object directly. A blessing that cannot be serialized cannot be stolen, replayed, or minted by anything except the check itself.

What runs, and what is written down

Two more things hold at the same time, and they matter to whoever has to answer for this later.

The query runs inside the asker's boundary. The agent cannot reach a connection belonging to another part of the business, and permission to run queries at all is a distinct grant, separate from permission to read documents. Being allowed to ask the AI a question is not the same as being allowed to make it query production.

And every attempt is recorded, including every refusal. A rejected statement is not a non-event to be dropped on the floor. It is the most interesting line in the log, because it is what an attempt looks like. The record keeps the statement and the row count. It does not keep the rows.

The bottom line

Connecting an agent to your database is not the mistake. It is the point, and the value is real. The mistake is assuming that the discipline you apply to human-written SQL somehow transfers to SQL written by a component that reads untrusted text for a living.

It does not transfer. It has to be rebuilt where the statement meets the data, and it has to work by proof rather than by suspicion: one read-only statement, only the tables and columns that connection was given, only the functions analysis needs, refused unless provable, and a permission to run that cannot be forged.

Your engineers' SQL gets a review. Your agent's should get a stricter one, and it should get it every single time, in the milliseconds before a cursor opens.

You don't build this. You configure it.

None of this is a model you have to train or a review queue you have to staff. Infozense Knowledge Engineering ships the governed layer with the Action gate already in place. You register the connection and the tables it is allowed to touch, and every statement your agent writes is parsed, proven, run inside your boundary, and written to the ledger. Your agent gets to use your live data. It does not get to be trusted with it.

Infozense Knowledge Engineering

Just gave an agent a database connection?

That's the conversation we have best. Bring one real setup, and we'll walk through what its queries are actually allowed to do.

Let's talk →

contact@infozense.com  |  +66-82-242-4008  |  Bangkok, Thailand