Security.
The trust model is the differentiator. This page describes how it works, with the real package names so your team can audit it directly.
Tenant isolation
Every read and write resolves the authenticated tenant from a Clerk org session, mapped to a server-side tenant_id. Durable tenant-owned rows in Postgres are protected by Row-Level Security policies that default to deny — there is no path to another tenant's data through the API or MCP surfaces.
Headers from clients cannot override the authenticated tenant. Production fails closed on unmapped Clerk sessions and on retired identity rows.
Source ACL flow-through
Source-derived authorization is evaluated by a pure evaluateAcl function in @context-company/core. It denies by default. Multi-evidence claims require every supporting evidence object to be readable by the caller before the claim is surfaced. Agent principals re-check after tenant checks.
If a user can't read the Notion page, the agent context pack derived from it can't either. Mixed evidence defaults to the most restrictive ACL.
Sanitization and data handling
A shared sanitizer in @context-company/core redacts prompt-injection text and secret-like values from every generated context surface — compiler, DB, MCP, and the web app reuse the same regexes. Evidence is de-duplicated on raw source text before sanitizing so redaction does not collapse distinct citations.
Public REST and MCP payloads omit tenant IDs, source-connection IDs, external IDs, provider tokens, raw settings, and hidden record counts. Redactions are reported as generic counts and reasons.
Approval-gated writes
No agent posts to a source without a durable, server-side approval. Approval rows are tenant-owned and keyed by candidate ID. Reviews advance pending records only; execution atomically transitions approved → executing and writes an execution-attempt outbox row before any provider call.
Execution endpoints accept durable approval IDs only. Client-supplied approved flags or candidate bodies are never sufficient. Failures stay retryable; provider-success recording gaps enqueue reconciliation without duplicating writes.
Sub-processors
The product runs on a small list of named sub-processors:
- Clerk — authentication, organization and user directory.
- Supabase — Postgres database with Row-Level Security, durable object storage for raw events.
- OpenAI — embeddings and model-assisted draft authoring (every generated artifact is a draft proposal until owner review).
- Vercel — application hosting.
- Trigger.dev — durable job runner for normalization, embedding, backfill, skill learning, observability, and maintenance queues.
- Sentry — error and performance monitoring; PII and request bodies are opt-in and disabled by default.
We do not subprocess to model providers other than OpenAI on day one, and we do not relay your normalized data to any third-party analytics, marketing, or session-replay systems.