Integration Guide

Protect your databases in under 5 minutes, three ways: the transparent TCP proxy for runtime traffic, the vericto CLI for pre-commit & CI/CD, and a direct REST API. Zero credentials stored.

Prerequisites

  • A Vericto account (sign up free)
  • An API key (create one in Dashboard → API Keys)
  • For TCP proxy (runtime protection): Docker or any container runtime to deploy the proxy in your infrastructure
  • For the CLI (pre-commit & CI/CD): a shell, or a CI runner with Node/Docker
  • For the HTTP API (direct REST): ability to make HTTP requests from your pipeline or app

Vericto offers three integration modes. Pick per environment, they compose:

ModeWhen to useEnforcement
TCP proxyRuntime: every query your app (or an LLM agent) sends to Postgres/MySQLBlocks in real time, before the query reaches the DB
CLI (vericto)Shift-left: pre-commit hooks and CI/CD, all four dialectsFails the build; SQL is analyzed, never executed
HTTP APICustom integrations: call the REST endpoint directly from your own toolingReturns a verdict you act on

Zero credentials: Vericto never stores your database credentials. The TCP proxy runs in your infrastructure and forwards authentication transparently. Your credentials never leave your network.

Step 1: Create workspace & database

  1. Go to /register and create your account
  2. Navigate to Dashboard → Databases → Add Database
  3. Enter a name (e.g. prod-users-db) and select the dialect. PostgreSQL and MySQL can run through the transparent TCP proxy; Oracle and SQL Server are evaluated via the HTTP API only.
  4. Copy the Database ID. You'll need it for configuration
  5. Go to Dashboard → API Keys and create a key with the rules:read and telemetry:write scopes (the only ones the proxy needs: it pulls its ruleset and reports telemetry). The proxy evaluates SQL locally, so it does not need the AST evaluation scope. Copy it securely.

That's all you need from the Vericto dashboard. No connection strings, no credentials.

TCP Proxy: Production database protection

The TCP proxy intercepts every SQL query at the wire protocol level, for both PostgreSQL and MySQL (choose with VERICTO_WIRE_PROTOCOL). Deploy it as a sidecar or standalone container in your infrastructure. Your app connects to the proxy with the same credentials it uses for the database directly.

# docker-compose.yml
services:
  vericto-proxy:
    image: ghcr.io/vericto/vericto-proxy:latest
    ports:
      - "5433:5433"
    environment:
      VERICTO_API_URL: "https://api.vericto.com"
      VERICTO_API_KEY: "${VERICTO_API_KEY}"
      VERICTO_DATABASE_ID: "${VERICTO_DATABASE_ID}"
      VERICTO_WIRE_PROTOCOL: "postgres"   # or "mysql"
      UPSTREAM_HOST: "your-db-host.rds.amazonaws.com"
      UPSTREAM_PORT: "5432"
      PROXY_LISTEN_PORT: "5433"
      # Remote DB (RDS): encrypt the proxy → database hop.
      UPSTREAM_SSLMODE: "require"   # or "verify-full" + UPSTREAM_SSLROOTCERT

  app:
    environment:
      # Point your app to the proxy — same user:pass as before
      DATABASE_URL: "postgres://user:pass@vericto-proxy:5433/mydb"
    depends_on:
      - vericto-proxy

Configuration reference

All proxy configuration is passed via environment variables. Only UPSTREAM_HOST is required; the control-plane link turns on as soon as you set VERICTO_API_URL and VERICTO_API_KEY. Omit them and the proxy still evaluates with its built-in default ruleset (handy for dev or air-gapped setups).

