Database guardrails for AI agents

Your agent writes the SQL. Vericto checks it before it runs.

A deterministic check between your AI agents and Postgres or MySQL. A destructive statement comes back as a normal SQL error, with the rule and the fix, so the agent can correct it. The same rules run in CI, in MCP and in your apps.

No account: one docker run of the proxy, or vericto check --offline.

  • Free, open-source proxy and engine (AGPL-3.0)
  • No AI in the verdict: same rules, same result
  • No credit card required
-- your agent, cleaning up test users
postgres=# DELETE FROM users;
ERROR:  Vericto blocked this query [VERICTO-001] — AST node: DeleteStmt > WhereClause = NULL. Suggestion: DELETE FROM users WHERE id = $1
-- the agent reads the rule and the fix, and retries
postgres=# DELETE FROM users WHERE id = 42;
DELETE 1
Real output of vericto-proxy 4.20.0 with its built-in rules. The DELETE without WHERE never reaches the database; on MySQL it comes back as ERROR 1142.

Works with

  • PostgreSQL
  • MySQL
  • MCP
  • GitHub Actions
  • GitLab CI
  • LangChain
  • dbt
  • Airflow
  • Snowflake

Try it

Watch it block a DELETE on your machine

Two paths with no account and no API key: the proxy with Docker, or the CLI offline. With a free account, the same engine answers your agent over MCP and your pull requests in CI.

Start a throwaway Postgres, put the proxy in front of it with the built-in rules, and send a few queries with the image's own psql. All you need is Docker.

Run
docker network create vericto-demo
docker run -d --name vericto-demo-db --network vericto-demo \
  -e POSTGRES_PASSWORD=demo postgres:17
docker run -d --name vericto-demo-proxy --network vericto-demo \
  -e UPSTREAM_HOST=vericto-demo-db vericto/vericto-proxy:4.20.0
until docker exec vericto-demo-db pg_isready -q -h localhost -U postgres; do sleep 1; done

docker run --rm --network vericto-demo postgres:17 \
  psql postgresql://postgres:demo@vericto-demo-proxy:5433/postgres \
  -c "CREATE TABLE users (id int PRIMARY KEY, email text)" \
  -c "INSERT INTO users VALUES (1, 'ana@example.com'), (42, 'bo@example.com')" \
  -c "DELETE FROM users" \
  -c "DELETE FROM users WHERE id = 42" \
  -c "SELECT id, email FROM users"
Output
CREATE TABLE
INSERT 0 2
ERROR:  Vericto blocked this query [VERICTO-001] — AST node: DeleteStmt > WhereClause = NULL. Suggestion: DELETE FROM users WHERE id = $1
DELETE 1
 id |      email
----+-----------------
  1 | ana@example.com
(1 row)

The DELETE with a WHERE does run. docker logs vericto-demo-proxy shows the decision. Clean up with docker rm -f vericto-demo-db vericto-demo-proxy && docker network rm vericto-demo. Next: the proxy in front of your database.

The CLI ships with the engine inside. With --offline it checks SQL on your machine against the 42 standard rules: it makes no request, and the SQL never leaves your computer. It works the same in a pre-commit hook or a CI step.

Run
echo "UPDATE users SET role = 'admin';" > roles.sql
npx @vericto/vericto-cli@latest check --offline roles.sql
Outputexit 1
note: offline mode: 42 standard rules at default severities, engine 4.3.0. Custom rules, overrides, sensitive columns, allowlists and the audit trail apply online only.
✖ roles.sql  BLOCKED  VERICTO-030 critical
    UpdateStmt > WhereClause = NULL
    fix: UPDATE users SET {col} = $1 WHERE id = $2
1 blocked · 0 allowed · 0 flagged · 0 monitored   (ruleset standard@engine-4.3.0 · mode: offline (engine 4.3.0, 42 standard rules, no workspace policy))

Also with brew install vericto/tap/vericto, winget, Scoop or Docker. Next: the CLI in your pipeline.

Connect your agent to the remote MCP server and call check_sql before it runs anything. It gets the verdict, the fix and what to do next. It is advisory: to make the block mandatory, route the agent's connection through the proxy.

Claude Code
claude mcp add --scope user --transport http vericto https://mcp.vericto.com/mcp \
  --header 'Authorization: Bearer ${VERICTO_API_KEY}'
check_sql("DROP TABLE invoices;"), excerpt
{
  "passed": false,
  "findings": [{
    "line": 1,
    "status": "BLOCKED",
    "rule_code": "VERICTO-010",
    "severity": "critical",
    "ast_node_path": "DropStmt",
    "suggested_fix": "Use a versioned migration tool (Flyway, Prisma Migrate, Alembic, Rails migrations)",
    "next_action": "apply_fix_and_recheck"
  }],
  "next_steps": [{
    "action": "apply_fix_and_recheck",
    "message": "do not run it as written; apply the suggested fix, then call check_sql again with the corrected SQL."
  }]
}

Published in the MCP Registry as com.vericto/sql-firewall. Cursor, Codex, VS Code and other clients: setup per client.

