GitHub
SignalPilot reads repositories through a GitHub App installation rather than a personal access token. That means access is granted per repository, is revocable from GitHub, and produces short-lived installation tokens the gateway mints on demand.
Two things need it:
- dbt projects imported into a project.
- Private eval sets and private
project_repovalues — see Evals.
Public repositories need no setup at all.
Connecting
- Settings → GitHub → Connect GitHub.
- Choose the organization or account to install into.
- Grant access to only the repositories SignalPilot should read. GitHub lets you change this later; the gateway respects it immediately.
- You return to the settings page with the installation listed.
You can install into more than one account — each installation appears separately, with its repositories underneath.
Linking a repository to a project
From the installation, pick a repository and link it. That creates (or attaches to) a workspace project backed by that repo. Unlink detaches it; your GitHub repository is not modified.
Sync and fetch actions pull the latest commit into the workspace.
Pull requests from chat
When a chat runs against a GitHub-linked project, the agent can ship model changes as a pull request:
- The agent edits models in its sandbox and runs
dbt builduntil it passes. - It commits and pushes to a
signalpilot/<short-name>branch. The push goes to SignalPilot's own git server, which mirrors that one branch to your repository. Pushes to any other branch, force pushes, and branch deletions are refused. - It opens a pull request against the project's base branch and links you to it in its answer. It can later update the description or add comments.
- You review and merge on GitHub as usual.
There is no approval step before the pull request is opened, and SignalPilot never merges. The sandbox holds only its own session token; the GitHub installation token stays on the gateway.
How credentials are handled
- The gateway exchanges the App's private key for an installation token with a short lifetime, scoped to that installation.
- The token is used gateway-side to clone. It is never handed to a sandbox: eval and notebook sandboxes receive a presigned tarball of the checked-out tree, so a compromised sandbox has no path back to your repositories.
- A repository your installation does not cover is refused with a clear error rather than attempted anonymously.
Self-hosting
Configure the App with SP_GITHUB_APP_ID, SP_GITHUB_APP_CLIENT_ID,
SP_GITHUB_APP_CLIENT_SECRET, SP_GITHUB_APP_PRIVATE_KEY, and
SP_GITHUB_APP_SLUG, plus SP_WEB_URL so the OAuth redirect returns to your web
app. See Configuration.
There is also a bot path — SP_GITHUB_BOT_TOKEN, SP_GITHUB_WEBHOOK_SECRET,
SP_GITHUB_BOT_CONNECTION — used for webhook-driven automation. The webhook
endpoint refuses requests with 503 until the webhook secret is set.
Point the App's webhook at <gateway>/api/github/webhook, give it the same
secret, and subscribe it to Push and Pull request events. A push to a
watched branch is imported and the dbt map recompiled within seconds. If the
webhook is missing or misconfigured, a background sweep pulls every watched
branch on an interval (SP_REPO_SYNC_INTERVAL_SECONDS, 15 minutes by default),
so a linked project can be stale for at most one interval.
Troubleshooting
| Symptom | Cause |
|---|---|
| No installations listed | The App is not installed, or not on this account. Use Connect GitHub. |
| Repository missing from the list | The installation does not include it. Adjust repository access in GitHub. |
?error= banner after returning | The OAuth exchange failed — usually SP_WEB_URL not matching the App's callback URL. |
| Eval or project clone refused | The repo is outside the installation, or the URL is not https://github.com/…. |