Updated in v7.0.0 (breaking).
SQLVerifier.verify_sql() now returns a DiagnosticResult instead of an ad-hoc dict, and a proven-malicious query is reported as VERIFIED (truth) with a separate admission decision (policy). See the changelog for migration details.Overview
The SQL Engine validates queries for:- SQL injection patterns
- Destructive operations
- Schema compliance
- Syntax correctness
The DiagnosticResult contract
verify_sql() returns a DiagnosticResult with a status, an agent-safe agent_message, structured developer_fields, and a proof_ref bound to the query AST:
Proving that a query is malicious is a successful proof, so a malicious query is
VERIFIED — not BLOCKED. BLOCKED is reserved for cases where verification itself could not complete, and blocked results never carry a proof_ref. If the DDL schema fails to parse, the incomplete analysis is BLOCKED even when the query itself looks malicious (schema_parse_error takes precedence).
agent_message never leaks detection rules, rule IDs, or raw parser output. Rule-level detail lives in developer_fields.
Admission is a separate decision
Do not gate execution onstatus alone. POST /verify/sql returns an explicit admission field (ADMIT or BLOCKED) alongside the verdict. A malicious query is VERIFIED at the truth layer but BLOCKED at the admission layer. Gate on admission (or developer_fields.is_valid), never on status == "VERIFIED".
Usage
Schema compliance
When you passschema_ddl, every table the query reads or writes must be declared in that DDL. A reference to an undeclared table is an admission failure: the result is BLOCKED with is_valid: false and constraint_id: "sql_verifier.schema_violation". Names the query defines itself, such as CTEs, are not treated as tables. Without schema_ddl, the engine does not check table names.
Before v7.2.3, a query on a table outside the schema was admitted with a warning. See GHSA-q5g6-6cw2-cjm3.
MySQL and MariaDB executable comments
MySQL and MariaDB run SQL placed inside executable comments (/*! ... */, /*!NNNNN ... */, and /*M! ... */). The SQL engine expands these comments before analysis, so injection, destructive-operation, and schema checks apply to the SQL inside them. The engine expands them whatever dialect you declare.
developer_fields.executable_comments_expanded is true when the query contained an executable comment.
Injection detection
Detected patterns
Destructive operations
Administrative commands
The SQL engine also blocks administrative SQL commands by default:A resource-limit violation is a
CRITICAL admission failure but not evidence of malicious intent. Only true-malice issue types set malicious_classification: true.Supported dialects
- PostgreSQL
- MySQL
- SQLite
- SQL Server
- BigQuery