Data handling

The one-pager — where each byte lives, how it's encrypted, how tenants are isolated, and why a hijacked model still can't act.

One page, no marketing: where your bytes live, how they're protected, and the structural reasons an AI agent with access to your accounts can't misuse them.

Where each byte lives

DataStoreNotes
Memory ledger, vault notes, briefs, profile snapshotsGoogle Cloud Storage, under your space's own prefixMarkdown; the canonical copy of your content
Metadata and indexes (note index, jobs, schedules, proposals, audit log, rosters)Firestore, keyed or subcollectioned by spaceDerived or operational; the audit log is append-only by construction
Search vectorsPrivate vector index (Milvus), reachable only inside our VPCDerived from your markdown; rebuildable, never the source of truth
Connector OAuth tokensFirestore, KMS envelope-encryptedDecrypted only inside the gateway at the moment of use. Never held by WorkOS, never sent to agents or models
Your Anthropic API key (hosted runner)Firestore, KMS envelope-encryptedDecrypted per run, delivered to the model process's environment — never into the model's context window
Payment detailsStripeWe store only customer/subscription ids
Sign-in identityWorkOSAuthentication only
Feedback reports and their screenshotsFirestore + Google Cloud Storage, under your space's prefixStays in our environment. Credential-scrubbed before write; the screenshot is optional and disclosed to you before sending
Product analytics and session replayPostHog Cloud (US)Runs outside our Google Cloud environment. Session recordings mask form inputs but not page text, so they can contain your own content; server events carry counts and flags only. Never receives credentials, connector tokens, or connector content
Notification deliveries (email)Resend Cloud (US)Transactional notification delivery. Receives recipient email address and notification title/body only — never vault/memory content or connector data. Opt-in channel. DPF-certified. Deletes data 90 days post-termination

Encryption

  • In transit: TLS everywhere.
  • At rest: everything is encrypted at rest by Google Cloud's default encryption; credentials (connector tokens, your Anthropic key) carry an additional KMS envelope, so even a raw datastore read yields ciphertext.
  • Logs are scrubbed of every credential class we handle before they're written.

Tenant isolation

The space is the isolation unit. Every API route derives the space from your verified membership server-side — a client-supplied id can't widen it. Per-space data lives under per-space prefixes and subcollections, so cross-tenant access has no accidental path. Hosted skill runs execute one job per instance in fresh, per-run scratch directories wiped afterward, with every tool bound to one space server-side.

This isn't just policy — it's tested adversarially: a cross-tenant attack suite (forged ids, capability replay across spaces, tenant-confusion probes) runs in CI and gates every release.

The injection posture — why a hijacked model can't act

Agents read content attackers can author: emails, Slack messages, task descriptions. We assume prompt injection will sometimes fool the model, and we've built the walls so that a fooled model still can't do harm. Outermost wall first:

  1. The executable-action gap. Models and agents can only propose actions. A single server-side execution service is the only code that writes to your connected accounts, and it runs only on your approval. Risk is assigned by a server-side catalog — a model can't understate what an action costs — and send-class actions are never auto-approved. The worst case of a perfect injection is a proposal sitting in your inbox, attributed to the skill that made it, waiting for a human to reject it.
  2. Closed tool surface. Hosted runs have no shell, no filesystem access, no tool that takes a URL. The model's reachable world is a short allowlist of space-bound tools — exfiltration has no transport.
  3. Credentials never enter the model. Connector reads are proxied through the gateway; the model sees items, never tokens. Your Anthropic key rides the process environment, not the prompt.
  4. Untrusted content is marked. Connector content arrives inside explicit untrusted-data fences (escape attempts are neutralized) with a standing contract: fenced content is data, never instructions.
  5. Limits. Turn caps, hard timeouts, payload caps, and bounded retries keep any single run's blast radius small.

Every proposal transition lands in an append-only audit log with its actor — you, policy, or the skill.

Export and deletion

  • Export: a zip of your whole space, free on every plan, via a short-lived private link.
  • Deletion: removes your Cloud Storage objects (all versions, including export archives), Firestore documents, vector index entries, feedback reports and their screenshots, and KMS-encrypted credentials; deletes your stored connector tokens (removing our access — provider-side grants are revoked from that provider's connected-apps settings); removes your WorkOS identity; cancels your Stripe subscriptions and deletes the customer record; and deletes your PostHog analytics identities and session recordings, with the associated events queued for permanent erasure (PostHog processes those asynchronously). Backup snapshots age out within ≤14 days. Deletion is idempotent — an interrupted delete converges on re-run.

Questions or a fuller architecture discussion: support@davidchang.dev.