GitHub Enterprise Server (GHES) Setup
This guide walks you through configuring Gru to work with a GitHub Enterprise Server instance. If you're using github.com, see GETTING_STARTED.md instead.
Prerequisites
Complete the basic Getting Started prerequisites first (Rust, Claude Code). Then come back here for GHES-specific setup.
Step 1: Authenticate gh CLI with your GHES host
Gru delegates all GitHub API calls to the gh CLI, so you need gh authenticated against your GHES instance.
gh auth login --hostname github.netflix.com
Follow the prompts to authenticate. When asked about protocol, HTTPS is recommended for GHES.
Verify it worked:
gh auth status --hostname github.netflix.com
You should see output like:
github.netflix.com
✓ Logged in to github.netflix.com account yourname
Multi-host authentication
The gh CLI supports being logged into multiple hosts simultaneously. If you use both github.com and a GHES instance:
# Authenticate to both
gh auth login # github.com
gh auth login --hostname github.netflix.com # GHES
# Verify both
gh auth status
Gru sets GH_HOST on every gh CLI invocation, so the correct host is always targeted — you don't need to worry about which is the "default".
Token scope requirements
Your token needs the following scopes:
| Scope | Why |
|---|---|
repo | Read/write access to repositories, issues, and PRs |
read:org | Discover repos and check org membership |
If you authenticate interactively with gh auth login, the default scopes are usually sufficient. If you're using a personal access token, make sure it includes the scopes above.
To verify your token's scopes without exposing the token value, use the GitHub API — the response headers include X-OAuth-Scopes:
gh api --hostname github.netflix.com /user --include 2>&1 | grep -i x-oauth-scopes
Alternatively, navigate to your GHES instance → Settings → Developer settings → Personal access tokens to view scopes in the UI.
Step 2: Configure ~/.gru/config.toml
Create or edit ~/.gru/config.toml and add a named host entry:
[github_hosts.netflix]
host = "github.netflix.com"
The name (netflix in this example) is your shorthand — you'll use it when referencing repos.
Optional: web_url
If the GHES web UI lives on a different domain than the API/git host (uncommon), set web_url. Note that host is a bare hostname while web_url is a full URL including scheme:
[github_hosts.netflix]
host = "github.netflix.com"
web_url = "https://github-web.netflix.com"
Most GHES installations don't need this.
Step 3: Reference repos using the named host
In your config's daemon.repos, reference GHES repos with the name:owner/repo format (this shorthand is for config files only, not CLI arguments):
[daemon]
repos = [
"netflix:myteam/myapp",
"netflix:myteam/mylib",
]
This tells Gru that myteam/myapp lives on the host defined in [github_hosts.netflix].
Repo format reference
| Format | Example | Resolves to |
|---|---|---|
owner/repo | myorg/app | github.com/myorg/app |
name:owner/repo | netflix:myteam/myapp | Uses [github_hosts.netflix] |
host/owner/repo | github.netflix.com/org/svc | Legacy — use name:owner/repo instead |
The name:owner/repo format is recommended for GHES.
Step 4: Initialize and run
Initialize your GHES repo. If you're passing owner/repo explicitly, use --host:
gru init myteam/myapp --host github.netflix.com
Alternatively, if you run gru init from inside an already-cloned GHES repository, Gru can infer the host from the git remote automatically — no --host flag needed in that case.
Then use Gru normally:
# Work on a single issue (use the full URL for GHES issues)
gru do https://github.netflix.com/myteam/myapp/issues/42
# Or from within the worktree, just use the issue number
gru do 42
# Run lab mode to poll for gru:todo issues
gru lab
Full config example
Here's a complete config for a team using GHES with two repos:
[github_hosts.netflix]
host = "github.netflix.com"
[daemon]
repos = [
"netflix:myteam/api-gateway",
"netflix:myteam/web-ui",
]
poll_interval_secs = 60
max_slots = 4
[agent]
default = "claude"
[merge]
confidence_threshold = 9
See config.example.toml for all available options with explanations.
Troubleshooting
gh auth status fails for GHES host
github.netflix.com
X Not logged in to github.netflix.com
Fix: Run gh auth login --hostname github.netflix.com and authenticate.
"Unknown host name" error
Unknown host name 'netflix' in repo 'netflix:myteam/myapp'.
Add a [github_hosts.netflix] section to config.toml
Fix: Add the missing host entry to ~/.gru/config.toml:
[github_hosts.netflix]
host = "github.netflix.com"
403 Forbidden on API calls
Your token likely lacks required scopes. Re-authenticate with appropriate scopes:
gh auth login --hostname github.netflix.com --scopes repo,read:org
Or generate a new personal access token in your GHES settings with the scopes listed in Step 1.
SSL/TLS certificate errors
If your GHES instance uses a self-signed or internal CA certificate, the most reliable fix is to add the certificate to your system trust store. The gh CLI uses Go's standard TLS stack, which defers to the OS trust store.
On macOS:
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /path/to/ca-cert.crt
On Linux (Debian/Ubuntu):
sudo cp /path/to/ca-cert.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates
For git operations only (does not affect gh API calls):
git config --global http.https://github.netflix.com/.sslCAInfo /path/to/ca-bundle.crt
gru init hangs or times out
Check network connectivity to your GHES host:
gh api --hostname github.netflix.com /meta
If this fails, the issue is network-level (VPN, firewall, DNS).
Issue comments or labels not appearing
Verify your token has repo scope and that you have write access to the repository:
gh api --hostname github.netflix.com repos/myteam/myapp
If you get a 404, you either don't have access or the repo path is wrong.