Safe database access for AI agents

Let people ask an AI agent about your data, with your database or data lake safe from whatever the model sends.

By: Benjamin Clark

Intent

This pattern is a specialised implementation of capabilities and safeguards for AI agents, for reading data. The capability takes a structured query, made of columns, filters, ordering and a page, and compiles it for the store. No query text ever crosses the boundary. This enables three outcomes:

  1. The data stays safe from whatever the model sends, including after a prompt injection.
  2. One query language works across stores, so a new store needs a new compiler rather than new tools.
  3. Every read is capped, so one question can't stall the store or overflow the model's input.

Motivation

The quickest way to connect a model to data is a tool that takes SQL. Every safeguard then rests on the SQL the model chooses to write, which fails in three ways:

  1. It can reach anything its role can.
  2. It can run a query that stalls the store.
  3. It can misread columns nobody explained, and answer with confidence anyway.

This pattern takes query text away. The model fills in a structured query from a closed set of operators, and the server checks it and compiles it for the store, so the compiler is the injection boundary. An injected instruction can only ask for pages of data the capability could already read.

Applicability

Use this pattern when:

  1. People want to ask an AI agent questions about data held in a relational database or a data lake.
  2. The data must be safe from whatever the model decides to send it, including after a prompt injection.
  3. Everyone the agent serves may see all the data it reads for them.

Do not use this pattern when:

  1. Users may see different rows of the same data. Use LLM agents that act as the user instead.
  2. The model must write.
  3. Analysts need free-form queries across raw tables.

Structure

Sequence diagram of the Safe database access for AI agents pattern, whose participants are listed below

Variant A: Single-tenant relational database

When one organisation's people query its own database, such as PostgreSQL behind an internal tool, this variant works best.

  1. A schema of views built for reading is the contract, holding the definitions a model would otherwise guess.
  2. One read-only role is granted only that schema, with a statement timeout.

Variant B: Multi-tenant relational database

When a platform keeps its clients apart, and each has its own database, this variant works best.

  1. The same schema of views is created on every client's database, as in database instance per tenant.
  2. Each client has its own read-only role, so one client's access can't read another's data.
  3. The client is fixed outside the model, as in tenant-scoped MCP connectors.

Variant C: Data lake

When the data sits as Parquet in a data lake rather than in a database, this variant works best.

  1. The same structured query runs over the files directly, or over tables through a query engine such as Amazon Athena, as in the serverless query layer over a serverless data lake layout.
  2. A query engine adds aggregates and grouping, which suit questions across a whole dataset.
  3. Reads stay within one client's data, enforced by the API or the tables they go through.

Participants

ParticipantRole
AI agentAnswers people's questions, whether its tools run inside it or behind an MCP server.
Capability's toolsOne lists what can be read, and one takes a structured query.
Query compilerChecks the query's structure, and compiles it for the store.
Scoped read accessRead-only and time-limited, and scoped as each variant describes.
Data storeThe relational database or data lake being read.

Constraints and trade-offs

  1. The query language limits what the model can read, not what it concludes. Language models are non-deterministic, so it can misread the rows it gets, make something up, or give a different answer to the same question. A figure that must be exact still belongs in a deterministic report.
  2. It answers only what the query language and the exposed data allow, and that data becomes a product someone has to own.
  3. The query language is closed. A question it can't express, such as a join it doesn't offer, needs the data shaped for reading first, or the language extended.
  4. Slow reads are felt directly, in every answer that makes them.

Variant A: Single-tenant relational database trade-offs

  1. The core benefit is simplicity: one role and one set of views, with nothing to provision per client.
  2. The core cost is that everyone reaches the same data, so the views must hold only what everyone may see.

Variant B: Multi-tenant relational database trade-offs

  1. The core benefit is that the boundary between clients holds in the database itself, whatever the model is told.
  2. The core cost is provisioning: every new client needs its role and views created, and every change to them reaches every client.

Variant C: Data lake trade-offs

  1. The core benefit is that agents can read the lake you already have, with no database to run.
  2. The core cost is speed: a filtered read can scan a whole file, so tool timeouts must allow for the slowest ones.

Part of how I deliver

When people want answers from their data, this is one of the first capabilities I build. It's one of many patterns I bring through contract delivery.

AI in your systems, safely

I put chatbots and MCP servers into the systems businesses already run, reaching only what they should. If you want one on yours, book a call and we'll talk it through.

© 2026 Sudoblark Ltd. | Registered in England and Wales | Company number 14712154 | VAT number GB 438 1548 82 | Registered office: 1 Cedar Office Park, Cobham Road, Wimborne, BH21 7SB