logo
icon

ghpool

GitHub API proxy that pools multiple PATs for shared rate-limit budget, caches read responses in memory, and passes mutations through with the client's own auth — built for multi-agent setups (OpenAB, OpenClaw, custom coding agents) sharing the same repos.

template cover
Deployed0 times
PublisherzeaburZeabur
Created2026-05-29
Minimum1 Cores1 GB
Recommended1 Cores1 GB
Tags
Developer ToolsGitHubAI

ghpool

ghpool is a GitHub API proxy designed for multi-agent setups where several coding agents (OpenAB bots, OpenClaw workers, custom agents) share the same repos and burn through GitHub's per-token rate limits.

It does three things:

  • Pools PATs for reads — every GET request is routed through the identity with the most remaining rate-limit budget, so multiple agents share a combined budget instead of each hitting their own ceiling
  • Caches read responses — REST GET and GraphQL query results are cached in memory with per-resource TTLs (PR view 30s, run list 15s, repo view 5min, etc.)
  • Passes mutations through — POST/PATCH/DELETE and GraphQL mutations require the client's own Authorization header and are forwarded with that token, so GitHub's audit log still shows which agent did the write

Architecture

This template deploys ghpool as an internal-only service:

  • No public domain is bound — ghpool is accessed by sibling services in the same Zeabur project via the container network
  • Port 8080 is exposed as TCP (no Ingress, no TLS termination)
  • Port forwarding is disabled by default; enable it in the Networking tab if you need to test from outside the project

Sibling services connect using these environment variables (auto-exposed):

VariableValue
GHPOOL_HOSTNAMEcontainer hostname (e.g. ghpool.zeabur.internal)
GHPOOL_BASE_URLfull base URL (e.g. http://ghpool.zeabur.internal:8080)

Pointing clients at ghpool

How to route a client through ghpool depends on what it is:

Coding agents (Claude Code, Codex, custom agents): most honor GITHUB_API_BASE to override the GitHub API endpoint.

export GITHUB_API_BASE=${GHPOOL_BASE_URL}

gh CLI: use the ghp shim that ships with ghpool — a drop-in replacement that routes reads through ghpool and writes through real gh. Plain gh does not fully honor base-URL overrides (built-ins like gh issue list use GraphQL internally and bypass them); ghp is the reliable path.

Direct HTTP:

curl ${GHPOOL_BASE_URL}/repos/owner/repo

Writes always require the client's own Authorization header — ghpool never injects one for mutations, so the GitHub audit log still shows which agent did the write.

Adding more PATs

The template seeds the pool with one PAT (GHPOOL_PAT_DEFAULT). To add more:

  1. Open the Variables tab of the ghpool service
  2. Add a new environment variable named GHPOOL_PAT_<ID> (e.g. GHPOOL_PAT_BOT_CLAUDE, GHPOOL_PAT_BOT_CODEX) with the PAT as the value — the <ID> becomes the identity name reported by /stats
  3. Restart the service for the new identity to be picked up

Any environment variable matching the GHPOOL_PAT_* prefix is auto-discovered.

Endpoints

PathPurpose
GET /<github-api-path>Proxied GitHub REST API GET (pooled + cached)
POST /graphqlGraphQL — queries pooled+cached, mutations passthrough with client auth
GET /healthzHealth check
GET /statsPool budgets, cache hit rates, per-identity stats

Security notes

  • PATs are kept in environment variables only — never written to disk inside the container
  • GHPOOL_ALLOWED_OWNERS is enforced: requests to any org/user not in this list return 403, so a leaked PAT only exposes the repos you explicitly listed
  • Mutations always require an Authorization header from the client (no auth = 401), so the proxy can't be used as an anonymous write gateway

Resources

ghpool is a single Rust binary (distroless image) — extremely lightweight. Memory is dominated by the in-memory cache (max 10000 entries by default). If you proxy a very high request volume, increase RAM accordingly.