Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

github-credentials

A personal GitHub App-based credential broker: can replace long-lived PATs and SSH keys with short-lived, auto-refreshing GitHub App user access tokens, for GitHub repositories where the App is installed, usable by both git (via a credential helper) and gh (via GH_TOKEN).

github-credentials uses GitHub App user access tokens as the authentication mechanism for interactive Git over HTTPS, via Git's standard credential-helper protocol — an alternative to personal access tokens and SSH keys for supported repositories.

Identity stays the authenticated user — the App is an authorization boundary, not a replacement identity. Effective permissions are the intersection of: your own permissions on a repo, the App's granted permissions, and the installation's repository scope. It does not replace SSH keys or PATs for repositories the App isn't installed on, organizations that don't allow it, or non-GitHub services.

Architecture

See docs/adr/ for the architectural decisions behind this design — why GitHub App user tokens instead of PATs/SSH, why device flow, why a git credential helper, the authorization-boundary security model, and why no client secret is required. For the investigation and experiments that led to these decisions, see docs/history/investigation-log.md.

How it works

device flow login (one-time, browser)
        │
        ▼
  refresh_token  ──refresh (no secret needed)──▶  access_token (~8h)
        │                                              │
        ▼                                              ▼
 stored locally with                          used by git (credential
 restrictive file perms                       helper) and gh (GH_TOKEN)

Setup

Using the official release (recommended)

Official release/Chocolatey binaries already know which GitHub App to authenticate against — ADR-0017 — so setup is just:

  1. Install the cpm-github-credentials GitHub App on the account/repos you want to access: https://github.com/apps/cpm-github-credentials/installations/new (prefer "Only select repositories" over "All repositories").
  2. Download/install the binary (see Distribution below).
  3. token-broker login — no Client ID configuration needed.

Using your own GitHub App

For forks, development, or if you don't want to depend on the official App. Go to https://github.com/settings/apps/new and configure:

Setting Value
Callback URL blank (not used)
Expire user authorization tokens ✅ enabled (required for refresh tokens)
Enable Device Flow ✅ enabled
Webhook → Active ❌ disabled
Repository permissions → Contents Read and write
Repository permissions → Issues/Pull requests/Actions add as needed
Where can this be installed Only on this account, or public if you need to install it on organizations you own — see note below

Or use manifest.json via the App Manifest flow.

Note on installing to organizations: an owner-only-installable GitHub App (public: false) can only be installed on the account that owns it. To install on an organization you own, the App must be switched to publicly installable first (Settings → General → "Make this GitHub App public"). This does not submit it to the Marketplace or make it discoverable — it only lifts the owner-account-only install restriction.

Do not generate/keep a Client Secret unless you disable "Expire user authorization tokens" — no client secret is required for GitHub App user tokens obtained through device flow; refresh uses client_id + refresh_token only.

Install the App (Settings → "Install App" tab → choose account/org → select specific repositories), build (go build -o token-broker.exe ./cmd/token-broker), then log in with your App's Client ID:

./token-broker.exe login --client-id <your-client-id>

Or set it once via $env:TOKEN_BROKER_CLIENT_ID / setx TOKEN_BROKER_CLIENT_ID <id> to avoid passing it every time — it takes priority over the built-in official-App default either way.

Where tokens are stored

%APPDATA%\github-token-broker\tokens.json, restrictive file permissions (0600 in Go; on Windows this is an approximation of Unix semantics, actual protection comes from the file's NTFS ACL, which this project does not explicitly configure beyond Go's default).

Distribution

See ADR-0010/ADR-0011/ADR-0012 for the release/distribution model.

Usage

git

git config --global credential.https://github.com.helper `
  "!'C:/path/to/token-broker.exe' credential-helper"

git clone/push/pull over HTTPS now authenticate automatically, refreshing the token as needed.

gh (one-shot, does not affect other shells)

$env:GH_TOKEN = & .\token-broker.exe token
gh repo view owner/repo
Remove-Item Env:GH_TOKEN

Do not set GH_TOKEN globally/in a shell profile — it overrides gh's own authentication for every invocation in that shell, and this token is scoped to whatever permissions the GitHub App was granted, not full gh scope (e.g. no Actions/Secrets access unless the App was explicitly granted those).

CLI contract

Tracked as a compatibility surface under ADR-0009.

  • --help/-h on any command, or token-broker version/--version, always exits 0.
  • Exit codes: 0 success, 1 runtime failure (login/refresh/persistence/ helper-protocol), 2 usage error (unknown command, missing required flag, bad arguments).
  • stdout carries only machine-readable output — a token (token/credential-helper get) or nothing at all (login/store/erase on success). All human-facing prompts and diagnostics go to stderr.
  • credential-helper get only ever emits a token for protocol=https/host=github.com; any other target produces no output and exits 0 (git's convention for "no credential available"), regardless of how the credential helper is configured in git config.

Run token-broker --help or token-broker <command> --help for full per-command usage.

Security notes

  • tokens.json and any downloaded .pem are gitignored — never commit them.
  • Access tokens: ~8h lifetime. Refresh tokens: ~6 months, rotate on each use.
  • No Client Secret is required or stored by this design.
  • Revoke access anytime by uninstalling the App from an account/org, or deleting the App entirely. This prevents further token refresh and invalidates access granted through the App; whether already-issued access tokens stop working immediately is enforced by GitHub, not this project — in practice moot given their ~8h lifetime.

License

Apache 2.0 — see LICENSE.

About

GitHub App-based credential broker for git/gh authentication

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages