fix(fleet): propagate roster git identity (#1043)

This commit is contained in:
2026-08-07 01:46:03 -05:00
committed by coder-mos1
parent aa0a7b5fa2
commit ebf518215a
17 changed files with 258 additions and 22 deletions
@@ -71,6 +71,7 @@ write_generated() {
chmod 600 "$home/fleet/run/holder-owner"
cat > "$home/fleet/agents/$agent.env.generated" <<EOF
MOSAIC_AGENT_NAME=$agent
MOSAIC_GIT_IDENTITY=$agent
MOSAIC_AGENT_CLASS=code
MOSAIC_AGENT_RUNTIME=pi
MOSAIC_AGENT_MODEL=openai-codex/gpt-5.6-sol
@@ -114,6 +115,42 @@ fi
echo "$valid_args" | grep -qxF '/usr/bin/env' || fail "pane does not use absolute env"
echo "$valid_args" | grep -qxF -- '-i' || fail "pane environment is not cleared"
# Git identity is generated authority, not an optional or independently mutable
# local value. Each invalid form must fail before fake tmux receives a call.
assert_git_identity_rejected() {
local case_name="$1"
local expected_code="$2"
local home="$ROOT/git-identity-$case_name"
local agent="coder-git-identity-$case_name"
local generated="$home/fleet/agents/$agent.env.generated"
write_generated "$home" "$agent"
case "$case_name" in
missing) grep -v '^MOSAIC_GIT_IDENTITY=' "$generated" > "$generated.next" && mv "$generated.next" "$generated" ;;
unsafe) perl -0pi -e 's/^MOSAIC_GIT_IDENTITY=.*$/MOSAIC_GIT_IDENTITY=bad\/identity/m' "$generated" ;;
mismatch) perl -0pi -e 's/^MOSAIC_GIT_IDENTITY=.*$/MOSAIC_GIT_IDENTITY=other-agent/m' "$generated" ;;
local-shadow)
printf 'MOSAIC_GIT_IDENTITY=%s\n' "$agent" > "$home/fleet/agents/$agent.env.local"
chmod 600 "$home/fleet/agents/$agent.env.local"
;;
*) fail "unknown Git identity rejection case: $case_name" ;;
esac
chmod 600 "$generated"
: > "$TMUX_CALLS"
if output=$(run_start "$home" "$agent" 2>&1); then
fail "Git identity case $case_name was accepted"
fi
[ ! -s "$TMUX_CALLS" ] || fail "tmux ran before Git identity $case_name rejection"
echo "$output" | grep -qF "code=$expected_code" || \
fail "Git identity $case_name diagnostic omitted code $expected_code"
}
assert_git_identity_rejected missing missing-key
assert_git_identity_rejected unsafe unsafe-git-identity
assert_git_identity_rejected mismatch git-identity-mismatch
assert_git_identity_rejected local-shadow generated-key-shadow
# The generated-file parent is a security boundary too: even a private regular
# file is untrusted if its parent can be replaced or written by another user.
# Validation must happen before fake tmux receives even a has-session call.
@@ -274,6 +311,18 @@ after_pane_env=$(printf '%s\n' "$pane_args" | grep -n -m1 -F '/usr/bin/env' | cu
printf '%s\n' "$pane_args" | tail -n +"$after_pane_env" | grep -qxF -- '-i' || \
fail "pane command did not clear its environment"
pane_environment=$(tr '\0' '\n' < "$HOME_PANE_BOUNDARY/fleet/pane-environment")
# Exercise the repository launcher at $START, not the independently installed
# host copy. Set-compare every declared generated projection entry with the
# launched process environment so a newly declared identity cannot be omitted
# by a hand-maintained per-variable assertion.
declared_generated_environment=$(sort "$HOME_PANE_BOUNDARY/fleet/agents/coder-pane-boundary.env.generated")
missing_or_changed_generated_environment=$(comm -23 \
<(printf '%s\n' "$declared_generated_environment") \
<(printf '%s\n' "$pane_environment" | sort))
if [ -n "$missing_or_changed_generated_environment" ]; then
missing_or_changed_keys=$(printf '%s\n' "$missing_or_changed_generated_environment" | cut -d= -f1 | paste -sd, -)
fail "runtime pane omitted or changed generated environment keys: $missing_or_changed_keys"
fi
echo "$pane_environment" | grep -qxF "HOME=$PANE_TRUSTED_HOME" || \
fail "runtime pane did not receive trusted HOME"
echo "$pane_environment" | grep -qF "$PANE_STALE_PATH" && fail "runtime pane received stale PATH"
@@ -290,6 +339,7 @@ write_interaction_generated() {
chmod 600 "$home/fleet/run/holder-owner"
cat > "$home/fleet/agents/$agent.env.generated" <<EOF
MOSAIC_AGENT_NAME=$agent
MOSAIC_GIT_IDENTITY=$agent
MOSAIC_AGENT_CLASS=operator-interaction
MOSAIC_AGENT_RUNTIME=pi
MOSAIC_AGENT_MODEL=openai/gpt-5.6-sol