The vericto/check-sql action checks the .sql files each pull request changes against your workspace's rules. Findings show up as annotations on the PR, and a blocked statement fails the job. It authenticates with an API key or with GitHub OIDC, with no stored secret.

.github/workflows/vericto.yml
name: Vericto SQL check
on:
  pull_request:
    paths: ["**/*.sql"]
permissions:
  contents: read
  security-events: write
  actions: read
jobs:
  vericto:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
      - uses: vericto/check-sql@v1
        with:
          api-key: ${{ secrets.VERICTO_API_KEY }}

No account yet? A step with npx @vericto/vericto-cli@latest check --offline works on any runner. Next: safe SQL in CI/CD.

HOW IT WORKS

One engine between every source of SQL and your database

Vericto parses each statement into its syntax tree (pg_query for Postgres, sqlparser-rs for the other five dialects) and evaluates it against your rules. No AI in the path: the same statement with the same rules always gets the same verdict, whether it comes from an agent, your app or CI.

  • Allowed: continues to the database
  • Masked: continues, with sensitive columns masked
  • Blocked: turns into an × and goes back to the sender with a fix

Inline: blocks

The statement never reaches the database

The TCP proxy sits in front of PostgreSQL or MySQL: you only change the host in the connection string. A block comes back as a native error (SQLSTATE 42501, ERROR 1142) that any driver understands. The Python and Node SDKs and the Runtime API do the same from your code, on all six dialects.

Set up the proxy →

Before it runs: advises

The verdict comes back before you run or merge

Your agent calls check_sql over MCP while it writes the SQL; the CLI and the GitHub Action fail the commit or the PR; the Validation API checks batches over HTTPS. The caller decides what to do with the verdict, so for an autonomous agent, pair it with the proxy.

How to choose a mode →

In the dashboard

Every decision, in plain sight

What Vericto checks lands in your workspace: every query with its verdict and rule, the audit trail, your rules and what each agent may read.

The dashboard's Queries page with sample data: 39 blocked out of 1,263 queries in the last 24 hours, the hourly chart of allowed, blocked and flagged queries, and the list of statements with their rule, status, database and source: UPDATE users SET role = 'admin' blocked with VERICTO-030 through the MCP proxy, SELECT * FROM orders flagged with VERICTO-050, a read of customers with the email masked (VERICTO-085) and DROP TABLE invoices blocked with VERICTO-010.

An agent sends UPDATE users SET role = 'admin'; through the MCP proxy: it is blocked with VERICTO-030 (UPDATE without WHERE), shows up at the top of Queries, under the last 24 hours' chart, and its detail carries the AST node and the suggested fix.
The Audit Trail timeline with sample data, for October 31, 2026: UPDATE users SET role = 'admin', DROP TABLE invoices and TRUNCATE audit_log blocked as critical (VERICTO-030, VERICTO-010 and VERICTO-011), SELECT pg_sleep(30) and INSERT INTO orders_archive SELECT * FROM orders blocked (VERICTO-070 and VERICTO-040), SELECT * statements flagged (VERICTO-050 and VERICTO-051) and a SELECT on customers allowed with the public.customers.email column masked (VERICTO-085).
The audit trail: every decision with its time, severity, rule, source and database, masked columns included.
The dashboard's rules page with sample data: all 42 standard rules active (42 of 42, no custom rules, 38 critical or high) and the table filtered to high severity, with VERICTO-002 DELETE with LIMIT 0, VERICTO-013 DROP INDEX without IF EXISTS, VERICTO-015 ALTER TABLE DROP COLUMN, VERICTO-016 ALTER TABLE RENAME, VERICTO-017 ALTER TABLE DROP CONSTRAINT and VERICTO-018 ALTER COLUMN TYPE, all set to block.
Your workspace's rules: the standard ones and your own, with their severity and action, and a simulator to test a change before you apply it.
Agent access for one database in the dashboard, with sample data: the support-agent identity in enforce mode and read only by default, with some columns of public.orders and public.customers (email masked), read-write on public.tickets and no access to public.products.
Agent access: per database and per identity, which tables and columns each agent may read or write, in observe or enforce.

Dashboard screenshots with sample data.

FEATURES

What Vericto does with every query

A deterministic AST engine decides on every statement before it runs. Four controls run on top of it.

Block destructive SQL

DELETE and UPDATE without WHERE, DROP, TRUNCATE and risky DDL, inside CTEs and in every statement of a multi-statement string too. Every block comes with the rule, the AST node and a suggested fix.

Mask sensitive columns

Tag columns such as email or card_number and decide per column: block, flag or mask (full, last4, email or hash). Through the TCP proxy, the database returns the value already masked. Team and Enterprise.

An allowlist per agent

Each agent uses only the tables and columns you give it, read-only or read-write. Everything else is denied. Start in observe and switch to enforce once the traffic confirms it. Team and Enterprise.

Simulate before you enforce

Replay a rule change against your real traffic (up to 30, 90 or 180 days depending on the plan) and see which legitimate flows it would block, before it blocks anything. From the dashboard or from CI. Builder, Team and Enterprise.

The panels reproduce the output as the docs describe it; the data is sample data.

COVERAGE

