fix(#1970): bake token path into gh/git wrappers — env var didn't reach claude's bash-tool context
This commit is contained in:
parent
5c2cae41a2
commit
46007008a9
2 changed files with 21 additions and 23 deletions
|
|
@ -45,12 +45,13 @@ When enabled, the container gets:
|
||||||
`x-access-token` + the PAT (GitHub ignores the username for PAT auth).
|
`x-access-token` + the PAT (GitHub ignores the username for PAT auth).
|
||||||
Host-scoped, so it never touches the forge (`localhost:3000`) or any
|
Host-scoped, so it never touches the forge (`localhost:3000`) or any
|
||||||
other remote.
|
other remote.
|
||||||
- **Env**: `HIVE_GITHUB_TOKEN_FILE` (the token path — never the secret).
|
|
||||||
|
|
||||||
Both the wrapper and the credential helper read the token from the file
|
Both scripts read the token from `<state>/github-token` **at invocation
|
||||||
**at invocation time**, so a PAT written (or rotated) mid-session takes
|
time**, so a PAT written (or rotated) mid-session takes effect immediately
|
||||||
effect immediately — no container rebuild or restart. Until the file
|
— no container rebuild or restart. Until the file exists, `gh` / `git push`
|
||||||
exists, `gh` / `git push` simply fail unauthenticated.
|
simply fail unauthenticated. The token path is baked into the scripts at
|
||||||
|
build time (not read from an env var), because claude's Bash tool runs in a
|
||||||
|
minimal environment that wouldn't carry one.
|
||||||
|
|
||||||
## Provisioning
|
## Provisioning
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,17 @@ let
|
||||||
userName = config.hyperhive.user.name;
|
userName = config.hyperhive.user.name;
|
||||||
homeDir = "/home/${userName}";
|
homeDir = "/home/${userName}";
|
||||||
# GitHub integration (hyperhive.github.enable): a `gh` wrapper + a git
|
# GitHub integration (hyperhive.github.enable): a `gh` wrapper + a git
|
||||||
# credential helper, both sourcing the PAT from HIVE_GITHUB_TOKEN_FILE at
|
# credential helper, both reading the PAT from the agent's `github-token`
|
||||||
# invocation time so a dashboard-pasted token takes effect with no rebuild.
|
# state file at invocation, so a dashboard-pasted token takes effect with no
|
||||||
# The scripts are static (they read env at runtime) — the enable flag only
|
# rebuild. The token PATH is baked in at build time (nix knows `userName`) —
|
||||||
# gates whether they're installed + the env is set, so the token value never
|
# NOT read from `$HIVE_GITHUB_TOKEN_FILE`, because claude's Bash tool runs
|
||||||
# enters the nix store. github.com only; git auths as `x-access-token` + PAT.
|
# `bash -c` in a minimal env that doesn't source `/etc/set-environment`, so
|
||||||
|
# the env var isn't present where `gh`/`git` actually run. The token value
|
||||||
|
# never enters the nix store (only its path). github.com only; git auths as
|
||||||
|
# `x-access-token` + PAT.
|
||||||
ghWrapper = pkgs.writeShellScriptBin "gh" ''
|
ghWrapper = pkgs.writeShellScriptBin "gh" ''
|
||||||
if [ -n "''${HIVE_GITHUB_TOKEN_FILE:-}" ] && [ -r "''${HIVE_GITHUB_TOKEN_FILE}" ]; then
|
if [ -r "/agents/${userName}/state/github-token" ]; then
|
||||||
GH_TOKEN="$(cat "''${HIVE_GITHUB_TOKEN_FILE}")"
|
GH_TOKEN="$(cat "/agents/${userName}/state/github-token")"
|
||||||
export GH_TOKEN
|
export GH_TOKEN
|
||||||
fi
|
fi
|
||||||
exec ${pkgs.gh}/bin/gh "$@"
|
exec ${pkgs.gh}/bin/gh "$@"
|
||||||
|
|
@ -33,11 +36,11 @@ let
|
||||||
gitCredHelper = pkgs.writeShellScriptBin "git-credential-hive-github" ''
|
gitCredHelper = pkgs.writeShellScriptBin "git-credential-hive-github" ''
|
||||||
# git credential-helper protocol: only the `get` action needs an answer.
|
# git credential-helper protocol: only the `get` action needs an answer.
|
||||||
[ "''${1:-}" = "get" ] || exit 0
|
[ "''${1:-}" = "get" ] || exit 0
|
||||||
if [ -n "''${HIVE_GITHUB_TOKEN_FILE:-}" ] && [ -r "''${HIVE_GITHUB_TOKEN_FILE}" ]; then
|
if [ -r "/agents/${userName}/state/github-token" ]; then
|
||||||
# GitHub ignores the username for PAT auth — `x-access-token` is the
|
# GitHub ignores the username for PAT auth — `x-access-token` is the
|
||||||
# conventional placeholder; the PAT is the password.
|
# conventional placeholder; the PAT is the password.
|
||||||
printf 'username=x-access-token\n'
|
printf 'username=x-access-token\n'
|
||||||
printf 'password=%s\n' "$(cat "''${HIVE_GITHUB_TOKEN_FILE}")"
|
printf 'password=%s\n' "$(cat "/agents/${userName}/state/github-token")"
|
||||||
fi
|
fi
|
||||||
'';
|
'';
|
||||||
# Hive-wide OpenTelemetry config (host-driven; baked in per-agent by
|
# Hive-wide OpenTelemetry config (host-driven; baked in per-agent by
|
||||||
|
|
@ -1536,12 +1539,6 @@ in
|
||||||
# regardless of which profile files are sourced.
|
# regardless of which profile files are sourced.
|
||||||
NIX_REMOTE = "daemon";
|
NIX_REMOTE = "daemon";
|
||||||
}
|
}
|
||||||
// lib.optionalAttrs config.hyperhive.github.enable {
|
|
||||||
# GitHub integration: point the gh wrapper + git credential helper at the
|
|
||||||
# agent's PAT file (written by the credentials tab / `hivectl github
|
|
||||||
# set-token`). Only the path — never the secret (see hyperhive.github.enable).
|
|
||||||
HIVE_GITHUB_TOKEN_FILE = "/agents/${userName}/state/github-token";
|
|
||||||
}
|
|
||||||
// lib.optionalAttrs (!config.hyperhive.autoCompact) {
|
// lib.optionalAttrs (!config.hyperhive.autoCompact) {
|
||||||
# Zero watermark disables proactive compaction; the reactive path
|
# Zero watermark disables proactive compaction; the reactive path
|
||||||
# (compact-on-overflow) still fires when the session is truly full.
|
# (compact-on-overflow) still fires when the session is truly full.
|
||||||
|
|
@ -1670,9 +1667,9 @@ in
|
||||||
# Wire the GitHub credential helper for `git push` over HTTPS. Host-scoped
|
# Wire the GitHub credential helper for `git push` over HTTPS. Host-scoped
|
||||||
# to `https://github.com`, so it never touches the forge (localhost:3000)
|
# to `https://github.com`, so it never touches the forge (localhost:3000)
|
||||||
# or any other remote. Gated on hyperhive.github.enable; the helper reads
|
# or any other remote. Gated on hyperhive.github.enable; the helper reads
|
||||||
# the PAT from HIVE_GITHUB_TOKEN_FILE at invocation and auths as
|
# the PAT from the agent's `github-token` state file at invocation and auths
|
||||||
# `x-access-token` + the PAT. System /etc/gitconfig merges under the agent's
|
# as `x-access-token` + the PAT. System /etc/gitconfig merges under the
|
||||||
# ~/.gitconfig (safe.directory), so this is additive.
|
# agent's ~/.gitconfig (safe.directory), so this is additive.
|
||||||
# Nested-path binding + mkIf (matching the other `environment.etc."…"`
|
# Nested-path binding + mkIf (matching the other `environment.etc."…"`
|
||||||
# entries above) — a whole-set `environment.etc = {…}` here would collide
|
# entries above) — a whole-set `environment.etc = {…}` here would collide
|
||||||
# with them at the nix level ("attribute already defined").
|
# with them at the nix level ("attribute already defined").
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue