Privacy & security

This page describes what the code does today, including its limits.

PII shield

Text passes through the PII shield before embedding or storage. Two strategies:

StrategyEntity types
Tokenized (deterministic, HMAC-based, reversible only through your local vault)email, person, phone, location, organization, URL, IBAN, credit card, date/time, national registration number, IP address
Redacted (replaced by [REDACTED_<TYPE>], never tokenized)password, API key, AWS key, JWT, private key, crypto wallet

Secret guard

A second server-side layer detects credentials (private keys, JWTs, AWS keys, GitHub tokens, sk- and Stripe-style keys and more) and replaces them with [REDACTED:<kind>]. If almost nothing remains, the write is blocked. It also runs on imports. The macOS app drops secrets on the device before upload.

Per-user isolation

  • Each user has a separate store and data directory. Every memory API call resolves your own store from your credential; another user's memory id is simply "not found".
  • System admins (/admin/api/*) can list users, companies, plans and tokens. Their view of a user's memories is truncated to 200 characters of anonymized content (content_anon), never the raw text.

Authentication and tokens

  • Accepted credentials: EAM API token, EAM session token, Thundera SSO cookie, or a Thundera OIDC access token. See API reference.
  • API tokens are stored as a hash and shown once. One active token per account; creating a new one revokes the old one.
  • Revoke a token in Settings or with DELETE /api/v1/tokens/{id}.
  • Rate limits: 10 requests/min per IP on credential endpoints, 600 requests/min per credential on write, search, context and MCP.

Backup

GET /api/v1/backup exports your ACTIVE memories as JSON (content, source type, tags, pinned, relevance, access count, created time, entity ids, supersede links). Soft-deleted and superseded memories are not included. POST /api/v1/restore re-writes them through the normal pipeline in import salience mode; duplicates and empty items are skipped, not restored in place.

The export is readable text

A backup contains memory content (the raw text when available, otherwise the anonymized text). Treat the file like the data itself.

Wipe

POST /api/v1/wipe requires {"confirm":"WIPE ALL MEMORIES"}. It soft-deletes every ACTIVE memory (status SOFT_DELETE), including pinned ones, and logs the event. Soft-deleted memories are hidden and can be restored one by one with POST /api/v1/memories/{id}/restore. To remove them for good, call POST /api/v1/memories/purge with their ids; pinned memories are never purged.

Wipe is not a hard delete

Wipe hides your memories; it does not erase the underlying data. Purge is the irreversible step.

Where embeddings run

Embeddings use a local model in offline mode. The production deployment makes no calls to a hosted language model. DREAM is deterministic.