From d804859128ce531c19a1934d4888761d8e41a955 Mon Sep 17 00:00:00 2001 From: damocles Date: Sat, 11 Jul 2026 10:49:01 +0200 Subject: [PATCH] docs(#1970): document githubAccount + gh/git integration + hivectl github set-token --- CLAUDE.md | 2 ++ README.md | 14 +++++++++ docs/github.md | 72 +++++++++++++++++++++++++++++++++++++++++++ docs/tools/hivectl.md | 19 ++++++++++++ 4 files changed, 107 insertions(+) create mode 100644 docs/github.md diff --git a/CLAUDE.md b/CLAUDE.md index 37322c3a..aab72fdc 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -113,6 +113,8 @@ read them à la carte. - **"How does the matrix-tuwunel container work? What about fluffychat-web and per-agent matrix accounts?"** → [`docs/matrix.md`](docs/matrix.md). +- **"How do I give an agent a GitHub account (`gh` + `git push`)? + How is the PAT injected?"** → [`docs/github.md`](docs/github.md). - **"How does DNS resolution work in agent containers? What's the bridge network for?"** → [`docs/network.md`](docs/network.md). - **"How do I connect two hives into a swarm? How do I declare peer diff --git a/README.md b/README.md index b83d55a4..ca99fdac 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,20 @@ The hive-internal account is always named `main` (synthesized from `hyperhive.ma For more details see [`docs/matrix.md`](docs/matrix.md). +### GitHub account + +`hyperhive.githubAccount` gives an agent a managed GitHub identity — a `gh` CLI wrapper and `git push` over HTTPS, both authenticated as a configured bot account: + +```nix +hyperhive.githubAccount = { + username = "the-sword-above"; + tokenFile = "/agents/myagent/state/github-token"; # PAT provisioned out-of-band + # host = "github.com"; # default; set for GHE +}; +``` + +The PAT value is never in nix; write it with `hivectl github set-token --token-stdin`. Both the `gh` wrapper and the git credential helper read the token live, so a rotated PAT takes effect with no rebuild. Single account per agent. For more details see [`docs/github.md`](docs/github.md). + ## Operator CLI `hivectl` is the operator-facing host CLI for ad-hoc administration that diff --git a/docs/github.md b/docs/github.md new file mode 100644 index 00000000..3212acf1 --- /dev/null +++ b/docs/github.md @@ -0,0 +1,72 @@ +# GitHub accounts + +Give an agent a managed GitHub identity — a `gh` CLI and `git push` over +HTTPS, both authenticated as a configured bot account — so it can run +GitHub API calls and push commits without any manual `gh auth login`. + +This mirrors the [matrix account](matrix.md) pattern: nix carries the +login + host, never the secret; an operator-supplied personal access +token (PAT) is injected out of band into the agent's state dir. + +## Config option + +Declare `hyperhive.githubAccount` in the agent's `agent.nix`: + +```nix +hyperhive.githubAccount = { + username = "the-sword-above"; # the bot login + tokenFile = "/agents//state/github-token"; # where the PAT lives + # host = "github.com"; # default; set for GHE +}; +``` + +`null` (the default) leaves GitHub off entirely — no `gh` wrapper, no +credential helper, no env. Single account per agent by design (unlike +`matrixAccounts`, which is multi-account): the workflow is "this agent is +this one bot". + +The token **value** is never in nix. `tokenFile` only names the path; the +PAT is written there separately (see [Provisioning](#provisioning)). + +## How the agent uses it + +When `githubAccount` is set, the container gets: + +- **A `gh` wrapper** on `PATH` (shadowing the raw `gh`) that exports + `GH_TOKEN` from the token file at invocation, then execs real `gh`. So + `gh pr create`, `gh api …`, etc. just work as the bot. +- **A git credential helper** (`git-credential-hive-github`), wired via a + host-scoped `/etc/gitconfig` entry for `https://`, so + `git push https://github.com//` authenticates as the bot. + Host-scoped, so it never touches the forge (`localhost:3000`) or any + other remote. +- **Env**: `HIVE_GITHUB_USER`, `HIVE_GITHUB_HOST`, + `HIVE_GITHUB_TOKEN_FILE`, and `GH_HOST`. + +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. + +## Provisioning + +The PAT is operator-supplied. Write it into the agent's token file with: + +```sh +hivectl github set-token --token-stdin # paste the PAT on stdin (preferred) +hivectl github set-token --token # inline (visible in shell history) +``` + +hive-c0re delegates the write to hive-priv, which stores the file `0600` +owned by the agent (so the container can read it) — the same credential +injection path as forge/matrix tokens. See +[hivectl → GitHub](tools/hivectl.md#github). + +## Security + +- Use a **dedicated bot account**, never a human's. +- Mint a **minimally-scoped PAT** — only the repos/scopes the agent's + workflow needs. Agents have passwordless sudo, so a compromised or + hallucinating agent can act as the account within the token's scopes; + scope is the real blast-radius limiter, and the container boundary is + the enforcement. See [security.md](security.md). diff --git a/docs/tools/hivectl.md b/docs/tools/hivectl.md index 6af3b932..38d1c84f 100644 --- a/docs/tools/hivectl.md +++ b/docs/tools/hivectl.md @@ -75,6 +75,25 @@ hivectl matrix invite @mara:server --room '#hive-chat:server' # ...or to a spec invite power (it owns the hive Space, so that case always works). Idempotent — already-member / already-invited is a no-op. +## GitHub + +Write an operator-supplied GitHub personal access token (PAT) into an +agent's token file so its `gh` wrapper + git credential helper can act as +the configured bot account. Unlike forge/matrix there is no account +creation — the PAT is for an existing GitHub account. The agent must +declare [`hyperhive.githubAccount`](../github.md). + +```bash +hivectl github set-token damocles --token-stdin # paste the PAT on stdin (preferred) +hivectl github set-token damocles --token # inline (visible in shell history) +``` + +- `set-token`: writes `/github-token` (`0600`, agent-owned) via + hive-priv — the same credential-injection path as forge/matrix tokens. + The `gh` wrapper / git credential helper read it live, so a freshly-set + or rotated PAT takes effect with no rebuild or restart. Refuses an empty + token. See [github.md](../github.md) for the full flow + security notes. + ## Gateway Manage users in the gateway's HTTP Basic auth htpasswd file