VariableDefaultDescription
Upstream (proxy → database)
UPSTREAM_HOSTrequiredYour database host. The only strictly required variable.
UPSTREAM_PORT5432 / 3306Database port. The default depends on the protocol (Postgres 5432, MySQL 3306).
VERICTO_WIRE_PROTOCOLpostgrespostgres or mysql. Selects the protocol parser and the default ports.
PROXY_LISTEN_PORT5433 / 3307Port the proxy listens on for your app. Default by protocol (Postgres 5433, MySQL 3307).
Control plane (proxy → Vericto API)
VERICTO_API_URLVericto API URL. Use https://api.vericto.com. Setting it (with the key) enables telemetry and rule sync.
VERICTO_API_KEYWorkspace API key (vtro_…) with rules:read + telemetry:write scopes. Store it as a secret.
VERICTO_DATABASE_IDThe Database ID this proxy protects. Tags telemetry and selects that database's rules. Without it, the proxy does not report telemetry.
VERICTO_RULES_SYNC_INTERVAL_SECS300How often the proxy polls for ruleset changes. Minimum 30 s (lower values are clamped to 30).
Evaluation and health
VERICTO_MAX_QUERY_BYTES10485760Largest query the proxy will evaluate (10 MiB). Anything above is refused without being analysed, with rule code VERICTO-QUERY-TOO-LARGE. Raise it if your legitimate workloads (batch inserts, long IN lists) run past the limit; the real ceiling is the wire protocol's (64 MiB on Postgres, 16 MiB on MySQL). In monitor mode the query is forwarded unevaluated instead of refused.
VERICTO_HEALTHZ_PORTDedicated TCP port for load-balancer health checks. Answers without touching the database, and does not accept connections until the proxy has finished warming up. Omitted means the port is not opened.
TLS (see the next section)
UPSTREAM_SSLMODEdisabledisable, require, or verify-full. Encrypts the proxy → database hop.
UPSTREAM_SSLROOTCERTCA for verify-full. If omitted, uses the system public CA roots.
UPSTREAM_SSLCERT / UPSTREAM_SSLKEYClient certificate for upstream mTLS (cert auth). Applies only on the PostgreSQL hop.
PROXY_TLS_MODEdisabledisable or require. Terminates TLS on the app → proxy hop.
PROXY_TLS_CERT / PROXY_TLS_KEYServer certificate and key (PEM) when PROXY_TLS_MODE=require.
Telemetry (see the next section)
VERICTO_TELEMETRY_BUFFERmemorymemory or disk. Buffering strategy before delivery.
VERICTO_TELEMETRY_DISK_PATH/var/lib/vericto/spoolSpool directory when the buffer is disk.
VERICTO_TELEMETRY_MEMORY_CAPACITY10000Max events in the in-memory ring buffer before the oldest are dropped.
VERICTO_TELEMETRY_BATCH_SIZE100Max events sent in each POST /ingest/events batch.
VERICTO_TELEMETRY_FLUSH_SECS5How many seconds between reporter flushes of the buffer to the API.

Encrypting connections (TLS)

Proxy → database. When your database is remote (e.g. a managed RDS/Cloud SQL instance), encrypt the proxy → database hop with UPSTREAM_SSLMODE. The proxy performs the PostgreSQL SSLRequest negotiation and tunnels the session through TLS:

# Encryption only (does not verify the server certificate)
UPSTREAM_SSLMODE=require

# Encryption + verify the certificate chain and hostname
UPSTREAM_SSLMODE=verify-full
UPSTREAM_SSLROOTCERT=/etc/vericto/rds-ca.pem   # omit to use public CA roots

# Optional: mutual TLS — present a client cert so the proxy authenticates to a
# database configured with `cert` auth (one service identity for the proxy)
UPSTREAM_SSLCERT=/etc/vericto/proxy-client.crt
UPSTREAM_SSLKEY=/etc/vericto/proxy-client.key

Client → proxy. By default the proxy declines client TLS, because it is meant to run inside the same trusted boundary as your app (sidecar, same host, or private subnet) where that hop never leaves your network. To encrypt it natively, set PROXY_TLS_MODE=require with a server certificate and key. The proxy answers the SSLRequest with 'S' and terminates TLS as the server:

PROXY_TLS_MODE=require
PROXY_TLS_CERT=/etc/vericto/server.crt
PROXY_TLS_KEY=/etc/vericto/server.key

Vericto recommends terminating client TLS at the proxy when:

  • The app → proxy hop crosses an untrusted network (different host, VPC, or AZ) instead of a sidecar / private subnet.
  • Your driver enforces sslmode=require and you don't want to run a TLS-terminating load balancer (AWS NLB, HAProxy) in front.
  • A compliance baseline mandates encryption in transit on every hop.

If the proxy already runs as a sidecar or in the same private subnet, leave it disabled. It isn't needed. This is server-side TLS (the client authenticates the proxy); the proxy relays auth end-to-end, so scram-sha-256, md5 and cloud token auth (IAM / Entra) work unchanged. SCRAM channel binding (SCRAM-SHA-256-PLUS) and per-end-client cert auth are not supported through a TLS-terminating proxy by design. Both exist to detect a proxy in the middle. Inspecting SQL requires decrypting at the proxy, so opaque end-to-end TLS is incompatible with enforcement.

