GitHub integration
StagingReservation is a GitHub App — it connects to your repos via GitHub's permission model, not via personal access tokens. Each workspace can install on a different account or org.
What permissions does the App need?
| Permission | Access | Why |
|------------|--------|-----|
| Contents | Read | List branches and tags so slot patterns can resolve to real refs. |
| Contents | Read & write | Optional but recommended. Lets the app create or delete branches/tags from the board and Environments page. Without this, you can still mirror — but the "+ Create branch" controls return a "needs Contents: write" error. |
| Metadata | Read | Required by every GitHub App install. |
| Deployments | Read | Receive deployment_status events so slot status flows Deploying → Live. |
| Pull requests | Read | Useful for trunk-based templates that watch pr-* branches. |
The app stores no GitHub tokens long-term. Every API call mints a short-lived installation token from the App's private key + your installation ID.
Webhook events we listen to
| Event | What we do with it |
|-------|--------------------|
| push | Match the ref against every slot's branch pattern. If a slot matches, set currentRef = branch, currentSha, currentStatus = Deploying. |
| create (ref type tag) | Same, but for tag slots. |
| deployment_status | Match the deployment's environment against deployment slots. Set currentRef, currentUrl, status from the deployment's state. |
Every webhook delivery is HMAC-SHA256 verified against your App's
webhook secret before any processing. Malformed or unsigned payloads
return 401 and are not persisted.
What about protected branches?
The app refuses to create or delete any branch named main
or develop, regardless of permissions. This is a hard-coded guard
in the app — granting Contents: write doesn't override it. To work
on those branches you do it on GitHub directly.
Installing for the first time
From a workspace's Repos page, click Connect GitHub. The flow:
- GitHub asks which account / org to install on.
- Pick "All repositories" or a specific list.
- Accept the permission scopes above.
- GitHub redirects back to the workspace's setup URL.
The setup URL is set on the App in GitHub:
https://<your-host>/github/setup. Workspace owners shouldn't have
to touch this — it's set up by whoever runs the StagingReservation
deployment.
Adding or removing repos later
The same Connect GitHub button reopens the GitHub install configuration. You can add or remove repos at any time without disconnecting from the workspace. Repos you've already connected appear under Connected repos with a Disconnect button — that removes the repo from this workspace but does not uninstall the App from your GitHub account.
Uninstalling
Uninstall the App from GitHub's
Settings → Applications → Installed GitHub Apps. This revokes
all access immediately. Slots that were tracking repos via the
uninstalled installation will stop receiving webhook events; their
currentRef/currentSha stay at the last known value until you
reconnect or rebind.
Troubleshooting
- "The GitHub App can't write to this repo" — Contents is set to
Read. Open the App's settings on GitHub, set Contents: Read & write, and re-approve the installation. - "That branch or tag already exists" — pick a different name or use the existing ref.
- Repos page is empty under "Available to connect" — the App is installed on a different account than the repos you want; open Manage GitHub access and add the right org or specific repos.
- Board shows no activity — confirm the App has webhook delivery
enabled on GitHub, and that your CI emits
deployment_statusevents. Webhooks land at/api/webhooks/githubon this host.