Read-only by policy: making text-to-query safe in a regulated data estate
Why a prompt that says 'only read' is not a control, and the five design rules we used to ship natural language analytics over life sciences data.
Natural language analytics is a feature buyers ask for often, and one of the easiest to get dangerously wrong. The short answer to “how do you make it safe?” is this: the safety rules must be properties of the system, not instructions to the model.
This note explains what that means in practice, using a service we delivered for a commercial intelligence platform that serves global pharmaceutical companies. The client and its customers are described by sector under a confidentiality agreement.
Why a prompt is not a control
A system prompt that says “only generate SELECT statements” is a request, not a guarantee. Models follow instructions most of the time. Security review is concerned with the rest of the time: an unusual question, a follow-up that changes intent, or text inside the data that looks like an instruction.
If the only thing between a user and a write operation on a clinical database is a sentence in a prompt, the honest answer to a security reviewer is that the system is not controlled. We did not want to give that answer.
Rule 1: the query layer can only read
The pipeline that executes generated queries can only issue read operations. Any write, update or delete is rejected by the query layer before it reaches the database, whatever the model produced.
This is the property that made the system approvable. It is testable: we can send the service a request designed to produce a write and show that it fails.
Rule 2: no implicit database
The platform holds a separate database per program, each with a different shape. The service has no server-side default database. Every query and every conversational call must name its database explicitly.
This sounds like a small ergonomic cost. It removes a whole class of failure: a misrouted request fails loudly instead of silently answering from the wrong program’s data, which in life sciences could mean the wrong customer’s data.
Rule 3: ground the model in a known schema
The model does not guess at collection and field names. Each database’s schema is inferred once, cached and reused across a session. The model reasons over a known shape, generated queries are more accurate, and cost stays predictable because schema discovery is not repeated on every question.
Rule 4: not every question is a data question
Users mix data questions with conversation: “thanks”, “what can you do”, “explain that last answer”. A classification step routes non-data questions down a conversational fast path that never touches the database. That removes latency and cost, and it also removes attack surface: fewer requests reach the query layer at all.
A reference resolution step handles follow-ups such as “and for those experts in the same region”, so users can narrow a result the way they would with a colleague, and the resolved question is what gets translated into a query.
Rule 5: make cost and behavior attributable
Every run records its model cost, attributable to a request. Query endpoints are rate limited per client. Answers stream as they are produced, and each conversation is stored in the same database it queried, which keeps tenancy intact.
The generated query is available to the user. Analysts who want to check the work can, and that visibility does more for trust than any accuracy percentage.
What to ask any vendor proposing text-to-query
| Question | A good answer |
|---|---|
| What stops the system writing to the database? | A rule enforced in the query layer, not the prompt, and testable |
| What happens if a request names no database? | It fails |
| How does the model know the schema? | Inferred and cached, not guessed |
| Can users see the generated query? | Yes |
| How is cost tracked? | Per run, attributable to a request |
The point
The model was the easy part of this system. The work that made it shippable was deciding which guarantees had to hold regardless of what the model did, and enforcing them in code. That is the difference between a demo and something a regulated organization can approve.
The full engagement is written up as a case study: natural language analytics for life sciences.