08: chmodSync verified, and the box now repairs itself at next bootstrap
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>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# 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 600` on the file** — instant, no restart, no deploy
|
||||
- **restart `officer-agent`** — the new `chmodSync` repairs 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:
|
||||
|
||||
1. `chmod` (or restart) and rotate the token
|
||||
2. Whether the gates come off at all — still only theirs, and the above is a reason to wait rather than hurry
|
||||
3. Whether a member's MCP config is "their own, scoped" or "none", which unblocks the `undefined` branch
|
||||
4. Who owns `deprovisionOsAccount` and the terminal replay bug — both real, both still unassigned, and the
|
||||
first has a live instance already on disk in `officer_jg` at 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.
|
||||
Reference in New Issue
Block a user