← All use cases

USE CASE

Catch destructive SQL before it reaches production, in your CI pipeline

The Vericto CLI evaluates your migration files against your ruleset. exit code 0 = ship it. exit code 1 = your pipeline fails before the query ever runs.

SQL migrations are the last place you want a surprise

LLM-generated migrations

Your agent wrote the migration. Did it add a WHERE clause? Did it scope the UPDATE? Did it avoid TRUNCATE? You don't know until it runs.

Manual review doesn't scale

At 10 deploys/day, nobody reads every migration carefully. One missed WHERE clause at 3am and you're doing an emergency restore.

Production is too late

Catching a DELETE FROM orders in staging is lucky. Catching it in CI is engineering.

What the Vericto CLI looks like in your pipeline

vericto check — migrations/0042_cleanup.sql
$ vericto check migrations/0042_cleanup.sql --dialect postgres

Vericto — Deterministic SQL Firewall v1.4.2
Evaluating 4 queries against workspace ruleset...

  Line 3:  ALTER TABLE users ADD COLUMN last_seen_at TIMESTAMPTZ    ALLOWED
  Line 8:  CREATE INDEX idx_users_last_seen ON users(last_seen_at)  ALLOWED
  Line 14: DELETE FROM audit_logs                                   BLOCKED

  Rule:     VERICTO-001 — DELETE without WHERE clause
  AST node: DeleteStmt > WhereClause = NULL
  Severity: CRITICAL
  Fix:      DELETE FROM audit_logs WHERE created_at < NOW() - INTERVAL '90 days'

  Line 19: UPDATE users SET last_seen_at = NOW() WHERE user_id = $1  ALLOWED

Summary: 3 passed, 1 blocked
Exit code: 1

Your pipeline fails at this step. The migration never reaches staging.

One step to add to your GitHub Actions workflow

name: CI

on: [push, pull_request]

jobs:
  sql-safety:
    name: SQL Safety Check
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install Vericto CLI
        run: npm install -g @vericto/vericto-cli

      - name: Check SQL migrations
        env:
          VERICTO_API_KEY: ${{ secrets.VERICTO_API_KEY }}
        run: |
          vericto check migrations/*.sql \
            --dialect postgres \
            --workspace ${{ vars.VERICTO_WORKSPACE_ID }}

The VERICTO_API_KEY is a workspace API key (vtro_...) with the ci_dryrun:execute scope. Create one in your Vericto dashboard under API Keys.

GitLab CI equivalent

sql-safety:
  stage: validate
  image: node:20-alpine
  script:
    - npm install -g @vericto/vericto-cli
    - vericto check migrations/*.sql --dialect postgres
  variables:
    VERICTO_API_KEY: $VERICTO_API_KEY
    VERICTO_WORKSPACE_ID: $VERICTO_WORKSPACE_ID

Every migration file, every query, every rule

The Vericto CLI sends each SQL statement in your file to the same AST engine that protects your production database. Same rules, same logic, zero drift between CI and production.

Supports

  • .sql files
  • Directories of .sql files (recursive)
  • Piped SQL via stdin
  • Multiple dialects: postgres, mysql, oracle, mssql

Reports

  • Per-query decision (ALLOWED / BLOCKED)
  • Rule code and AST node path
  • Suggested fix per blocked query
  • Exit code for CI integration
  • JSON output for custom tooling (--format json)

Why 'shift left' SQL security matters

10x

cheaper to catch a bug in CI than in production (NIST, 2024)

4.2h

average time to recover from a destructive query incident (team of 3 seniors)

$0

cost of a blocked migration in CI vs potential data loss, restore time, and customer impact

The CLI and CI validation are available on every plan, with monthly quotas per plan (Free 1,000/mo, Builder 10,000/mo, Team and Enterprise with higher limits).

See plans and limits →

Frequently asked questions

  • No. The dry-run mode evaluates SQL against the ruleset defined in your workspace, but never connects to any database. It's a pure static analysis step.

  • Yes, but without a workspace API key the CLI uses the default ruleset (CRITICAL rules only). For custom rules and your workspace configuration, you need a Team account.

  • Standard .sql files, directories (all .sql files recursively), and stdin. It handles multi-statement files, comments, and procedural blocks.

  • Yes, with --fail-on. By default (--fail-on block) only BLOCKED findings fail the build; FLAGGED ones (like SELECT without LIMIT) are reported but pass. Use --fail-on flag to also fail on FLAGGED, or --fail-on any to fail on any finding.

Add SQL safety to your CI pipeline today