claudes runs locally and makes no network requests. It reads:
~/.claude/projects/**/*.jsonl(session transcripts)~/.claude/sessions/*.json(registry of running sessions)- the process table, through
psandkill -0 - on
posture: the Claude Code settings files and~/.claude.json(only themcpServersentries are used)
It writes:
~/.cache/claude-sessions.json(mode0600)~/.cache/claude-sessions-audit.json(mode0600)- a
custom-titlerecord into a transcript onrename ~/.Trash/claude-sessions/onrmandmemory rm~/.claude/CLAUDE.mdonmemory promote, after asking, with the previous version kept asCLAUDE.md.claudes-bak- a project's
memory/MEMORY.mdonmemory rmandmemory promote --move(the line of the removed memory) - Claude Code settings files on
posture --fix, after asking, each with the previous version kept as<file>.claudes-bak
claudes ui listens on 127.0.0.1 only, on a free port unless
--port is given. Every request needs the random token that is
printed at start and changes on every run; a request whose Host
header is not the loopback address is refused, which stops DNS
rebinding. The page has a strict Content Security Policy, loads
nothing from other hosts and only reads: no request changes a
file. Other local users who can read the process list still see
nothing of the token, since it is not on the command line.
resume and review hand over to the claude binary with
exec; from then on Claude Code's own behavior and settings
apply.
The metadata cache holds, per transcript: directory, branch,
timestamps, titles, prompt count, cost, linked pull request
URLs, and the first and last prompt truncated to 500
characters. That is a copy of text that already sits in the
transcripts, but in a second place. If a prompt contained
something sensitive, it is in the cache as well; delete
~/.cache/claude-sessions.json after cleaning up a transcript.
The audit cache never holds a secret. It stores the masked form
(ghp_…dB (40)) and the first 12 hex characters of the value's
SHA-256, used to count distinct secrets across sessions. For
action findings it stores up to 160 characters of the command
around the match.
This is not specific to claudes, but the audit makes it
visible: Claude Code transcripts contain the full output of
every command Claude ran. A cat .env, a docker inspect, or a
failing curl with an auth header puts credentials into a file
in your home directory, and into the conversation that was sent
to the model.
When claudes audit reports a secret:
- Rotate it. A secret in
tool outputorpromptwas part of the model context. - Remove the session with
claudes rm, or edit the transcript if you need to keep the rest of it. - Empty the Trash and delete both caches.
- Check backups that include
~/.claude.
Claude Code deletes transcripts older than cleanupPeriodDays
(setting in ~/.claude/settings.json, default 30). A shorter
period limits how long secrets stay on disk.
Please report security issues privately through GitHub: Security tab of the repository, "Report a vulnerability". Do not open a public issue for them.