Agenthost Docs

GitHub authentication for agents

How private repos, workspace repos, runtime tokens, and the GitHub integration relate — and how to verify gh on a runtime.

Agents run on your machine via the daemon. Cloning and fetching private GitHub repositories happens there, using git and optional gh. The Agenthost server does not perform git operations for agent tasks.

Three ways the daemon gets a GitHub token (priority order)

When the daemon starts an agent task, it sets GH_TOKEN / GITHUB_TOKEN on the agent process from one resolved value. The daemon picks the first non-empty source in this order (see resolveGitHubToken in the server/daemon code):

(1) GitHub token saved on the runtime (highest priority)

  • Where to set: Agenthost UI → your workspace → Runtimes → select the runtime (device + provider) → GitHub token field. On Save, the server calls GitHub’s GET /user API with your PAT; if GitHub returns 401/403, the save is rejected and nothing is written. On success, the UI shows which GitHub user the PAT belongs to and (when GitHub sends it) token scopes from the X-OAuth-Scopes header — this is independent of whether the gh CLI is installed on the daemon machine.
  • How it is stored: In PostgreSQL on the agent_runtime row, column settings (JSONB). The key is github_token (plaintext in the DB). API GET responses never return the raw token — only github_token_set and a short github_token_preview (masked). Updating settings uses UPDATE ... SET settings = settings || patch::jsonb so other keys are preserved. When the daemon registers runtimes for a workspace, the server attaches plaintext tokens to the registration HTTP response (github_tokens keyed by runtime id) over TLS; the daemon keeps that in memory as the highest-priority source for resolveGitHubToken(). Tokens are not embedded in the metadata JSON blob (that blob only carries things like CLI version and gh probe status).
  • After you change the token: Restart the daemon on that machine so it re-registers and picks up the new value; heartbeats today do not re-stream github_tokens.
  • When to use: Team-friendly default — each machine that runs agents can have its own PAT without putting secrets in shell profiles.
  • Scopes: For private repo clone/fetch over HTTPS, a classic PAT needs repo (or a fine-grained token with Contents: Read on the repos you use). For pushes, include write access as needed.

(2) Environment variables on the daemon process

  • Where to set: Whatever launches the daemon (shell profile, systemd unit, Docker env, CI, etc.) — set GH_TOKEN or GITHUB_TOKEN for the process that runs agenthost daemon start (or the desktop app’s embedded daemon).
  • When to use: Headless servers, containers, or when you intentionally want the same token for all workspaces on that host.

(3) GitHub CLI on the host (gh auth login)

  • Where to set: On the same user account (or environment) that runs the daemon, run gh auth login and complete the flow so gh auth token returns a token.
  • When to use: Local development when you already use gh and prefer not to paste a PAT into Agenthost.

If all three are empty, HTTPS clones of private GitHub repos will fail; public repos may still work. SSH remotes ([email protected]:...) can still work if SSH keys and the agent are available to git (not covered by the token list above).

How to see if gh is installed and logged in on a runtime

Open Runtimes in the workspace, choose the runtime row for the machine and provider you care about. The GitHub section shows:

  • gh CLI authenticated as <user>gh is on PATH and gh auth token works.
  • gh CLI available (not authenticated) — binary found but not logged in.
  • gh CLI not detected on this runtimegh was not found when the daemon registered.

That status reflects the daemon host at registration time; restart the daemon after installing or logging in to gh so metadata refreshes.

metadata.gh_available is not “do I have a runtime PAT?” It only records whether the GitHub CLI (gh) was found on the daemon’s PATH and (when found) whether gh auth status succeeded. You can have gh_available: false in the raw metadata JSON while a runtime GitHub token is saved and used for HTTPS git — those are independent. In the UI, the masked token row under GitHub is the indicator that (1) is configured; the CLI line is optional (3).

Workspace GitHub integration (OAuth) vs git auth

Connecting GitHub under Settings → Integrations stores an OAuth token on the server for Agenthost features (e.g. listing repos, importing issues, webhooks). It does not replace (1)–(3) for local git clone/fetch inside agent tasks.

You can still use the integration to pick repositories when editing Settings → Repositories (“Add from GitHub”), which copies HTTPS URLs into the workspace list. Clone auth for those URLs still uses (1)–(3) on the daemon host.

Workspace repository list

Workspace repositories (Settings → Repositories) are an allowlist of URLs passed to the agent as metadata. They are not credentials. For GitHub HTTPS, use https://github.com/org/repo.git form.

Per-agent PAT / separate GitHub users for commits

Today, one resolved token (per the priority above) is injected into the agent process as GH_TOKEN / GITHUB_TOKEN for that run. Per-agent PATs are not a first-class field yet.

Practical options:

  • Different GitHub accounts: Run agents on different machines (or different OS users) with different runtime tokens or gh logins — each runtime row maps to one daemon registration context.
  • Commit author metadata only: You can set GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL in the agent’s Environment tab so commits show a chosen name/email; push still uses the runtime/daemon/gh identity unless you use SSH keys for that identity.

Do not put GH_TOKEN / GITHUB_TOKEN in the agent Environment tab — those keys are blocked; the daemon manages them to avoid accidental overrides and confusion with (1)–(3).

Next