What it protects
What Vericto applies in a SaaS, all at the TCP proxy:
- Rules per database. They are configured per workspace, with per-database overrides, and the critical ones (DELETE and UPDATE without WHERE, DROP, TRUNCATE) block by default: the statement that would touch every row of every tenant never reaches the database.
- VERICTO-087 (Team and Enterprise): an allowlist of tables and columns per database user, in each database. Give each service its own user: the API, the workers, the support tool. Under an allowlist, DDL,
SET ROLE,SET search_pathandUSEare denied. - VERICTO-085 (Team and Enterprise): sensitive columns blocked or returned masked. The policy is per database and applies to all its sessions: if the support tool must see masked values and the application must not, give support its own proxy, registered as another database with masking on.
- VERICTO-019: disabling a table's Row Level Security or triggers, the basis of row-level isolation on Postgres.
- Audit trail per workspace. Every event carries its database and its identity (the database user or the API key), so you see each database's and each service's traffic separately. With sanitized telemetry, literals, such as your customers' data, are replaced before they leave the proxy.
What Vericto isolates, and what it does not
Vericto decides on the shape of each statement, not on the rows it returns, and it does not know the tenant of the request behind it. So:
- It does separate rules, allowlists and sensitive columns per database, and allowlists per database user. With a schema or a database per tenant and one user per tenant, an allowlist that names only its schema denies the other tenants' tables.
- It does not filter rows. In a shared table with a
tenant_idcolumn, Vericto cannot check that the WHERE filters on the right tenant: it does not know whether that request should gettenant_id = 42or43. That is what Postgres Row Level Security, or a schema or database per tenant, is for. - It does not authenticate your tenants, separate networks or credentials, or resolve views, functions and triggers. Your model's roles, grants, RLS and database separation are still the isolation mechanism; Vericto is defence in depth on top.
Latency and availability
Each statement adds the hop to its database's proxy and the evaluation in its process, with no network calls on the critical path. Allowlists and sensitive columns are decided on the AST, like any other rule, without reading results.
For parsing and rule evaluation, the design target is p99 < 2 ms. It is a target, not a measurement: the proxy latency benchmark is not published yet.
With one database per tenant, count the proxies: one per database is the simplest, and memory grows with connections, about 4 KB per TCP session. Protected databases depend on the plan: 1 on Free, 3 on Builder, 10 on Team and custom on Enterprise.
How to implement it
- Choose the model: a database per tenant or tenant group (the easiest to isolate), a schema per tenant, or shared tables with
tenant_idand RLS. Register each database in the workspace with its dialect. - Deploy one proxy per database (the container
ghcr.io/vericto/vericto-proxy) withUPSTREAM_HOSTpointing at it, and connect the services that use that database to it. - Create one database user per service (the API, the workers, the support tool) and, on Team and Enterprise, its allowlist in observe. Simulate it against its queries from the last 7 days and switch it to enforce.
- Tag each database's sensitive columns. If one service must see them masked and another must not, give it its own proxy, registered as another database.
- With shared tables, turn on Postgres Row Level Security and check that VERICTO-019, which catches it being disabled, is set to block.
- Before changing a rule for one database, simulate it against that database's real traffic (Builder, Team and Enterprise).
When not to use this option
- As the only isolation between tenants. Vericto is not a tenant-isolation mechanism: it does not see the request's tenant or filter rows. Use it on top of RLS or a database per tenant, not instead of them.
- Thousands of small databases, one per tenant. One proxy per database multiplies instances, and protected databases count against the plan: group tenants per database, or talk to sales about Enterprise.
- Oracle or SQL Server. There is no TCP proxy for those dialects: use the Runtime API with one API key per service. The allowlist then becomes a decision your code honours, not a control.
Plan availability
| Feature | Free | Builder | Team | Enterprise |
|---|---|---|---|---|
| TCP proxy (PostgreSQL and MySQL) | Yes | Yes | Yes | Yes |
| Queries per month (proxy and Runtime API) | 500K | 5M | 50M | Unlimited |
| Databases | 1 | 3 | 10 | Custom |
| Custom rules (YAML) | — | 5 | 20 | Unlimited |
| Per-agent allowlists (VERICTO-087) | — | — | Yes | Yes |
| Sensitive columns and masking (VERICTO-085) | — | — | Yes | Yes |
| Rule simulator | — | Up to 30 days | Up to 90 days | Per contract (up to 180 days) |
Prices and every limit on Pricing.