Features: sshAgentEnv: omit — the ssh-agent setting is named after what it does (#266)
+38
-4
@@ -1776,8 +1776,9 @@ has its own once-per-daemon guard, so a benign INFO can no longer suppress a ser
|
||||
**`SSH_AUTH_SOCK` is now blocked, and that is a downgrade, not a win.** It was once allowed on
|
||||
purpose, because a worktree's remote was `ssh://git@git.ltms.dev` and a member could not push
|
||||
without the agent socket. Members now push over HTTPS with `WORKER_GITEA_TOKEN`, so the live config
|
||||
sets `sshAuthSock: block`, and `MemberEnvAllowList.derive` drops the name even if an operator lists
|
||||
it under `allow:` — the config cannot re-grant it by accident.
|
||||
sets `sshAgentEnv: omit` (spelled `sshAuthSock: block` before #266; both still parse), and
|
||||
`MemberEnvAllowList.derive` drops the name even if an operator lists it under `allow:` — the config
|
||||
cannot re-grant it by accident.
|
||||
|
||||
Do not read that as the problem being solved. #184 measured a member with the socket blanked pushing
|
||||
**fine anyway**: the forge key is a readable, passphrase-free *file*, and `ssh -G` finds it outside
|
||||
@@ -1800,7 +1801,7 @@ anything that re-exports them afterwards silently undoes it.
|
||||
```yaml
|
||||
memberCredentials:
|
||||
policy: allow-list # default is "deny-by-default"
|
||||
sshAuthSock: block # "allow" only if a member must use the operator's ssh-agent
|
||||
sshAgentEnv: omit # "inherit" only if a member must use the operator's ssh-agent
|
||||
```
|
||||
|
||||
**Why it exists.** A control that lives inside a sourced file can always be undone by a file sourced
|
||||
@@ -3128,7 +3129,7 @@ What each control actually does:
|
||||
|---|---|---|
|
||||
| Environment | `memberCredentials` + the `ZDOTDIR` scrub | **Real**, for what the member *inherits*. It does not protect the values — the member can source the same files again. |
|
||||
| Files | worktree provisioning neutralizes some config files | **Not a boundary.** File modes do not separate processes with the same uid. A member can read the original by absolute path. |
|
||||
| Sockets | `sshAuthSock: block` | **Not a boundary.** It omits one variable. It does not revoke access to the socket, and it cannot remove a readable key file. |
|
||||
| Sockets | `sshAgentEnv: omit` | **Not a boundary.** It omits one variable. It does not revoke access to the socket, and it cannot remove a readable key file. |
|
||||
| Git config | the worktree's HTTPS rewrite + cleared `credential.helper` | **Routing, not enforcement.** Normal git commands go the intended way; a member can still call `ssh` directly. |
|
||||
| Process table | secrets kept out of argv | **No boundary.** argv is visible to any local user, and a different uid would not fix that. |
|
||||
|
||||
@@ -3152,6 +3153,39 @@ grants access to them.
|
||||
|
||||
Open work, ranked, is on #184.
|
||||
|
||||
## The ssh-agent setting is named after what it does — `sshAgentEnv: omit`
|
||||
|
||||
**What.** `memberCredentials.sshAuthSock: block|allow` is now
|
||||
`memberCredentials.sshAgentEnv: omit|inherit`.
|
||||
|
||||
**The knob.** All eight spellings parse, silently, with no deprecation warning:
|
||||
|
||||
```yaml
|
||||
memberCredentials:
|
||||
sshAgentEnv: omit # canonical; "inherit" passes SSH_AUTH_SOCK through
|
||||
# sshAuthSock: block # the old key and old values still work, unchanged
|
||||
```
|
||||
|
||||
Old configs need no edit. If both keys appear, `sshAgentEnv` wins. **An unrecognised value
|
||||
normalises to `omit`**, so a typo fails closed rather than handing a member the agent.
|
||||
|
||||
**Why it exists.** `block` named an effect fleetd does not have. It omits the variable from the
|
||||
member's environment; it does not deny access to the socket. A member runs as the same OS user, so
|
||||
the socket stays reachable and the path is discoverable. An operator scanning a config file reads a
|
||||
value name and stops — that is the point of a good one — so `block` was actively misleading, and the
|
||||
honest explanation sat in a comment most readers never reach.
|
||||
|
||||
What the setting still buys is real and worth keeping: a member does not pick up the operator's
|
||||
agent by default, which removes a whole class of accident. It is an accident-reducer, not a deny.
|
||||
|
||||
**The gotcha: the shim is load-bearing, not cosmetic.** `fleetd.yaml` is gitignored, so no worker
|
||||
can see it and no test in the repo covers it. The live config on this host still says
|
||||
`sshAuthSock: block`. A rename without the read-both shim would have silently dropped the setting at
|
||||
the next restart — trading a naming bug for a real credential regression, in a file the test suite
|
||||
cannot reach. This was verified against the running daemon rather than argued: after redeploy,
|
||||
`GET /member-credentials` still reported `policy: allow-list` with 39 known / 7 allowed / 34 blocked,
|
||||
and a real member spawned on the new jar reported `SSH_AUTH_SOCK: unset`.
|
||||
|
||||
## fleetd states the member trust model at startup
|
||||
|
||||
**What.** Every boot, `fleetd` logs one INFO line saying what kind of boundary members run inside.
|
||||
|
||||
Reference in New Issue
Block a user