Multi-tenant isolation
Every Vorel customer (“tenant”) shares the same Postgres database. Cross-tenant data leakage prevention is a 4-layer defence:1
Postgres Row-Level Security (RLS)
Every tenant-scoped table has a policy: rows are visible only when the row’s
tenant_id matches the current request’s tenant context. The Vorel app connects as a non-superuser database role. Forgetting to set the tenant context returns zero rows: fail-closed by design.2
Transaction-scoped tenant context
Every tenant-facing route opens a Postgres transaction and sets the current tenant context as the first statement. Exits cleanly on commit/rollback.
3
Operator-side admin lint
Operator-console reads use a separate database client that bypasses RLS by design (it’s used for cross-tenant operator views like the tenants list). Every such query MUST filter by tenant explicitly. Our CI runs a static check that flags any cross-tenant query without an explicit tenant filter and blocks the PR. Legitimate cross-tenant queries (e.g. listing all tenants) need an explicit annotation explaining why.
4
Append-only triggers
Audit, billing and lifecycle-transition tables reject UPDATE + DELETE via Postgres triggers, and the message table permits updates only on a narrow whitelist of columns. Even if RLS were bypassed, mutation isn’t possible from the application’s database role.
Encryption
Append-only audit
Several tables capture immutable trails:- Conversation turns: every message, immutable once written apart from a narrow whitelist of operational columns. Underpins the transcript that QA scoring and analytics rely on.
audit_log: every operator-console read AND every mutation. Forensic trail for who-saw-what and who-did-what, covering operator actions and reads alike.billing_events: every cost-of-goods event and every chargeable event. Immutable for accounting integrity.- Lifecycle transitions: case transitions, customer merges, outreach logs and CRM webhook events, all total-immutable.
pci_vault_redirect_issued / pci_vault_redirect_completed / pci_vault_redirect_failed (PCI vault-redirect payment flows), pci_enable_toggled / pci_vendor_changed (per-tenant PCI configuration), crm_as_sor_enforcement_disabled (per-tenant CRM-write enforcement override), and impersonation_started / impersonation_ended (operator view-as-tenant sessions).
Rate limiting
Vorel enforces a layered rate-limit stack to defend against floods, accidents, and runaway integrations:
Built on a fixed-window primitive backed by our in-memory data store, with a fail-open posture: a transient cache outage admits all traffic rather than 429-everyone. Plan-aware limits land at the call site when our billing model launches.
Right-to-access + right-to-erasure
Vorel ships first-class endpoints for PDPL Art. 15-17 + GDPR Art. 15-17:POST /api/tenant/export(operator-gated): returns a ZIP ofconversations + messages + leads + appointments + offerings + knowledge_base + audit_logfor a single tenant. Default redaction: customer email + phone redacted; opt-out viainclude_full_pii=true(audit-logged). Includes a chain-of-custody README.POST /api/tenant/forget(operator-gated, dry-run-by-default): runs a 7-step scrub for a single customer phone within a single tenant: tombstones conversations, redacts message content, nulls leads/appointments PII, scrubs audit-log JSONB references. Wrapped in a Postgres transaction for atomicity. Salted-hash audit-log references so the deletion event is provable without re-introducing the PII.
SLOs
We maintain a set of 5 service-level objectives:
A 4-state error-budget policy (healthy / caution / concern / exhausted) drives engineering response.
An SLO is a floor we commit to, not a description of typical performance. Voice turns normally
complete well inside the p95 target. See How it works for current
latency.
Observability + incident response
- OpenTelemetry tracing exported to a managed observability backend for distributed tracing + custom metrics dashboards.
- Centralized error monitoring for uncaught exceptions across web + workers.
- Structured JSON logs with W3C trace-context propagation across every cross-process boundary.
app.vorel.ai/status: public status page with operator-curated incident banner.- Incident response playbook: sev definitions, RACI matrix, 6-phase response, tenant comms templates aware of PDPL Art. 17 + GDPR Art. 33’s 72-hour regulator-notification window.
Compliance posture
For the formal documents (DPA template, PII inventory excerpt for buyer due diligence, SLO commitments), see Compliance.
Controls you operate yourself
The controls above are ours. These are yours:- Roles and permissions for your team. See Access control.
- API keys with scopes, expiry, atomic rotation and per-key call budgets.
- Approval policies for anything an assistant can do on your behalf.
- Tool permissions, which remove a capability from the agent rather than asking it not to use one.
- Retention overrides, to narrow retention below the platform default.
Bug bounty + disclosure
We don’t run a formal bug bounty today. To report a security issue: emailsecurity@vorel.ai with details. We’ll acknowledge within 48 hours, triage within 5 business days, and credit you in the changelog once fixed if you’re comfortable with disclosure.
We do NOT use Vorel-collected customer data for any purpose other than running your tenant. We do NOT sell, share, or analyse customer data across tenants. We do NOT use customer conversations for training third-party AI models.