Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ endif

.PHONY: help build-rust build-macos sign notarize staple dmg release \
clean-macos test compliance-greps verify doctor signing-readiness \
regen-trajectories regen-predictor build-healthbridge
regen-trajectories regen-predictor build-healthbridge rotate-key

help:
@echo "Harlo build targets"
Expand All @@ -58,10 +58,18 @@ help:
@echo " regen-trajectories Regenerate data/trajectories_10k.jsonl (~229 MB, ~minutes)"
@echo " regen-predictor regen-trajectories + train models/cognitive_predictor_v1.joblib"
@echo " clean-macos Remove dist/ and build/"
@echo " rotate-key Rotate ANTHROPIC_API_KEY (paste new key; validates + persists)"

build-rust:
maturin develop --release

# Rotate the daemon's ANTHROPIC_API_KEY: prompts for the new key (hidden, never
# in shell history), validates it against the API, sets the launchctl session
# env + a persistent login agent, bounces the daemon. Never prints the key.
# See docs/key-rotation.md.
rotate-key:
bash scripts/rotate_anthropic_key.sh

build-macos:
ifeq ($(UNAME_S),Darwin)
rm -rf build dist
Expand Down
32 changes: 32 additions & 0 deletions docs/key-rotation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Key rotation — `ANTHROPIC_API_KEY`

Harlo's only cloud credential is `ANTHROPIC_API_KEY` (the daemon reads it from
the environment — `provider/claude.py`). Rotate it whenever it may have been
exposed.

## One command

```bash
make rotate-key # or: bash scripts/rotate_anthropic_key.sh
```

Paste the new key when prompted (input is hidden). The script:

1. **Validates** the key against the Anthropic API *before* changing anything.
2. Sets it for the current login session (`launchctl setenv`).
3. **Persists** it across reboots via a `chmod 600` login agent.
4. Bounces the Harlo daemon so it picks up the new key.

The key is **never** printed, logged, or passed as a shell argument.

## Then, in the Anthropic console

`console.anthropic.com → Settings → API Keys` → **delete the old key**. That is
the step that actually neutralizes the old credential; the script only swaps in
the new one locally.

## Note

The Harlo MCP server (the default coaching surface) uses **no** Claude
credential at all — only the `twin ask` CLI path calls the API. So rotating the
key never disrupts the MCP coaching path.
Loading