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.
Cross-tenant aggregation (consent-gated)¶
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. |
Related pages¶
- Security architecture — the trust boundary, encryption, and the threat model.
- Data privacy & retention — what is collected, retention, and crypto-shred erasure.
- Residency & subprocessors — region pinning and the aggregation environment.
- Data-subject rights — how erasure requests reconcile with the append-only architecture.