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).
|
||||
Host-scoped, so it never touches the forge (`localhost:3000`) or any
|
||||
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
|
||||
**at invocation time**, so a PAT written (or rotated) mid-session takes
|
||||
effect immediately — no container rebuild or restart. Until the file
|
||||
exists, `gh` / `git push` simply fail unauthenticated.
|
||||
Both scripts read the token from `<state>/github-token` **at invocation
|
||||
time**, so a PAT written (or rotated) mid-session takes effect immediately
|
||||
— no container rebuild or restart. Until the file exists, `gh` / `git push`
|
||||
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
|
||||
|
||||
|
|
|
|||
|
|
@ -18,14 +18,17 @@ let
|
|||
userName = config.hyperhive.user.name;
|
||||
homeDir = "/home/${userName}";
|
||||
# GitHub integration (hyperhive.github.enable): a `gh` wrapper + a git
|
||||
# credential helper, both sourcing the PAT from HIVE_GITHUB_TOKEN_FILE at
|
||||
# invocation time so a dashboard-pasted token takes effect with no rebuild.
|
||||
# The scripts are static (they read env at runtime) — the enable flag only
|
||||
# gates whether they're installed + the env is set, so the token value never
|
||||
# enters the nix store. github.com only; git auths as `x-access-token` + PAT.
|
||||
# credential helper, both reading the PAT from the agent's `github-token`
|
||||
# state file at invocation, so a dashboard-pasted token takes effect with no
|
||||
# rebuild. The token PATH is baked in at build time (nix knows `userName`) —
|
||||
# NOT read from `$HIVE_GITHUB_TOKEN_FILE`, because claude's Bash tool runs
|
||||
# `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" ''
|
||||
if [ -n "''${HIVE_GITHUB_TOKEN_FILE:-}" ] && [ -r "''${HIVE_GITHUB_TOKEN_FILE}" ]; then
|
||||
GH_TOKEN="$(cat "''${HIVE_GITHUB_TOKEN_FILE}")"
|
||||
if [ -r "/agents/${userName}/state/github-token" ]; then
|
||||
GH_TOKEN="$(cat "/agents/${userName}/state/github-token")"
|
||||
export GH_TOKEN
|
||||
fi
|
||||
exec ${pkgs.gh}/bin/gh "$@"
|
||||
|
|
@ -33,11 +36,11 @@ let
|
|||
gitCredHelper = pkgs.writeShellScriptBin "git-credential-hive-github" ''
|
||||
# git credential-helper protocol: only the `get` action needs an answer.
|
||||
[ "''${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
|
||||
# conventional placeholder; the PAT is the password.
|
||||
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
|
||||
'';
|
||||
# Hive-wide OpenTelemetry config (host-driven; baked in per-agent by
|
||||
|
|
@ -1536,12 +1539,6 @@ in
|
|||
# regardless of which profile files are sourced.
|
||||
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) {
|
||||
# Zero watermark disables proactive compaction; the reactive path
|
||||
# (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
|
||||
# to `https://github.com`, so it never touches the forge (localhost:3000)
|
||||
# or any other remote. Gated on hyperhive.github.enable; the helper reads
|
||||
# the PAT from HIVE_GITHUB_TOKEN_FILE at invocation and auths as
|
||||
# `x-access-token` + the PAT. System /etc/gitconfig merges under the agent's
|
||||
# ~/.gitconfig (safe.directory), so this is additive.
|
||||
# the PAT from the agent's `github-token` state file at invocation and auths
|
||||
# as `x-access-token` + the PAT. System /etc/gitconfig merges under the
|
||||
# agent's ~/.gitconfig (safe.directory), so this is additive.
|
||||
# Nested-path binding + mkIf (matching the other `environment.etc."…"`
|
||||
# entries above) — a whole-set `environment.etc = {…}` here would collide
|
||||
# with them at the nix level ("attribute already defined").
|
||||
|
|
|
|||
Loading…
Reference in a new issue