fix(agent-setup, github-app-token): guard against inherited GH_CONFIG_DIR outside AGENT_HOME #2

Open
Flea Flicker wants to merge 1 commits from gb_flea/skills:gandalf/gh-config-dir-isolation into main
First-time contributor

Summary

Fixes a cross-agent token contamination class where an inherited GH_CONFIG_DIR from a prior session or a sibling agent's workspace caused generate-token.sh to write .gh-token into a foreign agent's workspace directory instead of the correct one.

Confirmed live impact: while generating a GitHub App token, a stale inherited GH_CONFIG_DIR pointed to a different agent's workspace (…/ccfa5281…/.github/), silently writing the token there. Pinning GH_CONFIG_DIR to $AGENT_HOME fixed it. These guards prevent recurrence.

Changes

1. agent-setup/scripts/setup.sh — guard before derivation

Insert an early check immediately after the AGENT_HOME validation, before export GH_CONFIG_DIR=... is set:

if [[ -n "${GH_CONFIG_DIR:-}" && "$GH_CONFIG_DIR" != "$AGENT_HOME"* ]]; then
  echo "WARN: Inherited GH_CONFIG_DIR '$GH_CONFIG_DIR' is outside AGENT_HOME. Overriding." >&2
  unset GH_CONFIG_DIR
fi

This ensures a contaminated inherited value is cleared before the script re-derives the correct one.

2. agent-setup/SKILL.md — fix dotfile source path

Change the ## Usage example from source ~/.env to source "$AGENT_HOME/.env" — the script writes to $AGENT_HOME/.env, not ~/.env; ~ is not guaranteed to equal $AGENT_HOME.

3. github-app-token/scripts/generate-token.sh — hard guard + pinned auth

(a) After resolving GH_TOKEN_DIR, add a die() guard that refuses to write when GH_CONFIG_DIR is outside AGENT_HOME:

if [[ -n "${GH_CONFIG_DIR:-}" && -n "${AGENT_HOME:-}" && "$GH_CONFIG_DIR" != "$AGENT_HOME"* ]]; then
  die "GH_CONFIG_DIR '$GH_CONFIG_DIR' is outside AGENT_HOME '${AGENT_HOME}'. Refusing to write token to a foreign workspace."
fi

(b) Pin GH_CONFIG_DIR on the gh auth login invocation so it cannot fall back to any inherited config dir:

GH_CONFIG_DIR="$GH_TOKEN_DIR" gh auth login --with-token < "$GH_TOKEN_FILE"

Verification

  • bash -n agent-setup/scripts/setup.sh
  • bash -n github-app-token/scripts/generate-token.sh
  • Repro: export GH_CONFIG_DIR=/tmp/someone-elses/.github AGENT_HOME=/tmp/me
    • setup.sh — warns and overrides
    • generate-token.sh validation block — die()s with "Refusing to write token to a foreign workspace"
  • With GH_CONFIG_DIR unset and a valid AGENT_HOME, behaviour is unchanged

Related

No secrets in this PR.

Co-Authored-By: Paperclip noreply@paperclip.ing

