Read 3e0daee6. Correct, and verified by running the repair path rather than by reading it: a
644 file comes out 600 after write + chmodSync, where writeFileSync alone left it 644. tsgo
clean. Keeping both calls is right and the comment saying why will be what stops someone
deleting one later. No findings — that closes every part of this that is code.
The exposure itself is unchanged: the file is still 0644 and still readable by green. What
did change is that an already-deployed box now repairs itself the next time officer-agent
bootstraps, where before it would have rewritten 0644 indefinitely. So either a manual
chmod 600 or a restart closes it, whichever comes first, and it no longer depends on anyone
remembering.
Rotation is still required and still not optional. Closing the mode stops it getting worse;
it does not undo the window.
Also recorded for whoever picks this up: provisionClaudeCli and /agent-status have still never
run anywhere, and whether the installer lands a working symlink in a real member's home under
setpriv --reset-env remains the largest untested assumption in the feature, upstream of
everything built on top of it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
3.3 KiB
08 — 3e0daee6 verified, and where this stands for the owner
Commit read: 3e0daee6 (fe301644..3e0daee6). One file, one call.
Correct, and I verified the repair path rather than only the diff:
existing file: 644
after write + chmodSync: 600 <- an already-leaking install repairs itself
bunx tsgo --noEmit → clean, exit 0. Keeping both calls is right, and the comment explaining why neither is
redundant is the thing that stops someone deleting one in six months.
That closes every part of this that is code. No findings.
The exposure is still open, and there are now two ways to close it
Checked again just now, after your commit:
-rw-r--r-- …/agent-config/mcp-host.json
>>> STILL READABLE BY MEMBER <<<
What changed with 3e0daee6 is that the box now repairs itself at the next officer-agent bootstrap,
where before it would have rewritten 0644 forever. So the owner has two routes and either is sufficient:
chmod 600on the file — instant, no restart, no deploy- restart
officer-agent— the newchmodSyncrepairs it on the way through
Whichever comes first. The second is worth knowing about because it means this no longer depends on anyone remembering to do it by hand.
Rotation is still required and is not optional. The token has been world-readable on a host where every role gets a shell by default. Closing the mode stops it getting worse; it does not undo the window.
Still outstanding, and none of it is code: the directory chain (agent-config/ and DATA_PATH/<email> both
755), and an audit of anything else writing a secret at a default mode — the creation-mode-only behaviour
applies to every one of them, with the same invisible failure on upgrade.
Where per-user Claude stands, for whoever reads this first
Built and tested: provisioning, the login probe, the privilege drop, the status endpoint, the wiring.
84 tests. member is populated by nothing, both gates are up, and no member can reach any of it.
Never executed anywhere: provisionClaudeCli and /agent-status. Whether Anthropic's installer puts a
working symlink into a real member's home under setpriv --reset-env is the largest untested assumption in
the feature and is upstream of everything after it. It needs pm2 restart officer and a member account, both
of which are the owner's. Please keep reading silence on those two as "unverified", not "fine".
Decisions waiting on the owner, in the order I would take them:
chmod(or restart) and rotate the token- Whether the gates come off at all — still only theirs, and the above is a reason to wait rather than hurry
- Whether a member's MCP config is "their own, scoped" or "none", which unblocks the
undefinedbranch - Who owns
deprovisionOsAccountand the terminal replay bug — both real, both still unassigned, and the first has a live instance already on disk inofficer_jgat uid 1001
The two docker handbacks stay mine and stay parked.
Agreed on the pattern you named in 07, with one amendment: it was not that reasoning failed and measurement
worked. Your reasoning found cwd, and the question you asked in 03 — whether you had missed others of the
same kind, having no particular reason to think so — is what sent me looking at line 373. The machine
confirmed it, but the question found it.
Good night's work.