The problem with allowlists
When engineering teams think about protecting a database from LLM queries, the first idea is usually an allowlist: only allow SELECT, block DELETE and DROP.
The problem is that allowlists operate on the first token of the query. SELECT always passes. DELETE always blocks. But an intelligent AI agent generates queries that the allowlist cannot classify correctly.
An allowlist does not know the difference between UPDATE users SET status = "inactive" WHERE id = $1 and UPDATE users SET status = "deleted".
Vericto evaluates the complete tree in depth. It does not matter at what level the destructive node is: if it is in the tree, it is detected.
What an allowlist cannot detect
These are the four patterns that AI agents frequently generate and that an allowlist cannot detect:
1. UPDATE without WHERE
-- Un agente responde a "actualiza el precio del producto"
-- con contexto ambiguo y genera esto:
UPDATE products SET price = 0;
Modifies all rows in the table. Syntactically valid, semantically catastrophic.
2. DELETE with always-true WHERE
-- El LLM fue instruido para "limpiar registros viejos" pero
-- generó una condición trivialmente verdadera:
DELETE FROM sessions WHERE 1=1;
The allowlist blocks it for being DELETE. But the agent can reframe it as a mass UPDATE.
3. TRUNCATE inside a CTE
-- Patrón observado en agentes que construyen queries multi-step:
WITH cleanup AS (
SELECT id FROM old_data
)
TRUNCATE TABLE orders;
The query starts with WITH: a first-token allowlist does not detect it as TRUNCATE.
4. DROP TABLE in nested subquery
-- Raro pero documentado en modelos con function calling agresivo:
DO $$
BEGIN
DROP TABLE IF EXISTS users;
END $$;
Documented in advanced reasoning models. The outer query can be an innocuous SELECT.
How AST parsing works against these cases
The AST (Abstract Syntax Tree) is the structured representation of a query. Instead of evaluating the text, Vericto evaluates the semantic tree.
For an UPDATE without WHERE, the tree has an UpdateStmt node with the property whereClause = null. For a CTE with TRUNCATE, the tree has a CommonTableExpr node containing a TruncateStmt.
UpdateStmt
├── relation: "products"
├── targetList:
│ └── ResTarget
│ ├── name: "price"
│ └── val: Integer(0)
└── whereClause: NULL ← el nodo que activa VERICTO-042
VERICTO-042 detects UPDATE without WHERE. VERICTO-031 detects UPDATE without WHERE in CTEs. Both rules are active by default.
The WHERE 1=1 pattern is the most common case. The allowlist allows it because it is a SELECT. AST parsing detects that the WHERE is trivially true.
DeleteStmt
├── relation: "sessions"
└── whereClause:
└── A_Expr
├── kind: AEXPR_OP
├── name: "="
├── lexpr: Integer(1)
└── rexpr: Integer(1) ← ambos operandos son literales iguales
→ evaluable estáticamente → siempre true
AST parsing produces the same result for the same query, always. You can write a test that verifies the exact behavior. You can audit the blocking decision. You can certify the control.
Aren't database permissions enough?
This is the most common objection. "If the DB user only has SELECT, it cannot cause harm." The problem is this is not true in practice.
The least privilege principle is correct, but applying it correctly to AI agents is notoriously difficult. Vericto complements permissions with a semantic layer.
Permissions and AST parsing are complementary layers. Permissions limit what the agent can do. AST parsing validates that what it does makes sense.
Database permissions and AST parsing are complementary defense layers, not alternatives. Vericto does not replace permissions: it complements them with semantic validation.
Why determinism matters
The alternative to AST parsing for detecting dangerous queries is an ML model. ML models have false positives, stochastic variance, and are not auditable. For a security control, this is unacceptable.
- Database permissions are fragile and hard to audit in complex systems
- AI agents need write access to function (INSERT results, UPDATE state, etc.)
- A revoked permission breaks agent functionality, not just destructive operations
Determinism is not just a technical property: it is a requirement for the control to be auditable and certifiable for SOC2 or ISO27001.
How to implement it in <5 minutes
If you have an LLM-to-SQL pipeline, Vericto integration requires a single change: the host in your connection string.
- DATABASE_URL=postgres://user:pass@prod-db.host:5432/mydb
+ DATABASE_URL=postgres://user:pass@localhost:5433/mydb
Your ORM or driver does not know there is a proxy in the middle. Clean queries pass through. Destructive ones are blocked with a standard permissions error.
Vericto's 28 standard rules cover all these patterns.