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:
| Mode | When to use | Enforcement |
|---|---|---|
| TCP proxy | Runtime: every query your app (or an LLM agent) sends to Postgres/MySQL | Blocks in real time, before the query reaches the DB |
CLI (vericto) | Shift-left: pre-commit hooks and CI/CD, all four dialects | Fails the build; SQL is analyzed, never executed |
| HTTP API | Custom integrations: call the REST endpoint directly from your own tooling | Returns 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
- Go to /register and create your account
- Navigate to Dashboard → Databases → Add Database
- 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. - Copy the Database ID. You'll need it for configuration
- Go to Dashboard → API Keys and create a key with the
rules:readandtelemetry:writescopes (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).
| Variable | Default | Description |
|---|---|---|
| Upstream (proxy → database) | ||
UPSTREAM_HOST | required | Your database host. The only strictly required variable. |
UPSTREAM_PORT | 5432 / 3306 | Database port. The default depends on the protocol (Postgres 5432, MySQL 3306). |
VERICTO_WIRE_PROTOCOL | postgres | postgres or mysql. Selects the protocol parser and the default ports. |
PROXY_LISTEN_PORT | 5433 / 3307 | Port the proxy listens on for your app. Default by protocol (Postgres 5433, MySQL 3307). |
| Control plane (proxy → Vericto API) | ||
VERICTO_API_URL | — | Vericto API URL. Use https://api.vericto.com. Setting it (with the key) enables telemetry and rule sync. |
VERICTO_API_KEY | — | Workspace API key (vtro_…) with rules:read + telemetry:write scopes. Store it as a secret. |
VERICTO_DATABASE_ID | — | The 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_SECS | 300 | How often the proxy polls for ruleset changes. Minimum 30 s (lower values are clamped to 30). |
| Evaluation and health | ||
VERICTO_MAX_QUERY_BYTES | 10485760 | Largest 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_PORT | — | Dedicated 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_SSLMODE | disable | disable, require, or verify-full. Encrypts the proxy → database hop. |
UPSTREAM_SSLROOTCERT | — | CA for verify-full. If omitted, uses the system public CA roots. |
UPSTREAM_SSLCERT / UPSTREAM_SSLKEY | — | Client certificate for upstream mTLS (cert auth). Applies only on the PostgreSQL hop. |
PROXY_TLS_MODE | disable | disable or require. Terminates TLS on the app → proxy hop. |
PROXY_TLS_CERT / PROXY_TLS_KEY | — | Server certificate and key (PEM) when PROXY_TLS_MODE=require. |
| Telemetry (see the next section) | ||
VERICTO_TELEMETRY_BUFFER | memory | memory or disk. Buffering strategy before delivery. |
VERICTO_TELEMETRY_DISK_PATH | /var/lib/vericto/spool | Spool directory when the buffer is disk. |
VERICTO_TELEMETRY_MEMORY_CAPACITY | 10000 | Max events in the in-memory ring buffer before the oldest are dropped. |
VERICTO_TELEMETRY_BATCH_SIZE | 100 | Max events sent in each POST /ingest/events batch. |
VERICTO_TELEMETRY_FLUSH_SECS | 5 | How 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=requireand 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:
| Mode | Behavior | Best 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.
| Workload | CPU | Memory | Disk | Queries/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 / Driver | Configuration | Example |
|---|---|---|
| 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 doctorto confirm config, connectivity, auth, and your remaining monthly quota in one command. - HTTP API: Send a test batch and check the response. A
200with"exit_code": 0and"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.