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:
| Strategy | Entity 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.
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 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.