42 rules · 6 dialects · 8 incident families · 52 scenarios

Each scenario is a concrete SQL pattern a rule catches, tested against vericto-engine 4.1.1. It is counted once, not once per dialect or per position.

Who causes it

The same rule stops a person's mistake, an ORM bug and a compromised agent's attack. Each scenario is counted under its most typical origin:

  • 5 Developer or DBA console
  • 7 Application or ORM bug
  • 9 CI/CD migration
  • 9 AI agent or text-to-SQL
  • 9 SQL-injection attacker
  • 13 Insider or compromised agent

In 6 public incidents we documented, the destructive SQL (the published statement, or the one the mechanism implies) is BLOCKED by these rules when the connection goes through Vericto: a DELETE FROM on every production table, DROP TABLE requested from text-to-SQL frameworks (two CVEs), a schema push that dropped tables, COPY … TO PROGRAM on a "read-only" MCP server and a COMMIT; DROP SCHEMA that escaped a read-only transaction. The cases, with their sources.

See all 52 scenarios

INTEGRATIONS

Works with your current stack

Two ways in. On PostgreSQL and MySQL, the TCP proxy needs no code changes. On all six databases, the SDKs, the Runtime API, the CLI and MCP check SQL before it runs.

Databases

Zero code changes

TCP proxy

Point your connection string at the proxy. It works with any driver or ORM and blocks destructive queries inline, before they reach the database.

Set up the proxy →
All six databases

SDK, Runtime API, CLI and MCP

The Python and Node SDKs and the Runtime API check each query before your code runs it. The CLI and MCP check SQL before it ships.

Not on the list? Any PostgreSQL or MySQL driver works through the proxy, and the Runtime API works from any language. See all integrations →

WHY TRUST US

Measured, public and verifiable

Vericto does not use AI to decide what to block. The engine, the proxy and the CLI are open source under the AGPL-3.0, and every claim on this page can be checked.

  • 0.08 msadded at the median on PostgreSQL, from 970 to 4,800 statements/s per 0.5 vCPU task (direct path: 0.30 to 0.32 ms)
  • ~0.07 msper statement on MySQL: 1.1 ms per 16-statement oltp_read_only transaction, from 36 to 250 transactions/s
  • 0.13 → 0.60 msadded p99 on PostgreSQL at 10% and 50% of the task's capacity: it grows with the load on the 0.5 vCPU quota

vericto-proxy 4.21.0 · enforce mode · 42 built-in rules · c7g (Graviton3) · 0.5 vCPU · TLS · October 31, 2026

Small statements: it is a measurement under these conditions, not a guarantee. Benchmark, conditions and method.

  • Open source · AGPL-3.0

    Engine, proxy and CLI

    The AST engine, the TCP proxy and the CLI. Free to use in production, commercially too, with a commercial license for closed-source products.

  • Apache-2.0

    SDKs, CI action and benchmark

    The Python and Node SDKs, the check-sql action, and the benchmark harness with its results.

  • Packages

    Install it from where you already install things

    The CLI on npm, Homebrew, winget and Scoop; the proxy on Docker Hub and GHCR, with a build provenance attestation.

  • MCP Registry

    Listed in the official MCP Registry

    Vericto's remote server is published as com.vericto/sql-firewall, active since October 13, 2026.

  • Offline

    Evidence you can verify offline

    Compliance reports are signed with Ed25519 and your auditor checks the signature with the public key, with no account and no network. How to verify them.

  • Public

    Public changelog and status

    Every release, with what changed and why, in the changelog. Service availability on the status page.

For security and platform teams

Say yes to AI agents on production data

One policy for agents, apps and CI, with the evidence an auditor asks for. The proxy runs in your infrastructure: your credentials never leave your network.

  • Signed audit trail

    Every decision is recorded, immutable: the statement, the verdict, the rule, the database and the time. Reports are signed with Ed25519 and verify offline. Audit trail.

  • SOC 2 and ISO 27001 evidence

    A signed PDF report with every export, mapped to 12 controls of SOC 2 (CC6.1–CC8.1) and ISO 27001 (A.5.18–A.8.32). A report every month, kept 13 months, on Enterprise. What your auditor gets.

  • An allowlist per agent

    Each agent uses only the tables and columns you give it, read-only or read-write. Start in observe and move to enforce. Agent access.

  • Mask sensitive columns

    On the TCP proxy the query is rewritten and the database returns the value already masked: full, last4, email or hash. Masking.

  • Fail-open or fail-closed

    Fail-open by default, so your traffic is never cut off; fail-closed if you choose it, also for what the parser cannot read. Enforcement modes.

  • Enterprise

    A 99.9% SLA on Standard, and 99.95% or 99.99% with a dedicated deployment. A monthly compliance report, generated automatically and kept 13 months. See Enterprise.

Put a guardrail on your agent's SQL today

Start free

Dashboard, MCP and CI checks: 500K queries/mo and 1K SQL validations/mo free, no credit card.

Start free

Try it without an account

The proxy with Docker, or the CLI with --offline. Nothing leaves your machine.

See the commands →

Talk to us

Enterprise, a dedicated deployment, or a security question.

Contact us →