Skip to main contentSkip to main content
Skip to main content

Trust Center

How Ophie encrypts, stores, and deletes your data. Engineering details written for users, not just auditors.

Looking for the plain-English version? Read /security for a consumer overview of our encryption-at-rest model.

Last Updated: May 4, 2026

Pre-Launch Engineering Draft

This Trust Center describes practices Ophie intends to operate at public launch. It has not undergone external legal or security audit. Claims have been reviewed internally against the codebase by the founding team.

Summary

Every session transcript, memory, and insight you share with Ophie is protected with a per-user envelope encryption key — a Data Encryption Key (DEK) — stored wrapped under an AWS KMS Customer-Managed Key (CMK). Your ciphertext lives in Supabase Postgres. The KMS CMK never leaves AWS; our agent unwraps your DEK once per session, uses it to encrypt with AES-256-GCM + AAD, and never writes the raw key to disk or logs.

This page answers three questions for every layer of the stack: what is encrypted, by whom, and what survives a breach. We also document what is not protected — because honest scope matters more than marketing confidence.

Transparency commitment

If a section below understates a risk or overstates a control, email team@ophie.app. We will update the page and credit the reporter.

1. Encryption Architecture

The diagram below shows the full dataflow from your microphone to persistent storage:

Ophie encryption architecture: user device connects via WebRTC to LiveKit Cloud; transcript flows to Ophie agent; AWS KMS CMK unwraps the DEK once per session; agent performs AES-256-GCM AEAD encryption; ciphertext stored in Supabase Postgres; vector embeddings plus opaque ciphertext sidecar stored in Pinecone; Postgres Decrypt events logged to CloudTrail then to CloudWatch alarms

Encryption primitives

  • Algorithm:AES-256-GCM with Additional Authenticated Data (AAD). The AAD binds each ciphertext to its owner's user ID, preventing cross-user ciphertext reuse.
  • Key hierarchy: AWS KMS CMK (annual rotation enabled) wraps per-user DEKs. DEKs are stored wrapped in user_profiles.encrypted_dek; the KMS CMK never leaves the AWS HSM boundary.
  • HMAC fingerprint: a separate HMAC key (encrypted_mac_key) covers one indexed column per table for equality lookups without decrypting row content.
  • Transport: WebRTC (DTLS-SRTP) from your device to LiveKit Cloud; TLS 1.2+ from LiveKit to the Ophie agent and from the agent to all backend services.

2. Key Rotation Cadence

KeyRotation TriggerMechanism
AWS KMS CMKAnnual (automatic)AWS KMS automatic key rotation enabled — verifiable in Terraform module infrastructure/terraform/modules/kms/
Per-user DEKOn-demand via runbook (TRUST-07)New DEK generated; all ciphertext re-encrypted in background; old DEK NULLed after PITR window closes
JWT signing keysManaged by Supabase AuthNot under application control; Supabase rotates per their SLA

Per-user DEK rotation is triggered manually via the TRUST-07 runbook. The cleanup gate ensures the old DEK remains readable through the PITR window, then is NULLed permanently.

No automatic per-user rotation at this time

Automatic per-user DEK rotation on a schedule is not yet implemented. It is tracked as a future requirement (FUTURE-11). The current model provides key isolation between users; rotation within a single user account requires operator action.

3. Threat Model

What envelope encryption protects against

  • Leaked Postgres backup: a raw database dump exposes only ciphertext. Without access to AWS KMS, the attacker cannot decrypt session content.
  • Supabase support staff access: Supabase support sees only wrapped DEKs and AEAD ciphertext. Content decryption requires KMS authorization, which logs every call to CloudTrail.
  • Stolen service-role key: the service-role key can read rows but not decrypt them without also compromising AWS credentials with KMS Decrypt permission.

What envelope encryption does NOT protect against

  • Compromised FastAPI process: the agent holds the unwrapped DEK in memory during an active session. An attacker with process-level access can extract it. This is inherent to server-side decryption; it is not a gap we can close without client-side cryptography (which is not part of this architecture).
  • Pinecone vendor-side dashboard access:vector embeddings and the ciphertext sidecar live in Pinecone under Ophie's account. Pinecone staff with dashboard access can see these values. We do not have CMEK on the Standard tier (see §4). The ciphertext sidecar is opaque, but the vector embedding is not.
  • LiveKit audio in transit:LiveKit Cloud receives your audio stream (DTLS-SRTP). The media bytes are accessible to LiveKit's infrastructure during routing. Transcription happens in our agent, not at LiveKit.
  • JWT signing keys: authentication tokens are signed by Supabase Auth. A Supabase-side compromise of the signing key would allow impersonation. We do not control this key.

