Data Flow & Isolation
This page describes what data enters the VeriProof platform, how it moves between components, and what guarantees apply to isolation between tenants and between deployment tiers.
What the SDK sends
When your application calls the VeriProof SDK, it sends an OTLP (OpenTelemetry Protocol) trace payload containing:
| Data type | What it contains | Sent by default |
|---|---|---|
| Span metadata | Span ID, trace ID, timestamps, duration, status | ✅ Always |
| Governance attributes | Risk level, decision context, guardrail actions, intent | ✅ When annotated |
| Session metadata | Application ID, session ID, tenant ID | ✅ Always |
| Merkle root | SHA-256 root over all spans in the batch | ✅ Always |
| Content (prompts/completions) | Input text, output text, retrieved documents | ❌ Off by default |
Content capture is an explicit opt-in. When disabled (the default), the payload contains no text from your AI application’s inputs or outputs — only structured metadata describing what happened.
Even with content capture enabled, captured text is encrypted at rest using AES-256-GCM before it touches persistent storage.
Standard Tier data flow
[Your AI App]
│ SDK: OTLP payload + Merkle root
│ Headers: X-API-Key, x-functions-key
▼
[Ingest Functions API]
│ Validates API key identity (CustomerTenantKey table)
│ Verifies Merkle root matches payload
│ Rejects if mismatch → HTTP 422
│
├──▶ [PostgreSQL — customerportal schema]
│ session_traces, span_records, governance_events
│ (isolated by CustomerId + PostgreSQL RLS)
│
└──▶ [Notary Outbox — notary schema]
notary_outbox queue
[Blockchain Functions — background worker]
│ Reads from notary_outbox
│ Groups batches by time window
│ Computes CMT update
▼
[Solana Mainnet — Concurrent Merkle Tree]
└── Transaction recorded on-chain
⬆ transaction_id written back to session recordsData never leaves VeriProof’s Azure infrastructure in the Standard Tier. All data is stored in the region selected at account creation (default: West Europe).
Enterprise Tier data flow
The Enterprise Tier modifies the flow so that session content stays inside your Azure subscription:
[Your Azure Subscription]
─────────────────────────────────────────────
[Your AI App]
│ SDK
▼
[Confidential Notary — Your ACI, AMD SEV-SNP]
│ Computes Merkle commitment (32 bytes)
│ Encrypts full session record (AES-256-GCM)
│
├──▶ [Your PostgreSQL] ← Full session data stays here
│ (all spans, governance events, content)
│
├──▶ [Your Azure Blob (WORM)] ← Encrypted audit log
│
└──▶ [Your Azure Key Vault] ← Encryption keys
─────────────────────────────────────────────
│ 32-byte commitment only
▼ (crosses subscription boundary)
[VeriProof Central Infrastructure]
▼
[Blockchain Functions] ← Never receives session content
▼
[Solana Mainnet]What crosses the subscription boundary: Only the 32-byte SHA-256 Merkle commitment, the tenant ID, and the batch timestamp. VeriProof’s central infrastructure cannot reconstruct session content from a 32-byte commitment.
Tenant isolation guarantees
In the Standard Tier, every database query that touches session data passes through two independent isolation layers:
Layer 1 — EF Core global query filters: Applied at startup via reflection over all entity types that have a CustomerId property. Queries are automatically scoped to the requesting tenant’s ID before execution. This is a compile-time guarantee — it cannot be bypassed by individual query authors.
Layer 2 — PostgreSQL Row-Level Security: A separate database-level policy requires that app.current_customer_id is set in the session context and matches the row’s customer_id column. This policy is enforced by the database engine itself, independent of the application layer.
The only path to bypass either layer is an explicit and audited opt-out:
- EF Core:
IgnoreQueryFilters()— used only in admin/staff operations, which use a separate database role - PostgreSQL RLS: the
staff_roledatabase role — bypassed only for VeriProof’s Staff Portal, with full audit logging
See Multi-Tenant Isolation for the full architecture.
What is stored and for how long
| Data | Location | Retention (default) | Encrypted at rest |
|---|---|---|---|
| Session records and spans | PostgreSQL customerportal schema | Plan-defined (2–7 years) | ✅ TDE + column encryption |
| Governance events | PostgreSQL customerportal schema | Same as session records | ✅ |
| Notary outbox (pre-anchor) | PostgreSQL notary schema | Until anchored + 30 days | ✅ |
| Blockchain transactions | Solana — permanent | Permanent (on-chain) | N/A — public ledger |
| Captured content (opt-in) | PostgreSQL, encrypted | Same as session records | ✅ AES-256-GCM |
| API keys (hashed) | PostgreSQL customerportal schema | Until revoked | ✅ SHA-256 hash only |
| Audit log | PostgreSQL worker schema | 2 years | ✅ |
What VeriProof employees can access
VeriProof’s Staff Portal provides cross-tenant read access for customer support operations. Staff access:
- Uses the
staff_rolePostgreSQL database role (bypasses RLS) - Is restricted to authenticated VeriProof employees with verified OIDC identity
- Logs every read, write, and export operation to the audit log
- Does not include access to customer API keys (stored as one-way hashes)
- Does not include access to captured content unless explicitly shared by the customer
Data residency
| Tier | Default region | Custom region |
|---|---|---|
| Standard | Azure West Europe | Enterprise plans: contact us |
| Enterprise | Your subscription | You control your own subscription region |
Enterprise customers who deploy through Azure Marketplace’s Managed Application model have complete control over the Azure region of all components within their subscription.
Next steps
- Infrastructure Components — Azure services and how they are configured
- Encryption at Rest — storage encryption details
- Multi-Tenant Isolation — EF Core and PostgreSQL RLS architecture