#213: fix ZDOTDIR credential scrub gate + directory under memberHerdrSocket
The memberCredentials.policy: allow-list ZDOTDIR scrub decided zsh-vs-not using fleetd's own process $SHELL and wrote the generated scrub dir into fleetd's own java.io.tmpdir. Under memberHerdrSocket: (member panes run as a different OS user than fleetd's own process) this silently protects nothing: the wrong shell decides the gate, and the directory can be unreachable to the member. - New FleetConfig.memberLoginShell: the member OS user's login shell, only ever read when memberHerdrSocket: is configured; fleetd's own $SHELL keeps deciding everything when memberHerdrSocket: is absent (byte-identical to before). - HerdrPeerLauncher.applyEnvironmentAllowListPolicy: memberHerdrSocket + memberLoginShell not configured/non-zsh falls back to the CB-596 sentinel overlay (warn loudly, never refuse to spawn). memberHerdrSocket + zsh memberLoginShell generates the ZDOTDIR under the configured worktreeRoot instead of java.io.tmpdir, shared with the existing worktreeGroup (reused, not a new key). - EnvAllowListScrub: new generate(parentDir, allowedNames, group) overload shares the generated directory via pure-Java POSIX group ownership (rwxr-x--- dir, rw-r----- files) — no external process spawn. - fleetd.example.yaml documents memberLoginShell: and worktreeGroup:'s reuse for the scrub directory (the live fleetd.yaml is gitignored). 4 new tests in HerdrPeerLauncherAllowListWiringTest cover the acceptance criteria; 3 of the 4 were watched failing against the pre-fix code.
This commit is contained in:
@@ -117,6 +117,15 @@ herdrSocket: ~/.config/herdr/herdr.sock
|
||||
# Optional socket for member panes. Omit this to use herdrSocket for both leads and members.
|
||||
# memberHerdrSocket: /Users/member/.config/herdr/herdr.sock
|
||||
|
||||
# fleetd #213: the login shell the member OS user (memberHerdrSocket above) actually runs. ONLY
|
||||
# read when memberHerdrSocket is set — fleetd's own $SHELL says nothing about a pane running
|
||||
# under a different OS user, and there is no channel to ask herdr for that user's shell, so this
|
||||
# must be told rather than guessed. Absent, blank, or anything not ending in "zsh" is treated the
|
||||
# same as "not zsh": the memberCredentials.policy: allow-list ZDOTDIR scrub (see worktreeGroup
|
||||
# below) is skipped in favour of the weaker CB-596 sentinel overlay — a degraded control, never a
|
||||
# refusal to spawn. When memberHerdrSocket is absent this key is never consulted at all.
|
||||
# memberLoginShell: /bin/zsh
|
||||
|
||||
# How member sessions are spawned. Define one or more named profiles (backends) under
|
||||
# `profiles`; each key is the profile name (also the ccs profile). A profile says only WHICH
|
||||
# BACKEND — model, CLI adapter, credentials, cost. It says nothing about what a member spawned on
|
||||
@@ -643,6 +652,13 @@ guard:
|
||||
# CAUTION: this isolates credentials, not the repository — a member in the group can still
|
||||
# write the operator's git objects and refs in the shared repo. The operator running fleetd
|
||||
# must already be a member of the named group, or every provisioning spawn fails loudly.
|
||||
#
|
||||
# fleetd #213: this is also the ONE group the memberCredentials.policy: allow-list ZDOTDIR scrub
|
||||
# reuses when memberHerdrSocket is set — deliberately not a second config key. Under
|
||||
# memberHerdrSocket, the scrub directory is generated under worktreeRoot (never java.io.tmpdir,
|
||||
# which the member OS user cannot reach) and shared read-only with this group. If worktreeGroup
|
||||
# is unset while memberHerdrSocket is set, the scrub cannot be guaranteed reachable by the member,
|
||||
# so fleetd falls back to the weaker CB-596 sentinel overlay instead (a WARN names the gap).
|
||||
# worktreeGroup: fleet-workers
|
||||
|
||||
# Session lifecycle limits (CB-303). All knobs are opt-in; omit or set to null to keep
|
||||
|
||||
Reference in New Issue
Block a user