Part of the AI coding agent security checklist
Where Claude Code keeps your conversation history
Every Claude Code session is saved on your machine as a plaintext JSONL file, and deleted after 30 days unless you change that. Where the files are, what is in them, how long they stay, and how to remove them.
Checked against the Claude Code documentation and the reports under Sources. Published .
Where the files are
Claude Code stores each session as one file, ~/.claude/projects/<project>/<session-id>.jsonl. <project> is the working directory path with every character that is not a letter or a digit replaced by -, so a session started in /Users/you/work/my-repo is saved under ~/.claude/projects/-Users-you-work-my-repo/.
If the converted name is longer than 200 characters, Claude Code cuts it to 200 and appends a hash of the full path, so it stays within filesystem limits. On Windows, ~/.claude is %USERPROFILE%\.claude.
# projects, most recently used first ls -lt ~/.claude/projects/ | head # sessions in one project, newest first ls -lt ~/.claude/projects/-Users-you-work-my-repo/ | head # the project directory for the folder you are in ls -lt ~/.claude/projects/"$(pwd | sed 's/[^A-Za-z0-9]/-/g')"/ | head # how much is stored du -sh ~/.claude/projects
The third command applies the naming rule above. For a path over 200 characters it will not find the hashed name; list the directory and look instead.
The session file is not the only thing a session leaves behind:
| Path | What it holds | Age limit |
|---|---|---|
projects/<project>/<session-id>.jsonl |
The full conversation: every message, tool call and tool result. | Swept |
projects/<project>/<session-id>/subagents/ |
Transcripts of the subagents that session started. | Swept |
projects/<project>/<session-id>/tool-results/ |
Large tool outputs, spilled to separate files. | Swept |
file-history/<session-id>/ |
Copies of files taken before Claude edited them, used to rewind to a checkpoint. | Swept |
paste-cache/ |
The contents of large pastes. | Swept |
history.jsonl |
Every prompt you have typed, with its time and project path. Used for up-arrow recall and Ctrl+R search. | Kept |
/tmp/claude/response.md |
What /copy wrote on Claude Code 2.1.59 to 2.1.127: one fixed path for every user on the machine, readable by all of them. | Kept |
Paths that do not start with / are under ~/.claude/. If you set CLAUDE_CONFIG_DIR, all of it lives under that directory instead: with CLAUDE_CONFIG_DIR=~/.claude-work, transcripts are in ~/.claude-work/projects/. In current versions, pasted images and each session's scratchpad are not here at all. They sit under Claude Code's temp directory, such as /private/tmp/claude-<uid>/ on macOS.
Older builds left one more file outside both. On 2.1.59 to 2.1.127, /copy wrote the response to /tmp/claude/response.md, readable by everyone (0644) in a directory anyone could enter (0755). Another local user could read what you copied, secrets included, or plant a symlink there so that your next /copy overwrote a file of their choosing (CVE-2026-46406). 2.1.128 fixed it. Check for a copy an old build left:
claude --version # 2.1.128 or later ls -la /tmp/claude/ # owner, mode, and whether response.md is a symlink rm /tmp/claude/response.md # once you have looked
If response.md is a symlink, or /tmp/claude/ belongs to another user, someone set up the overwrite the advisory describes. Note where the link points before you remove it.
What is in them
Everything the session saw. The contents of every file Claude read, the output of every command it ran, and the text you pasted. If the agent ran cat .env, the values are in the transcript.
None of it is encrypted. Claude Code's documentation says transcripts and history are not encrypted at rest and that OS file permissions are the only protection. Anything that can read your home directory can read them, including whatever backs it up or syncs it. On a shared machine, check its permissions with ls -ld ~/.claude; chmod 700 ~/.claude keeps other users out. To keep secrets out of the transcript in the first place, see how to stop Claude Code reading your .env file.
# a readable copy of an older session: resume it, then export claude --resume <session-id> /export session.txt # which files mention a value you are worried about grep -rlsF 'first-8-chars' ~/.claude/projects ~/.claude/history.jsonl \ ~/.claude/file-history ~/.claude/paste-cache
Search for the first few characters of a key, not the whole value, or the full secret ends up in your shell history as well. The recursive search covers subagent transcripts, tool-result files, edit snapshots and large pastes too.
Every tool call is in there with its arguments, so you can also read the transcripts back as an audit log of what the agent ran.
What malware looks for
File permissions keep other users out. They do not stop a program running as you. On 8 September 2026, Gen Digital reported that commodity infostealers now collect AI coding tools' local data: access and refresh tokens, credentials in MCP configs, prompt histories and conversation databases. It names Claude among the targets of the Remus and CallbackBeaver families, and shows an STG Stealer configuration that collects ~/.claude/.credentials.json and ~/.claude.json: the file Claude Code keeps its login in when it cannot use the macOS Keychain, and its config. The report says the data sits in predictable places, some of it in plaintext. ~/.claude/projects fits that description. Retention is a security setting as well as an audit one: what a stealer cannot find, it cannot take.
After an infection, rotate from a clean device: every credential the transcripts held, the keys in your MCP configs, and your AI services' sessions and API keys, not only browser passwords. ranwhat clean lists what the transcripts held, and rotate in its review session groups it by provider.
How long Claude Code keeps them
30 days by default. The cleanupPeriodDays setting changes it: a whole number of days, minimum 1. Claude Code deletes anything older in a background sweep after a session starts, without a message, so an old session simply stops appearing in /resume.
{
"cleanupPeriodDays": 90
}To stop the files being written at all, set CLAUDE_CODE_SKIP_PROMPT_HISTORY=1. Sessions started with it write no transcript and no prompt history, and do not appear in --resume, --continue or up-arrow history. For a single claude -p run, --no-session-persistence skips the transcript.
CLAUDE_CODE_SKIP_PROMPT_HISTORY=1 claude claude -p --no-session-persistence "run the tests and list the failures"
How to delete them
claude project purge removes what Claude Code holds for one project. It prints the full plan first and asks before deleting anything. Start with a dry run.
claude project purge ~/work/my-repo --dry-run the plan, nothing deleted claude project purge ~/work/my-repo the plan, then one y/N prompt claude project purge ~/work/my-repo --yes no prompt, for scripts claude project purge ~/work/my-repo -i step through item by item claude project purge --all every project
Leave out the path to pick a project from a list. A path with no stored state is an error, with exit status 1.
You can also delete the files by hand. The main pieces of one session are its transcript, its directory of subagent and tool-result files, and its edit snapshots. Its prompts stay in history.jsonl, which purge filters for you.
rm ~/.claude/projects/-Users-you-work-my-repo/<session-id>.jsonl rm -r ~/.claude/projects/-Users-you-work-my-repo/<session-id>/ rm -r ~/.claude/file-history/<session-id>/
Do not delete these
~/.claude.json, ~/.claude/settings.json and ~/.claude/plugins/ hold your auth, preferences and installed plugins. ~/.claude/.credentials.json, where it exists, holds your login. And claude rm <id> is not a deletion of history: it removes a background session, but its transcript stays on disk and claude --resume can still open it.
Before you delete: see what is in them
Deleting a transcript removes your local copy of a secret. It does not un-send it. The value already went to the model as part of the conversation, and what the provider retains is set by your account's terms, not by the files on your disk. So the first job is a list of what to rotate.
For Anthropic accounts, the data usage page gives the retention: 30 days as standard for Team, Enterprise and API accounts, and 30 days or 5 years for Free, Pro and Max, depending on whether you allow your data to be used for model improvement.
check reads the transcripts and changes nothing. It lists the risky actions the agent took, found by the same rules as ranwhat watch, and the credentials sitting in the files, as ranwhat clean finds them, each with the project it was found in. Rotate those. Then either purge the project, or keep the history and mask the values:
ranwhat clean report, then a review session: mask 3, keep 3, rotate ranwhat clean --apply mask every value found, backups first
--apply replaces each value in place with <ranwhat:redacted:…>. It copies each file it changes to ~/.ranwhat/backups first, and parses the rewritten file back before it replaces the original. The backup holds the original values, so delete it once you have checked the result.
To stop the values reaching a transcript in the first place, see Claude Code and .env secrets.
Sources
Every statement about Claude Code on this page comes from its official documentation or Anthropic's security advisory, and the malware findings from Gen Digital's report. Every statement about ranwhat comes from its source.
- Manage sessionstranscript location, naming, /export, claude rm
- Explore the .claude directorywhat is swept, what is kept, plaintext storage, purge
- Settings referencecleanupPeriodDays, desktopSessionCleanupPeriodDays
- Environment variablesCLAUDE_CONFIG_DIR, CLAUDE_CODE_SKIP_PROMPT_HISTORY
- Data usagewhat Anthropic retains, and for how long
- AuthenticationKeychain and .credentials.json
- MCPMCP server configs in ~/.claude.json
- GHSA-4vp2-6q8c-pvq2CVE-2026-46406, /copy, fixed in 2.1.128
- Gen Digital: infostealers and your AI agent8 September 2026
- ranwhat sourcewatch.py and clean.py: what is read, and how masking works