Skip to main content

E1004 -- API key found in shell history

Severity: WARN. Rotate the key + scrub the history entry.

What happened

controlzero doctor found a Control Zero API key inside one of your shell history files (~/.bash_history, ~/.zsh_history, or ~/.history). Most often this happens when someone pastes a key into a one-off command:

export CONTROLZERO_API_KEY=cz_live_abcd1234...
controlzero install claude-code --api-key=cz_live_abcd1234...

Either of those commands lands the full key in your history file as soon as you press Enter.

Why it matters

Shell history files are:

  • On disk, owned by your user, but often readable to any process running as the same user (extensions, language servers, MCP servers).
  • Backed up by macOS Time Machine, iCloud Drive, Dropbox, or any synced home-directory tool that does not exclude .history.
  • Sometimes shared via dotfile repos that get pushed to GitHub.
  • Cached in tmux scrollback and screen-sharing recordings.

A leaked key in history is harder to clean than a leak in a settings file because rewriting the history file is per-shell-syntax and shell-process-aware.

How to fix

Step 1: rotate the key

Open the dashboard, revoke the leaked key, and create a new one. Until you do this, scrubbing the local history file is not enough, because the key may already be in a backup or sync target.

Step 2: scrub the history entry

In the same shell session that holds the entry:

# Show the line numbers
history | grep -n cz_live_

# Delete the offending line by number (e.g. 423)
history -d 423

# Persist the change
history -w # bash
fc -W # zsh

For multiple matching lines, repeat history -d for each. If your shell already wrote the entry to disk in a previous session, you may also need to edit ~/.bash_history or ~/.zsh_history directly with your editor.

Step 3: prevent recurrence

Two lighter-weight habits prevent this:

  1. Use controlzero install <agent> --api-key=... once, then put the key into ~/.controlzero/config.yaml (mode 0600) and never type it on a command line again. The SDK reads the config file by default; no env var needed.
  2. Prefix sensitive commands with a leading space in zsh / bash when you do need to type a key. With HISTCONTROL=ignorespace set, leading-space commands are not recorded.
  • E1001 -- API key found in agent settings file
  • E1002 -- ~/.controlzero directory is world-readable
  • E1003 -- config.yaml is world-readable