4. Pinecone Posture

Ophie uses Pinecone Serverless (Standard tier) for vector similarity search over session memories. This tier does not offer Customer-Managed Encryption Keys (CMEK). We completed a formal risk-acceptance review before shipping this configuration.

ControlStatus
CMEK (customer-managed keys)Not available on Standard tier — risk accepted
Per-user namespace isolationEnabled — each user's vectors are in a separate namespace
Chunk sizeAt least 128 tokens per chunk — limits re-identification from partial fragments
Ciphertext sidecarEach vector stores an opaque AEAD ciphertext in metadata — the actual transcript content requires KMS decryption to read
Kill-switch playbookDocumented internal runbook — deletes all user namespaces if Pinecone is compromised

The decision: the Standard tier posture is acceptable for pre-launch given the ciphertext sidecar pattern and namespace isolation, with a commitment to evaluate CMEK if Pinecone adds it to Standard or if usage grows past the Enterprise tier threshold.

5. Disclosed Leakage

The following surfaces represent known leakage vectors — places where some data may be visible outside the encrypted envelope. We disclose them proactively.

  • Sentry stack-frame metadata: Ophie uses Sentry for error tracking. Stack frames may contain variable names or partial string values. CRYPTO-11 applies server-side PII scrubbing before any event is sent; content bytes are not intentionally included. Residual metadata risk exists if an exception occurs mid-decryption with cleartext in scope.
  • CloudWatch metric labels: KMS CloudTrail events include an EncryptionContext that contains the user_id. User IDs are not content — they are identifiers — but they are visible in CloudWatch metric dimensions to anyone with CloudWatch read access to the account.
  • Pinecone vendor-side dashboard: as documented in §4, Pinecone staff with dashboard access can see vector embeddings and the opaque ciphertext sidecar. The ciphertext sidecar content requires KMS decryption; the embedding does not.
  • DEK cache window (cross-process):when your account is deleted, the DEK is NULLed in the live database immediately. However, another active FastAPI worker that already loaded your DEK into its in-process cache may retain it for up to 10 minutes (the cache TTL). During this window, a hypothetical attacker who can read that worker's memory could still decrypt ciphertext. We do not promise sub-second cross-process eviction. (See §7 for the full caveat.)

6. Deletion Timeline

When you delete your account, the following sequence runs:

  • Immediately (T+0): your DEK is set to NULL in the live database and your in-process DEK cache is evicted. Encrypted rows are tombstoned with a deleted_at timestamp. Pinecone vectors are deleted (vendor-side delete via API).
  • After PITR window closes (currently total): a background sweep permanently hard-deletes all tombstoned rows from the database. At this point, even a Postgres PITR restore cannot recover your content — the DEK needed to decrypt the restored ciphertext no longer exists in any live backup.

Forget-session caveat (D-05)

Forgetting an individual session is a row-only delete — the row is removed and swept after the PITR window, but the account-level DEK is not NULLed. Full crypto-shred (DEK NULL) only happens at account deletion. This is because a single DEK encrypts all your sessions; NULLing it for one session would destroy the rest.

The deletion timeline value above is read live from our backend configuration. It reflects the current Supabase PITR retention setting. If the PITR window changes, this page updates automatically within 5 minutes.

7. Honesty Caveats

Two-person review status

Two-person review is enabled when our team has ≥2 security reviewers. Today, with a solo founder + AI-assisted review, every encryption-touching change is recorded with a signed self-review log committed alongside the change.

DEK cache invalidation window

Decrypt cache invalidation is per-process; in the worst case, a previously-cached DEK on another worker remains usable for up to 10 minutes after account deletion. We do not promise sub-second cross-process eviction. The DEK is NULLed in the live database at T+0; the cache window is a residual exposure documented in §5.

Self-review audit trail

Each encryption-touching pull request includes a committed self-review entry using a dedicated encryption PR template. These entries are not a substitute for independent audit; they are a compensating control during the pre-launch solo-founder phase.

Questions about our security practices? team@ophie.app. For privacy questions, see our Privacy Policy.