Telemetry buffering: memory vs. disk

The proxy buffers evaluation events before sending them to the Vericto API. Two strategies are available:

ModeBehaviorBest for
memory (default) Events are held in a fixed-size ring buffer (default: 10,000 events). If the API is unreachable, the oldest events are dropped when the buffer fills. They are lost on container restart. Low-latency environments where losing some events during API outages is acceptable. Zero disk I/O overhead.
disk Events are written to an append-only spool on disk. It survives container restarts and prolonged API outages. The reporter reads from and removes from the spool after a successful delivery. Compliance-critical environments (SOC2, ISO 27001) where no event may be lost. Requires mounting a persistent volume.

Configuration via environment variables:

VERICTO_TELEMETRY_BUFFER=memory|disk        # default: memory
VERICTO_TELEMETRY_DISK_PATH=/var/lib/vericto/spool
VERICTO_TELEMETRY_MEMORY_CAPACITY=10000

Important: telemetry is always non-blocking. Regardless of the buffer mode, the SQL evaluation path is never delayed by telemetry I/O. Events are sent to the buffer asynchronously after the decision is made.

Resource recommendations

The proxy is designed to be lightweight. The AST engine compiles to native code and evaluates queries in-process, with no network calls on the critical path.

WorkloadCPUMemoryDiskQueries/sec
Small (dev, staging) 0.25 vCPU 64 MB None (memory buffer) Up to 1,000 q/s
Medium (production) 0.5 vCPU 128 MB 100 MB (if disk buffer) Up to 10,000 q/s
High (high throughput) 1 vCPU 256 MB 500 MB (disk buffer) 50,000+ q/s

Key factors: CPU scales with query complexity (queries with multiple JOINs require parsing more AST nodes). Memory scales with the number of connections (each TCP session holds ~4 KB of state). Disk is only needed for telemetry buffering in disk mode.

Latency target: P99 < 2ms for rule evaluation. The proxy adds negligible overhead compared to the network round-trip to your database.

Frameworks & ORMs

Once the proxy is running, point your app to it. The only change is the host, same credentials, same database name:

ORM / DriverConfigurationExample
Prisma DATABASE_URL in .env postgres://user:pass@vericto-proxy:5433/mydb
SQLAlchemy create_engine(url) postgresql+psycopg2://user:pass@proxy:5433/mydb
Drizzle ORM connectionString postgres://user:pass@proxy:5433/mydb
TypeORM host + port in DataSource host: 'vericto-proxy', port: 5433
ActiveRecord DATABASE_URL postgres://user:pass@proxy:5433/mydb
Go (pgx/lib-pq) sql.Open("postgres", url) postgres://user:pass@proxy:5433/mydb
Java (JDBC) jdbc:postgresql://host:port/db jdbc:postgresql://vericto-proxy:5433/mydb
.NET (Npgsql) Host=;Port=;Database= Host=vericto-proxy;Port=5433;Database=mydb

CLI: shift-left in pre-commit & CI/CD

The vericto CLI validates SQL against your workspace's rules before it ever runs, in pre-commit hooks and CI pipelines. It's a thin client: it sends SQL to your workspace (POST /api/v1/ci/check-key) and mirrors the verdict as a process exit code. SQL is analyzed, never executed. Works with all four dialects (PostgreSQL, MySQL, Oracle, SQL Server) and is available on every plan, metered by a monthly CLI allowance.

TCP proxy vs. CLI: the proxy protects runtime traffic (queries your app or an LLM agent actually sends). The CLI protects authoring time (migrations and SQL in code review), so unsafe queries never merge. Most teams use both.

Install & authenticate

# Shell installer (Linux / macOS)
curl -fsSL https://github.com/vericto/vericto-cli/releases/latest/download/vericto-cli-installer.sh | sh

Authenticate once. On a laptop, vericto login opens your browser and mints a scoped 30-day key. Nothing is pasted. In CI, provide an API key via the VERICTO_API_KEY environment variable (or use OIDC, below):

vericto login                 # browser login (developer at a keyboard)
vericto doctor                # verify config, connectivity, auth & plan quota

