The Terrantula GitHub App is the recommended way to authorize PR-opening triggers against GitHub. Once installed and linked to a project, Terrantula mints short-lived installation tokens at dispatch time — you don't store long-lived personal access tokens. This page is the reference for the App's identity, permissions, install flow, and credential resolution.
The GitHub App only ever opens pull requests (and, optionally, fires
repository_dispatch). It never runs terraform apply. Your CI applies the
merged change; Terrantula observes the outcome via the
webhook.
The App is optional. A static trigger.auth.token (a PAT or
{{ secrets.* }} reference) works without any App install — the Sam-cohort
escape hatch for GHE-Server and no-App self-hosters. See
Credential resolution.
| Field | Hosted (terrantula-io) | Self-hosted |
|---|---|---|
| App ID | 3754472 | your numeric App ID |
| App slug | terrantula-io | your App slug |
| Owner | terrantula-io org | you |
| Install URL | https://github.com/apps/terrantula-io/installations/new | https://github.com/apps/<your-slug>/installations/new |
| Webhook URL | https://api.terrantula.io/webhooks/github | https://YOUR-DOMAIN/webhooks/github |
Self-hosters register their own App and supply its credentials to the Terrantula API and worker (see Configuration).
| Permission | Level | Why |
|---|---|---|
contents | write | Open PRs, push branches, fire repository_dispatch. |
actions | write | Trigger repository_dispatch workflows. |
pull_requests | write | Open and update PRs. |
issues | write | Reserved for linking issues to action runs. |
metadata | read | Required by GitHub for all Apps. |
The App subscribes to the events that drive lifecycle and PR-trigger auto-completion:
| Event | Use |
|---|---|
pull_request | Transition a PR-trigger ActionRun on merge/close. |
pull_request_review | Reserved. |
workflow_job, workflow_run | Reserved. |
installation | Track install / suspend / delete lifecycle. Auto-delivered. |
installation_repositories | Track repo-grant changes. Auto-delivered. |
installation and installation_repositories are delivered automatically — no
checkbox in the GitHub UI.
POST /github/install-url, session-authed).GET /github/install-callback?installation_id=…&state=….
The callback is authenticated by the signed state JWT — not a session or
Bearer token. Terrantula validates the state, fetches installation metadata +
granted repos, and upserts a github_installations row with status active.installation webhook to
/webhooks/github.
The callback is the source of truth for row creation; the webhook is
acknowledged.A cross-tenant install collision (an installation already claimed by another org) returns 409 and never leaks which org owns it.
If you close the install tab before the redirect lands, the row may be missing.
An org owner/admin can claim it with POST /github/installations/recover
({ orgId, installationId }).
PR-opening triggers (and postMergeDispatch) pick a GitHub credential at
dispatch time:
auth.token → mint an installation token for the
target repo (link read from project_github_repos). Preferred.auth.token supplied → use the static token (or the
referenced {{ secrets.* }} value) as-is. The OSS / Sam-cohort escape hatch.trigger.auth.token.Every dispatch emits a github-dispatch-attempted audit event with
credential_type, repo, installation_id (when applicable), and outcome —
no token values are ever logged.
A static auth.token used for repository_dispatch must have contents:writescope on the target repo. Installation tokens get this automatically from the
App's permissions.
Self-hosters set four environment variables on the API and worker. The
PR-opening surface is gated on TERRANTULA_DEPLOYMENT=cloud in the API; the OSS
default uses static-token credentials only (no SaaS dependency).
| Env var | Value |
|---|---|
GITHUB_APP_ID | Numeric App ID. |
GITHUB_APP_NAME | The App slug (the /apps/<slug> URL segment), not the display name. |
GITHUB_APP_PRIVATE_KEY | The full PEM (GitHub emits PKCS#1; PKCS#8 also accepted). |
GITHUB_APP_WEBHOOK_SECRET | The webhook secret you set in App settings — must match exactly. |
If any are missing, all GitHub routes return HTTP 503 — Terrantula does not crash; GitHub integration is simply unavailable. See the Configuration reference for the full env list.
DELETE /github/installations/:id marks the row deleted
in Terrantula; it does not uninstall the App on GitHub — that stays
user-controlled. GitHub installation deleted/suspend webhooks also flip the
row and revoke cached installation tokens.installation_repositories webhook and update the cached granted_repos.GITHUB_APP_WEBHOOK_SECRET. There is no grace period; restart the API after
changing either.