Safe text-to-SQL: how I designed it to limit the model
Letting a model query a database means deciding what it cannot do. This page describes the design in my agents platform, which is in construction, in phase 0.
The risk of letting a model write SQL
Text-to-SQL turns a natural-language question into a query. The risk is that a model generates the query: it can write instead of read, ask for tables it should not, return another customer’s data or launch a query that never ends.
The design: one door, with restrictions in two layers
In the AI agents platform for companies, the SQL Tool is the only access to the tables. The restrictions live in two separate layers:
- In the tool: read-only, an allowlist, validated SQL, a timeout and a row limit.
- In the database: tables carry RLS per tenant_id, and the user’s JWT carries the tenant_id.
The SQL agent is one of the three the LangGraph orchestrator routes to, and the database also keeps a catalog of tables and metrics.
The same rule, already in production in AgendaGo
AgendaGo, which is in production, does not do text-to-SQL: its model calls tools. But it applies the isolation rule this design takes: the tenant comes from the JWT and never from the model, and forbidden parameters are stripped, with Postgres RLS enabled across the schema.
Related stack
- PostgreSQL
- LangChain
- LangGraph
- Python