Vorel handles customer PII on your behalf. This page documents the technical controls that protect that data — what’s in place today and what’s on the roadmap. For the formal compliance picture (DPA, certifications, regulator-facing language), see Compliance.Documentation Index
Fetch the complete documentation index at: https://docs.vorel.ai/llms.txt
Use this file to discover all available pages before exploring further.
Multi-tenant isolation
Every Vorel customer (“tenant”) shares the same Postgres database. Cross-tenant data leakage prevention is a 4-layer defence:Postgres Row-Level Security (RLS)
Every tenant-scoped table has a policy: rows are visible only when
tenant_id = current_setting('app.current_tenant_id')::uuid. The Vorel app connects as the vorel_app Postgres role (NOT a superuser). Forgetting to set the tenant context returns zero rows — fail-closed by design.Transaction-scoped tenant context
Every tenant-facing route opens a Postgres transaction and
SET LOCAL app.current_tenant_id = '<uuid>' as the first statement. Exits cleanly on commit/rollback.Operator-side admin lint
Operator-console reads use a separate Prisma client (
adminPrisma) that bypasses RLS by design (it’s used for cross-tenant operator views like the tenants list). Every adminPrisma.<model>.find* call MUST filter by tenantId explicitly. Our CI runs a static check (apps/web/scripts/lint-admin-prisma.ts) that flags any call without a tenantId filter and blocks the PR. Legitimate cross-tenant queries (e.g. listing all tenants) need an explicit comment annotation explaining why.Encryption
| Layer | Mechanism |
|---|---|
| At rest (Postgres) | Disk-level encryption (Railway-managed) |
| At rest (Redis) | Disk-level encryption (Railway-managed) |
| In transit (internal) | TLS within the Railway internal network |
| In transit (public) | Cloudflare-terminated TLS at app.vorel.ai (HSTS preloaded, 2yr) |
| CRM credentials | Envelope-encrypted: AES-256-GCM with per-row data encryption keys, KEK in AWS KMS for production |
| Webhook outbound | HMAC-signed bodies + TLS to your URLs |
| Tenant API keys | bcrypt-hashed at rest (never stored plaintext) |
| JWTs | HS256 over rotated shared secret, short TTL (5 min for tool calls, 2 min for worker calls) |
Append-only audit
Three tables capture immutable audit trails:messages— every conversation turn, immutable once written. Underpins the conversation transcript that QA scoring + analytics rely on.audit_log— every operator-console read AND every mutation. Forensic trail for who-saw-what + who-did-what. Includes both operator actions (e.g. “claimed voice number for tenant X”) and reads (e.g. “operator opened tenant X’s CRM-credentials page”).billing_events— every cost-of-goods event (Vapi + Telnyx + Gemini per call) AND every chargeable event (per conversation, per minute). Immutable for accounting integrity.
vorel role used for retention sweeps + the right-to-erasure path.
Rate limiting
Vorel enforces a 4-layer rate-limit stack to defend against floods, accidents, and runaway integrations:| Layer | Limit | Where |
|---|---|---|
| Per-IP webhook | 500 req/min | /api/webhooks/* (before signature verification) |
| Per-Clerk-user dashboard | 200 req/min | All authenticated dashboard surfaces |
| Per-(tenant, tool) | 50 req/min | Each of the 14 internal tool endpoints |
| Per-(tenant, agent-router) | 1000 req/min | The agent dispatch chokepoint |
| Per-tenant aggregate | 5000 req/min | Across all surfaces |
| Per-customer-number (chat) | 30 req/min | WhatsApp inbound, post-payload-parse |
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 publish 5 service-level objectives athandoff/docs/SLOs.md (open-source for transparency):
| SLO | Target |
|---|---|
| Tool surface success rate | 99.9% |
| Voice call success rate | 99.5% |
| Voice turn p95 latency | < 3s |
| Operator console availability | 99.9% |
| Outbound webhook delivery | 99.0% (within 30 retry-window) |
Observability + incident response
- Honeycomb (OpenTelemetry exporter target) for distributed tracing + custom metrics dashboards.
- Sentry for uncaught exceptions across web + workers.
- Pino structured logs with W3C trace-context propagation across every cross-process boundary (web → worker → n8n → web).
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. See
handoff/docs/security/INCIDENT-RESPONSE.md.
Compliance posture
| Standard | Status |
|---|---|
| PDPL (UAE Personal Data Protection Law) | Documented; PII inventory + DPA + automated right-to-access + erasure paths all live |
| GDPR | Same paperwork posture. EU regions captured (tenant.region='eu'); per-region routing on roadmap |
| SOC 2 Type 1 | Foundational paperwork shipped (PII inventory, data flow, IR playbook). Drata/Vanta engagement on roadmap |
| SOC 2 Type 2 | Requires 6 months of operational data after Type 1 |
| HIPAA | Per-customer engagement (BAAs with all PHI-touching vendors). Clinic vertical pack ships with safety guards (forbidden_phrases='diagnose') but full HIPAA is not turn-key |
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.