Skip to main content
Guides

GitHub App Tokens

Generate short-lived GitHub installation tokens from a GitHub App private key. Tokens refresh automatically in the background.

Prerequisites

  • CA certificate generated (CA Setup)
  • A GitHub App created with the required permissions
  • The App’s private key (PEM file), downloaded from the App settings page
  • The installation ID (visible in the App’s installation URL: https://github.com/settings/installations/{id})

Configuration

Add a github-app credential source to gatekeeper.yaml:

proxy:
  host: 127.0.0.1
  port: 9080

tls:
  ca_cert: ca.crt
  ca_key: ca.key

credentials:
  - host: api.github.com
    header: Authorization
    grant: github
    source:
      type: github-app
      app_id: "12345"
      installation_id: "67890"
      private_key_path: ./github-app-key.pem

network:
  policy: permissive

log:
  level: info
  format: text
FieldRequiredDescription
app_idYesGitHub App ID (from App settings)
installation_idYesInstallation ID for the target org/account
private_key_pathOne ofPath to the PEM private key file
private_key_envOne ofEnvironment variable containing the PEM private key

Set either private_key_path or private_key_env, not both.

Private Key via Environment Variable

For environments where files are not practical (containers, CI):

source:
  type: github-app
  app_id: "12345"
  installation_id: "67890"
  private_key_env: GITHUB_APP_PRIVATE_KEY
export GITHUB_APP_PRIVATE_KEY="$(cat github-app-key.pem)"

Auto-Refresh Behavior

GitHub installation tokens expire after one hour. Gatekeeper refreshes them automatically:

  1. At startup, gatekeeper generates a JWT signed with the App private key and exchanges it for an installation token via the GitHub API.
  2. A background goroutine re-fetches the token at 75% of TTL (roughly every 45 minutes).
  3. If a refresh fails, gatekeeper retries with exponential backoff (1s to 60s) until it succeeds.
  4. Token rotation is atomic — requests always see either the old or new token, never a partial state.

When multiple credential entries share the same github-app source (e.g., api.github.com and github.com), a single refresh goroutine updates all of them.

Start the Proxy

gatekeeper --config gatekeeper.yaml

Verification

curl --cacert ca.crt --proxy http://127.0.0.1:9080 https://api.github.com/installation/repositories

A successful response confirms the installation token was generated and injected. The proxy log shows:

level=INFO msg=request http_host=api.github.com credential_injected=true grants=github

At debug level, refresh events appear:

level=DEBUG msg="credential refreshed" host=api.github.com grant=github ttl=1h0m0s

See examples/gatekeeper-github-app.yaml for a complete working example.

Next Steps