diff --git a/fleetd/src/main/java/dev/ltms/fleet/session/GitWorktrees.java b/fleetd/src/main/java/dev/ltms/fleet/session/GitWorktrees.java index 571dda0..5bca4cf 100644 --- a/fleetd/src/main/java/dev/ltms/fleet/session/GitWorktrees.java +++ b/fleetd/src/main/java/dev/ltms/fleet/session/GitWorktrees.java @@ -190,17 +190,25 @@ public final class GitWorktrees implements Worktrees { /** * {@link #configureEnvironmentCredentialHelper} only ever fires for an HTTPS origin — Git never * consults a {@code credential.helper} for an SSH transport. This repo's own origin is - * {@code ssh://git@git.ltms.dev:2224/fleet/fleetd.git}, and once {@code memberCredentials.policy: - * allow-list} blocks {@code SSH_AUTH_SOCK} (fleetd #157), a member sitting on an SSH origin has no - * way to authenticate at all — there is no private key file on this host, only an ssh-agent socket. + * {@code ssh://git@git.ltms.dev:2224/fleet/fleetd.git}, so a member sitting on that origin never + * reaches the helper and the repo-scoped {@code WORKER_GITEA_TOKEN} is simply not used. + * + *

An earlier version of this javadoc justified the rewrite by claiming a member cannot + * push once {@code memberCredentials.policy: allow-list} blocks {@code SSH_AUTH_SOCK}, because + * "there is no private key file on this host, only an ssh-agent socket". That premise is false + * (fleetd #184): {@code ssh -G} resolves a readable, passphrase-free {@code IdentityFile} outside + * {@code ~/.ssh}, and a member — same OS user — pushes over SSH with the socket blanked. The + * rewrite is still worth having, but for the reason below rather than that one: it routes the + * member through its own scoped token instead of the operator's ssh identity, which is what makes + * a member's pushes attributable and revocable. * *

The fix is a worktree-scoped URL rewrite: {@code url..insteadOf * }, set with {@code --worktree} so it lands only in * {@code /.git/worktrees//config.worktree} (enabled by * {@code extensions.worktreeConfig}, already turned on above) and never touches the shared * repo-level config the primary checkout also reads. {@code insteadOf} — not - * {@code pushInsteadOf} — because a member may also need to fetch or rebase, and a fetch over SSH - * fails for the exact same missing-agent reason a push would. + * {@code pushInsteadOf} — because a member may also need to fetch or rebase, and both should go + * through the member's own token for the same reason. * *

The host (and, for the rewrite's SSH-side match, the port) come from parsing the origin * itself — never a hardcoded forge host, which is exactly what #177 removed. An origin that is