"Just let the AI query the database" is how you build a data breach. I do let an LLM write SQL ag..."Just let the AI query the database" is how you build a data breach. I do let an LLM write SQL ag...
The network for creativity
Join 1.25M professional creatives like you
Connect with clients, get discovered, and run your business 100% commission-free
Creatives on Contra have earned over $150M and we are just getting started
"Just let the AI query the database" is how you build a data breach.
I do let an LLM write SQL against a customer's database. It's genuinely useful — "how many patients missed follow-ups last month?" answered in plain English. But a model that can emit arbitrary SQL against live customer data is one hallucinated DROP TABLE, or one cross-tenant SELECT, away from a disaster.
The fix isn't a better prompt. It's never trusting the model in the first place.
Step 1 — a router, not a text-to-SQL box. Most questions don't need generated SQL. Before anything touches data, classify intent:
Advisory: answer from the model alone. No DB.
Retrieval: semantic search over documents. No DB.
Stats: a canned, reviewed query. Parameterized, not generated.
Text-to-SQL: only genuine ad-hoc data questions land here. Three of four lanes never touch raw SQL. You've shrunk the attack surface to one path before writing a single guardrail.
Step 2 — that one path runs a gauntlet. Every generated query must pass, in order:
Schema resolver — the model only ever sees the tables and columns this tenant is allowed to read. It can't reference what it can't see, and it can't see another tenant's data. This is the big one.
Read-only role — the query runs as a Postgres role that physically cannot INSERT, UPDATE, or DROP. A malicious query isn't rejected by my code; it's rejected by the database.
SELECT-only parse — parse the SQL before running it. One statement, no writes, no stacked "; DROP ..." payloads.
Tenant filter + LIMIT + statement_timeout — row-level isolation enforced, rows capped, runtime capped. No query leaks across tenants or runs away with the DB.
Only after all four does anything reach a read replica.
The principle underneath all of it: the model proposes, the system disposes. Treat generated SQL exactly like untrusted user input — because that's what it is. Even if the model does something insane, three other layers still have to fail before a customer's data is at risk.
If your text-to-SQL feature is "the prompt says please only SELECT," you don't have a feature. You have an incident waiting for a date.
How are you sandboxing LLM database access — or are you keeping it away from the DB entirely?
#security #backend #AI #systemdesign #databases
Post image
Back to feed
The network for creativity
Join 1.25M professional creatives like you
Connect with clients, get discovered, and run your business 100% commission-free
Creatives on Contra have earned over $150M and we are just getting started