Skip to content

Tenant isolation

Venturi enforces isolation between tenants by construction — separate data stores, separate encryption keys, and a query layer that rejects any cross-tenant access. This page describes exactly how your data is kept apart from every other tenant's, and how Venturi support is prevented from holding standing access to it.

Target-state — record-level isolation and break-glass enforcement

Per-tenant data stores, per-tenant KMS keys, and the consent-gated aggregation boundary are GA and customer-inspectable. The record-level isolation invariant described below — the 403 TENANT_MISMATCH rejection carried through token, authorization, and audit — and the enforced support break-glass approval gate are Target-state controls being wired against the canonical identity model; not yet general. Rely on the binding labels in Docs authority & product state before treating either as GA.

Isolation primitives

Tenant isolation is built from per-tenant resources, not from row-level filtering on a shared store.

Resource Isolation model
Attribution store (Postgres) Each tenant's AttributionRecords live in a tenant-scoped database. Records for tenant T are accessible only to tenant T (and to Venturi support under the break-glass procedure below).
Event stream (Kafka) Event streams are tenant-scoped; the topic namespace is tenant-isolated.
Encryption keys (KMS) Every database and tenant-scoped object-storage bucket uses a customer-managed KMS key — one key per tenant — in your own KMS key store.
Audit trail The audit log is tenant-scoped; cross-tenant audit access is contractually prohibited.
Deterministic resolution Stage A of the attribution pipeline operates entirely within your VPC, with no shared state across tenants.

Per-tenant keys

Each tenant's encryption keys live in your own key store. Venturi workloads receive only Decrypt and GenerateDataKey on your key — never ScheduleKeyDeletion. Keys are rotated annually, or on a cadence you define.

This per-tenant key model is also the mechanism behind certified erasure: destroying a per-subject or per-tenant key renders the data encrypted under it permanently unrecoverable. See crypto-shred erasure.

Cross-tenant access is rejected, not filtered

Every request to the query API carries a Bearer token that resolves to a tenant_id. The token's subject claim is mapped to the tenant_id in the request path, and any mismatch returns HTTP 403 with the structured error code TENANT_MISMATCH — the request never returns rows belonging to another tenant. Cross-tenant attempts are additionally logged with full request context for security audit.

GET /v1/tenants/acme/attributions/abc123
Authorization: Bearer <token bound to tenant "globex">

HTTP/1.1 403 Forbidden
Content-Type: application/json

{
  "error": "TENANT_MISMATCH",
  "message": "Token tenant does not match the requested tenant."
}

This is an enforced engineering invariant — a cross-tenant query returns 403 TENANT_MISMATCH and never returns rows from a different tenant — covered by a dedicated property test.

Token validation discipline

Bearer tokens are verified for issuer, audience, expiry, and signature before any authorization decision. Tokens using alg:none or otherwise unsigned are rejected. Tenant binding — the subject-to-tenant_id mapping — is enforced only after signature verification: a token is never trusted to assert its own tenant before its signature is validated (RFC 8725, JWT Best Current Practices).

The model is shared; your data is not

Venturi's attribution-intelligence model uses shared model weights across tenants — there are no tenant-specific weights — with per-tenant calibration and per-tenant thresholds applied at inference time.

No tenant's data trains a model another tenant consumes

No tenant's data is used to train a model another tenant consumes, except under explicit, scoped, de-identified cross-tenant aggregation permission (described below). Your raw data never becomes another tenant's training input.

Any cross-tenant signal aggregation — used to improve the baseline models — runs in a separate, Venturi-managed Aggregation VPC that no tenant data plane can read. It operates only with explicit, scoped, de-identified permission, and is off by default for general-availability customers.

  • Explicit, informed, revocable consent. Participation is opt-in via your agreement; opt-out is available at any time and is recorded in your audit trail.
  • De-identification before egress. All tenant-identifying attributes are anonymized before any data leaves your VPC. The training pipeline reads only from the Aggregation VPC — never from tenant data planes directly.
  • k-anonymity with a minimum cohort of 5. Cohort outputs enforce a minimum cohort size of k = 5, with sub-cohort suppression and roll-up, and blocking of reconstruction-by-differencing across overlapping cohorts. A documented re-identification-risk acceptance test gates the pipeline.
  • Per-jurisdiction residency filtering. EU tenants do not contribute to non-EU aggregations, and vice versa.

Once anonymized into the Aggregation VPC, a contribution is non-personal. See Residency & subprocessors for the region-pinning guarantees and Data privacy & retention for how this interacts with erasure.

Support access is break-glass only

There is no standing Venturi support access to your data. Any support access to a tenant's database or runtime is break-glass:

  • Time-boxed — each access is short-lived, not persistent.
  • MFA-gated — it requires a second factor.
  • Audit-logged — every access is recorded to your tenant audit trail.
  • Customer-notified — the access triggers a notification to you.

This satisfies the GDPR Art. 28(3)(b) confidentiality-of-personnel obligation and the AICPA Trust Services logical-access criteria. For the full break-glass flow and what is visible to Venturi staff before a grant exists, see Support-access architecture.

What a reviewer can verify

Question Answer
Is my data in a shared database? No. Your AttributionRecords live in a tenant-scoped database, encrypted with your own KMS key.
Can another tenant query my data? No. Cross-tenant queries return 403 TENANT_MISMATCH, are logged, and never return another tenant's rows.
Does another tenant's model see my raw data? No. Model weights are shared, but your raw data is never another tenant's training input unless you explicitly opt into de-identified aggregation.
Does Venturi support have standing access? No. Support access is break-glass: time-boxed, MFA-gated, audited, and notified.
Who controls the encryption keys? You do. Keys live in your KMS store; Venturi holds only decrypt/generate, never delete.