Privacy
what is indexed, what is stripped, what never leaves
deja indexes credential-bearing histories, so privacy is a first-order concern, not an afterthought.
What gets indexed
The conversation, and what the agent did while having it: the file paths its tool calls named, the commands it ran, the spans its edits replaced, and what its tools printed. That last part is why redaction matters — command output carries far more credentials than prose does — and every one of these paths goes through the same redaction pass as the conversation itself. Replaced spans are source code from your own files; they are stored so deja restore can hand work back, and they stay on the machine like everything else.
On every agent whose compaction deja captures (Claude Code, Codex, Qwen, Kimi, Grok, Cursor CLI, opencode, pi and the others in the compaction reference), the index also keeps a bounded packet of the working context captured just before a compaction — the task, conclusions, files and commands of that session, redacted like everything else, for at most 32 session/workspace pairs. It lives in the index manifest, is left out of sync exports, honours excluded projects and DEJA_RECALL=off, and deja forget removes it even before its session has been indexed. See compaction recovery.
Local by default
Indexing and search have no network path unless you turn on semantic search. The index and its usage sidecar never leave the machine. Network access happens only when you run deja update, deja sync ssh, the doctor version check (which --offline disables), or deja embed — which sends text to the endpoint you configured and is covered below. Once deja embed has built the semantic sidecar, every search and every recall also sends its query to that endpoint, once per call and with secrets masked by the same rules the index uses. The one exception to “when you run”: at most once a day, a command typed at a terminal asks GitHub for the latest release number in the background and says so on stderr when a newer one is out. It sends no session data, hooks, the MCP server and the other commands an agent starts never start it, even under a terminal, and DEJA_OFFLINE=1 turns it off, as does DEJA_NO_UPDATE_NOTICE set to any value, which also hides the note a new version prints on its first run.
Redaction
Secrets are stripped at index time — API keys, JWTs, PEM/PGP private-key blocks, bearer and HTTP Basic auth, provider tokens, scheme://user:pass@host URLs, (since 0.14.2) bare high-entropy values in secret-shaped positions — the value side of any assignment or a token alone on its own line — and (since 0.20.2) a password stated in prose, where nothing separates the name from the value: "the admin password is …". That last one needs the value to carry a digit or a symbol, so a sentence like "the password is wrong" keeps its words. A secret split by terminal color escapes (grep --color, colored loggers), Authorization: Token headers and Slack and Discord webhook URLs are masked too. All of it happens before anything is written. Redaction runs on the full message before any size cap, so a secret straddling the cap boundary can't slip through. Redacted output is what search, MCP recall, share and sync all serve, and deja share also masks home paths, including encoded folder names like -Users-<name>-src, and emails.
Control what's kept
- Exclude —
~/.config/deja/excludepatterns orDEJA_EXCLUDE_PROJECTSskip projects at index time, andsync exporthonours them too, so a project excluded later does not leave the machine. Sessions indexed before the pattern existed stay searchable locally untildeja index --rebuild;deja indextells you when that is the case. A tree named as one project in~/.config/deja/projectsdoes not override a pattern: a repository excluded by its own name stays out. - Exclude a whole store — a line prefixed
harness:in the same file names an agent instead of a project —harness:opencode— and deja neither walks that store nor asks for the tool that would read it.DEJA_EXCLUDE_HARNESSESis the comma-separated form. Store names are exact, not patterns: they are the onesdeja sourcesprints, and both it anddeja doctorthen report the store asexcludedrather than naming a package to install. - Forget —
deja forgetremoves sessions and records a tombstone so they don't come back on the next index;--dry-runto preview,--listto see the tombstones,--unforget <id>to reverse one. - Redaction report —
deja stats --redactionshows what was masked, per rule and harness. - Audit what agents received —
deja loglists recent recalls and injections;deja log --lastprints the exact digest most recently served. - Trust scopes —
~/.config/deja/policy.jsoncontrols what memory activates where. Per activation path (search,mcp,auto) you allow or deny origins:local,imported(anything synced from another machine), orimported:<group>for synced sessions whose project, on the machine they came from, sits under that top directory. A rule cannot name a peer: each synced record does carry the sending machine's name, but that is the sender's own claim, which nothing verifies. Example — synced sessions stay searchable but never auto-inject:{"activations":{"auto":{"imported":false}}}.DEJA_AUTORECALL_LOCAL_ONLY=1remains an alias for exactly that rule. Receipts anddeja log --lastname the policy that allowed each injection.deja embedis the one command that sends session text off the machine, and no activation describes that, so it takes the agreement of all three: anything a rule withholds on any path is not embedded, anddeja embedreports how many records stayed.
Full details in the security model.
Found this useful? Star deja-vu on GitHub.