nlqdb

Solve · Agent builders

How do I safely give an AI agent database access without it running dangerous SQL?

If you want an AI agent to use a database without handing it a connection string and hoping it never emits a DROP, nlqdb keeps the agent on the data side of a trust boundary: writes are server-built parameterised inserts, read SQL passes a fail-closed three-stage validator, Postgres RLS isolates every row, and the compiled SQL is always shown.

Teams wiring an agent to SQL reach for the obvious shape — a read-only database role and a connection string in the tool config — then find it's leaky. A 'read-only' check enforced in app code is one SQL-comment trick away from a DELETE, a perfectly valid join can expose an oauth_tokens column, a single heavy query can exhaust the connection pool, and prompt-injected text sitting in a stored row can steer the next query. The risk is the agent holding credentials and authoring the SQL.

The snippet that solves it.

> things the agent logged grouped by type with a count of each

What nlqdb does for this

  • Agent writes go through `nlqdb_remember`: the server builds a parameterised INSERT from a fixed column allow-list, so the agent supplies data, never SQL.
  • Read SQL passes a three-stage validator — leading-verb gate, `node-sql-parser` AST parse, embedded-verb walk — that fails closed, so a CTE-hidden DROP is rejected.
  • Postgres row-level security isolates tenant rows at the engine, enforced on reads and writes regardless of SQL shape — not a guard in app code.
  • Every answer returns the compiled SQL under a trace toggle, and destructive operations show a row-count diff that needs a second confirmation before applying.

Drop into any HTML page

<nlq-data goal="things the agent logged grouped by type with a count of each"></nlq-data>

The agent asks in English; nlqdb compiles and shows the exact SELECT, so you audit the grain — and the validator would have rejected anything that wasn't a read before it ran.

What this replaces

What nlqdb doesn't try to do here

  • nlqdb can connect to a Postgres you already run (the signed-in BYO connect verb), but connecting one does not import these guardrails onto it — the server-built-write boundary and per-tenant RLS apply to databases nlqdb provisions, so the safe-store model on this page is the provisioned database, not a connected prod DB. On a connected database, scope safety with a least-privilege role.
  • No per-query statement-timeout or cost cap yet — a heavy SELECT can still run long; resource-exhaustion guards are tracked in the db-adapter, not wired.
  • No per-agent (sub-tenant) row scoping yet — `app.agent_id` RLS is roadmap; today isolation is per-tenant / per-database, not per-agent-within-a-tenant.

Questions buyers ask

Is a read-only Postgres role enough to let an AI agent query my database safely?
It's a start, but on its own it's leaky: a 'read-only' check enforced in app code is one SQL-comment trick from a write, a valid join can still expose a credentials column, and one heavy query can exhaust your connection pool. nlqdb layers engine-level guards — a fail-closed three-stage SQL validator plus Postgres row-level security — instead of trusting a single role or a single regex.
How does nlqdb stop an agent from running a destructive or injected query?
Writes never use agent-authored SQL — `nlqdb_remember` builds a parameterised INSERT server-side from a fixed column allow-list. Read SQL passes three independent stages (a leading-verb gate, a `node-sql-parser` AST parse, and an embedded-verb/function walk) and fails closed, so a CTE-hidden DROP, a `pg_sleep`, or an unparseable statement is rejected before it runs.
Can I see exactly what SQL the agent ran?
Always — every answer returns the result rows plus the compiled SQL under a trace toggle, and any destructive operation shows a row-count diff that needs a second confirmation before it applies. The SQL is the audit surface; nlqdb never hides it behind the answer.
Can I point nlqdb at my existing production database to make it agent-safe?
You can connect an existing database (the signed-in BYO connect verb), but that doesn't make it agent-safe — the server-built writes and per-tenant RLS on this page apply to databases nlqdb provisions, not one you connect. On a connected prod DB, scope a least-privilege role; for hard isolation, a read replica plus the validated read path is the safer shape.

Where this pain shows up in public

Enduring discussion hubs where you can verify the theme without taking our word for it. We don't quote individual posts; we cite search-result and subreddit URLs that stay live as new threads land.

Try nlqdb in 30 seconds

No sign-in. The anonymous database lasts 72 hours; adopt it with one click if you keep it.

Start with a goal →

Looking at this from a different angle? Browse all solve pages or browse competitor comparisons.