# Check migrations locally — exit 1 if anything is blocked
VERICTO_API_KEY=vtro_... vericto check migrations/*.sql --dialect postgres

CI/CD pipelines

The CLI is a thin client that mirrors the verdict as a process exit code, so it works in any CI that can run a command. vericto init scaffolds a ready-to-commit template for GitHub Actions and GitLab CI; on CircleCI, Jenkins, and others you wire it by hand (same command, gated on the exit code). --changed checks only the *.sql files changed against the merge base, so PRs stay fast:

# GitHub Actions — .github/workflows/vericto.yml
name: Vericto SQL Check
on: pull_request
permissions:
  contents: read
  security-events: write   # required to upload SARIF to the Security tab
jobs:
  sql-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }   # --changed needs history for the merge base
      - run: npm install -g @vericto/vericto-cli
      - run: vericto check --changed --format sarif --output vericto.sarif
        env:
          VERICTO_API_KEY: ${{ secrets.VERICTO_API_KEY }}
      - uses: github/codeql-action/upload-sarif@v4   # inline PR annotations
        if: always()   # upload findings even when the check step exits non-zero
        with:
          sarif_file: vericto.sarif

Exit codes let CI tell a real block from an outage: 0 clean · 1 a finding at/above --fail-on (default block) · 2 usage error · 3 auth/config error · 4 backend/network error. Use --monitor to report findings but always exit 0 during initial rollout.

Keyless CI auth (OIDC): instead of storing a static vtro_... key, a pipeline can authenticate with a short-lived per-run token via OIDC / workload identity, the same federation GitHub Actions and GitLab CI already provide. Create a trust policy for the workspace in the dashboard, then run vericto check --changed --oidc --workspace ws_123. The key is held in memory only, never written to disk.

Pre-commit hook & baseline

Catch unsafe SQL before it's even committed. vericto init --hook installs the hook; adopting the CLI on a repo with pre-existing SQL won't turn the build red on day one. Record a baseline so only new findings fail:

vericto init --hook                                  # install the pre-commit hook

# Baseline existing findings, then fail only on new ones
vericto baseline migrations/*.sql                    # writes .vericto-baseline.json
vericto check migrations/*.sql --baseline .vericto-baseline.json

Suppress a single finding inline. A reason is required, so it stays accountable:

DELETE FROM users; -- vericto:ignore[VERICTO-001] one-off backfill, tracked in JIRA-42

HTTP API: direct REST integration

Prefer to call Vericto from your own tooling instead of the CLI? Evaluate SQL over REST at POST /api/v1/ci/check-key, authenticated with an API key (scope ci_dryrun:execute). Queries are analyzed but never executed. This is the same endpoint the CLI uses. Reach for it only when the CLI doesn't fit your workflow.

Send a batch of up to 500 queries, each tagged with its source line. The response returns a per-query verdict and an exit_code (1 if anything was blocked):

Code examples

# curl — evaluate one or more queries
curl -s -X POST https://api.vericto.com/api/v1/ci/check-key \
  -H "X-API-Key: $VERICTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "dialect": "postgres",
    "file_name": "0001_init.sql",
    "queries": [
      { "line": 1, "sql": "ALTER TABLE users DROP COLUMN email;" }
    ]
  }'

# Response:
# {
#   "summary": { "total": 1, "blocked": 1, "allowed": 0, "ruleset_version": "…" },
#   "queries": [
#     { "line": 1, "status": "BLOCKED", "rule_code": "VERICTO-014",
#       "severity": "high", "ast_node_path": "…", "suggested_fix": "…" }
#   ],
#   "exit_code": 1
# }

For most pipelines the vericto CLI is simpler. It handles batching, --changed detection, baselines, and SARIF/Code-Quality output for you.

Verify & monitor

Once integrated, verify the setup is working:

  • TCP Proxy: Go to Dashboard → Databases and click "Verify connection". The proxy will report its status within seconds.
  • CLI: Run vericto doctor to confirm config, connectivity, auth, and your remaining monthly quota in one command.
  • HTTP API: Send a test batch and check the response. A 200 with "exit_code": 0 and "status": "ALLOWED" confirms the integration works.
  • Dashboard: Navigate to the Queries page to see real-time evaluation events flowing in, and the CI Runs page for CLI/API check history.

Enable Observe Mode during initial rollout. It logs all decisions without blocking anything, so you can validate your ruleset before enforcing it.