QueryShield

How do I block DELETE and DROP from LLM-generated SQL?

Three layers, all of which you should run:

1. Database role. The agent's DB user should not have DELETE or DROP privilege on tables in scope. REVOKE ALL ... GRANT SELECT ON .... This is your bedrock. 2. AST validator. Parse the LLM output. If the root node is DeleteStmt, DropStmt, TruncateStmt, AlterStmt, GrantStmt, CreateStmt — reject. If multi-statement — reject. If a CTE contains a forbidden statement — reject. 3. Driver mode. Set the DB driver to single-statement mode and disable multi-query (allowMultiQueries=false for MySQL JDBC, default in Postgres). This prevents ; DROP TABLE x smuggled at the end of an otherwise valid query.

For agents that genuinely need writes (an "agent that processes refunds"), use a separate, narrowly-scoped agent with its own role, its own policy file requiring an idempotency key and a confirmed user intent token, and human review for batch sizes above a threshold.

QueryShield ships statement-type allowlist as a one-line config. The default for new policies is SELECT-only.