## Summary Fixes a cross-agent token contamination class where an inherited `GH_CONFIG_DIR` from a prior session or a sibling agent's workspace caused `generate-token.sh` to write `.gh-token` into a **foreign** agent's workspace directory instead of the correct one. **Confirmed live impact:** while generating a GitHub App token, a stale inherited `GH_CONFIG_DIR` pointed to a different agent's workspace (`…/ccfa5281…/.github/`), silently writing the token there. Pinning `GH_CONFIG_DIR` to `$AGENT_HOME` fixed it. These guards prevent recurrence. ## Changes ### 1. `agent-setup/scripts/setup.sh` — guard before derivation Insert an early check immediately after the `AGENT_HOME` validation, before `export GH_CONFIG_DIR=...` is set: ```bash if [[ -n "${GH_CONFIG_DIR:-}" && "$GH_CONFIG_DIR" != "$AGENT_HOME"* ]]; then echo "WARN: Inherited GH_CONFIG_DIR '$GH_CONFIG_DIR' is outside AGENT_HOME. Overriding." >&2 unset GH_CONFIG_DIR fi ``` This ensures a contaminated inherited value is cleared before the script re-derives the correct one. ### 2. `agent-setup/SKILL.md` — fix dotfile source path Change the `## Usage` example from `source ~/.env` to `source "$AGENT_HOME/.env"` — the script writes to `$AGENT_HOME/.env`, not `~/.env`; `~` is not guaranteed to equal `$AGENT_HOME`. ### 3. `github-app-token/scripts/generate-token.sh` — hard guard + pinned auth (a) After resolving `GH_TOKEN_DIR`, add a `die()` guard that refuses to write when `GH_CONFIG_DIR` is outside `AGENT_HOME`: ```bash if [[ -n "${GH_CONFIG_DIR:-}" && -n "${AGENT_HOME:-}" && "$GH_CONFIG_DIR" != "$AGENT_HOME"* ]]; then die "GH_CONFIG_DIR '$GH_CONFIG_DIR' is outside AGENT_HOME '${AGENT_HOME}'. Refusing to write token to a foreign workspace." fi ``` (b) Pin `GH_CONFIG_DIR` on the `gh auth login` invocation so it cannot fall back to any inherited config dir: ```bash GH_CONFIG_DIR="$GH_TOKEN_DIR" gh auth login --with-token < "$GH_TOKEN_FILE" ``` ## Verification - `bash -n agent-setup/scripts/setup.sh` ✅ - `bash -n github-app-token/scripts/generate-token.sh` ✅ - Repro: `export GH_CONFIG_DIR=/tmp/someone-elses/.github AGENT_HOME=/tmp/me` - `setup.sh` — warns and overrides ✅ - `generate-token.sh` validation block — `die()`s with "Refusing to write token to a foreign workspace" ✅ - With `GH_CONFIG_DIR` unset and a valid `AGENT_HOME`, behaviour is unchanged ✅ ## Related - Parent: [PRI-1793](https://paperclip.farhoodlabs.com/PRI/issues/PRI-1793) - Root cause: [PRI-1791](https://paperclip.farhoodlabs.com/PRI/issues/PRI-1791) - This issue: [PRI-1796](https://paperclip.farhoodlabs.com/PRI/issues/PRI-1796) No secrets in this PR. Co-Authored-By: Paperclip <noreply@paperclip.ing>
Flea Flicker added 1 commit 2026-06-16 21:11:02 +00:00
Contamination class: a stale GH_CONFIG_DIR inherited from a prior
session or a different agent's workspace caused generate-token.sh to
write .gh-token into a foreign workspace, silently granting that
agent's gh config access to the wrong token.

Three hardening changes:

1. agent-setup/scripts/setup.sh — before deriving GH_CONFIG_DIR from
   AGENT_HOME, warn and unset any inherited value that points outside
   AGENT_HOME. This prevents the contaminated value from leaking into
   the derived path or the dotfile.

2. agent-setup/SKILL.md — correct the sourcing example from `source ~/.env`
   to `source "$AGENT_HOME/.env"` so the dotfile is sourced from the
   documented location (setup.sh writes to $AGENT_HOME/.env, not ~/
   which may differ).

3. github-app-token/scripts/generate-token.sh — (a) add a hard die()
   guard that refuses to write the token when GH_CONFIG_DIR is outside
   AGENT_HOME; (b) pin GH_CONFIG_DIR="$GH_TOKEN_DIR" on the gh auth
   login invocation so it cannot fall back to any inherited config dir.

Verified:
- bash -n passes on both modified scripts
- With GH_CONFIG_DIR=/tmp/someone-elses/.github AGENT_HOME=/tmp/me,
  setup.sh warns + overrides; generate-token.sh dies before writing.
- With GH_CONFIG_DIR unset and a valid AGENT_HOME, behaviour is
  unchanged (token lands in $AGENT_HOME/.github).

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u https://git.farh.net/gb_flea/skills gandalf/gh-config-dir-isolation:gb_flea-gandalf/gh-config-dir-isolation
git checkout gb_flea-gandalf/gh-config-dir-isolation
Sign in to join this conversation.