From 98376fd8468f2281ecfa6096985f3c2c4f6ecc20 Mon Sep 17 00:00:00 2001 From: atlas Date: Fri, 11 Sep 2026 12:49:16 +0200 Subject: [PATCH] docs/security: the claude dir is 0755 by design, not 0700 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit security.md's "What's NOT exposed" list said `/home//.claude/` is mode `0700`. Measured from inside an agent container — the vantage the claim is about, since the nixbld users in this threat model run there — it is `0755`. `ensure_claude_dir` (hive-c0re/src/lifecycle/setup.rs) chmods it to 0755 deliberately, and its comment says why: hive-core is a different user and needs read+execute to list the directory so `claude_has_session` can detect a valid session. So the code is right and the doc named a mechanism that was never the real one. The conclusion the doc drew still holds — nixbld users can't read anything that matters. Every sensitive entry is protected on its own: `.credentials.json`, `history.jsonl` and `settings.json` at 0600, `projects/` and `sessions/` at 0700, and the five `backups/*.backup.*` at 0600. 32 nixbld users exist on this host (uid 30001+) and none of them can read any of it. What changes is the invariant a reader should rely on. The directory mode was the doc's whole stated guarantee and it isn't there; the protection is per-file, which fails differently — anything landing in `.claude/` at a default mode is world-readable while the doc says it cannot be. `plugins/` (596 files, 0755) and `.last-cleanup` (0644) already demonstrate that files do land loose there. Both are harmless; the point is that nothing stops the next one from being. Closes #4204. --- docs/trust-boundary/security.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/trust-boundary/security.md b/docs/trust-boundary/security.md index c82010a6..c65c7b72 100644 --- a/docs/trust-boundary/security.md +++ b/docs/trust-boundary/security.md @@ -185,8 +185,15 @@ token policy bounds file reads; network isolation bounds network reach. **What's NOT exposed**: -- `/home//.claude/` — mode `0700`, owned by the per-agent - user ``. nixbld users can't read it. +- `/home//.claude/` — `.credentials.json`, `history.jsonl` and + `settings.json` are `0600`; `projects/` and `sessions/` are `0700`. All owned + by the per-agent user ``, so nixbld users can't read any of them. + ⚠️ The **directory itself is `0755`**, on purpose: `hive-core` is a different + user and needs read+execute to list it so `claude_has_session` can detect a + valid session (`ensure_claude_dir`, `hive-c0re/src/lifecycle/setup.rs`). + The per-file mode is therefore the whole protection here — anything added to + this directory at a default mode is world-readable, which isn't + hypothetical: `plugins/` and `.last-cleanup` already are. - `$HYPERHIVE_STATE_DIR/forge-token` (= `/agents//state/forge-token`) — written at mode `0600` and chowned to the per-agent uid:gid (see `hive-c0re/src/forge/mod.rs`'s module doc for exactly where). nixbld users