Backing up ~/.claude and ~/.codex without archiving your AI logins
If you back up the whole ~/.claude or ~/.codex folder, the restore works, and the backup now holds everything an infostealer wants. The same folder holds your settings, every session transcript in plaintext, and, on Linux, the login itself:
~/.claude/.credentials.json # Claude Code login, mode 0600
~/.codex/auth.json # Codex login when file storage is in use
~/.claude/projects/*/*.jsonl # transcripts: prompts, tool output, file contents
Split the folder into two lists. Back up what you wrote: settings, instructions, skills, hooks, and memory. Keep transcripts as optional encrypted data. Leave login files out of routine backups and log in again after a restore.
Where AI client state lives on macOS and Linux #
I checked these paths against Claude Code 2.1.316, Claude Desktop for Linux 4.4212.0, ChatGPT for macOS 1.2026.183, the Codex desktop app for macOS 26.1027.30824, and Codex source at commit 67f0994. “Documented” means the vendor docs name the path. “Observed” means I found it by inspecting the official build so that it can change in any release.
| Client | State root | Login material | Evidence |
|---|---|---|---|
| Claude Code | ~/.claude/ and ~/.claude.json, both under CLAUDE_CONFIG_DIR if set | Keychain on macOS, or ~/.claude/.credentials.json when the Keychain rejects the write (locked in an SSH session, for example). On Linux, always that file | Documented |
| Claude Desktop | macOS: ~/Library/Application Support/Claude/. Linux (beta): ${XDG_CONFIG_HOME:-~/.config}/Claude/ | Electron cookies and Local Storage, extension secrets encrypted with safeStorage | MCP config documented, rest observed |
| ChatGPT desktop, macOS only | ~/Library/Application Support/com.openai.chat/, ~/Library/Group Containers/2DC432GLL2.group.com.openai.chat/, ~/Library/Preferences/com.openai.chat.plist | Keychain items in OpenAI’s access group | Observed |
| Codex desktop, macOS only | ~/Library/Application Support/Codex/, plus ~/.codex | Shared with Codex CLI | Observed |
| Codex CLI | ${CODEX_HOME:-~/.codex}. CODEX_SQLITE_HOME, sqlite_home and log_dir can move parts of it | auth.json in file mode or as the auto fallback; .credentials.json for MCP OAuth without a keyring | Documented and source |
Desktop sessions that run Claude Code write to ~/.claude/, not to the Electron folder, so include both.
What to back up and what to leave out #
| Treatment | Claude Code | Codex |
|---|---|---|
| Back up, versioned | settings.json, CLAUDE.md, rules/, skills/, commands/, agents/, workflows/, output-styles/, keybindings.json, projects/*/memory/, agent-memory/, plugins/installed_plugins.json as a manifest | config.toml, *.config.toml, hooks.json, rules/, skills/, agent-role files |
| Back up after a secret check | ~/.claude.json (personal MCP servers, trust decisions) | MCP env blocks in config.toml |
| Optional, encrypted, short retention | projects/*/*.jsonl, subagents/, tool-results/, history.jsonl | sessions/YYYY/MM/DD/rollout-*.jsonl, archived_sessions/, history.jsonl |
| Exclude | .credentials.json, file-history/, paste-cache/, debug/, shell-snapshots/, session-env/, backups/ | auth.json, .credentials.json, log/, logs_2.sqlite, shell_snapshots/, packages/, caches |
For Claude Desktop, keep claude_desktop_config.json after checking its MCP env blocks, plus a list of installed extensions and where each came from. Reinstall extensions instead of restoring their executable caches. The ChatGPT app’s local databases are caches of a server-side account; use the account’s data export for conversations you want to keep.
Why copying the whole folder is the wrong default #
Transcripts are plaintext. Anthropic’s docs
say that anything passing through a tool is written to the session .jsonl, so a .env file a tool reads or a token a command prints is in there. Codex rollouts record tool activity the same way.
Your backup also keeps transcripts after the client has deleted them. Claude Code deletes transcripts after cleanupPeriodDays (default 30), but keeps sessions started, or last continued in Claude Desktop or Cowork at any age unless you set desktopSessionCleanupPeriodDays. A backup with a year of history still holds a transcript eleven months after the client deleted it.
A restore can also run code. Hooks, MCP server commands, skills, plugins, desktop extensions, and shell snapshots all execute something. If malware edited them, a full restore puts it back on the clean machine.
The Keychain protects less than it seems to. It stops someone who copies the disk offline, but malware running as your user can still request the item. The Linux desktop build can also fall back to Chromium’s basic password store when no wallet is running.
Dead ends worth skipping #
- Guessing Linux paths from macOS ones. Replacing
Library/Application Supportwith.configworks for Claude Desktop, which has a Linux beta. OpenAI ships no Linux desktop app for ChatGPT or Codex. The Codex source has Linux branches, but there is no supported Linux build. On Linux, your ChatGPT state lives in the browser profile. - Copying only the
.sqlitefiles. Codex keeps state instate_5.sqlite,thread_history_1.sqlite,memories_1.sqliteand others . A live copy without the-waland-shmsidecars can be incomplete or corrupt. Stop the client and copy all three. - Treating the desktop database as the archive. The Codex desktop app can rebuild its index from the rollout JSONL files, but metadata that lives only in the database is lost, back up the JSONL files.
- Assuming
claude purgecleaned everything. It doesn’t touchshell-snapshots/,backups/(older copies of~/.claude.json) or files written by/heapdump. According to Anthropic, a heap snapshot contains the full conversation and any credentials the process held.
Restore into a staging profile #
- Reinstall the signed apps, plugins, and extensions from their sources.
- Restore your config, then read every hook, MCP command, and executable path before the first launch.
- Restore transcripts or memory only if you need them.
- Log in again. Don’t restore
auth.json,.credentials.json, cookies, or Keychain exports. - Resume one session and confirm that it uses the right account and repository.
Verify the backup set #
To list what exists and how large it is, without printing any contents, run this on the machine you back up:
for p in "${CLAUDE_CONFIG_DIR:-$HOME/.claude}" "$HOME/.claude.json" \
"${CODEX_HOME:-$HOME/.codex}" \
"${XDG_CONFIG_HOME:-$HOME/.config}/Claude" \
"$HOME/Library/Application Support/Claude" \
"$HOME/Library/Application Support/Codex" \
"$HOME/Library/Application Support/com.openai.chat" \
"$HOME/Library/Group Containers/2DC432GLL2.group.com.openai.chat"; do
[ -e "$p" ] && du -sh "$p"
done
Then check that no login file ended up in the backup:
find /path/to/mounted/backup \( -name .credentials.json -o -name auth.json \) -print
It should print nothing. If it prints anything, that backup is a credential store: encrypt it, shorten its retention, or rotate the logins.
If malware may already have run #
Don’t treat a restore as the cleanup. From a clean device, revoke your Claude and ChatGPT sessions, then rotate API keys, MCP and connector credentials, and any secret that appeared in a transcript or in tool output. Any backup the malware could reach counts as exposed. Rebuild the user profile, restore only config you have reviewed, and log in again.
Caveats #
Paths and retention rules change between releases. The ChatGPT and desktop paths come from build inspection, not from a published schema, so check them against your installed versions before you write a backup job. Sources: the .claude directory reference
, Claude Code credential management
, Codex config and state locations
, Codex credential storage
, Claude Desktop MCP config paths
, and Electron’s app.getPath()
.
Back up the config you wrote, and leave out the files the app uses for login. Run the find check above against your latest backup tonight.