Connecting GitHub as a CI/CD provider
This section deals with setting up a GitHub App which is required for sfp server to integrate with your GitHub org.
sfp server acts on your repositories through a GitHub App: it clones code, writes commit statuses and checks, comments on and merges pull requests, and registers repository webhooks. These capabilities exceed what GitHub Actions' default GITHUB_TOKEN provides, which is why a dedicated GitHub App is used.
The App is the automation identity. It is separate from the GitHub OAuth App used to log users in (see Setting up sfp server → [6] Configure login): a typical setup has a login provider for users and this GitHub App for machine work. On Azure DevOps, the equivalent automation identity is a service principal. Connect either one after the server is up, in Settings → Integrations, or in the onboarding wizard — see Setting up sfp server → [5] Configure your git provider.
Automation vs. user attribution. The App is the actor for machine-driven work — cloning, checks, statuses, webhook creation. Actions that should be traceable to a person — opening a release issue, or raising a PR on a user's behalf through IssueOps — run under that signed-in user's OAuth token, so they appear under the user's name, not the App's. The user OAuth token comes from the login provider, not from this App.
The GitHub reference describes how repository operations authenticate as an installed App.
[1] Choose your app: managed or registered
The path depends on where your repositories live. The decision is made in an external provider console, so this section carries the conceptual marker.
| Where your repos live | What you use |
|---|---|
| GitHub.com | The managed flxbl-cloud app, installed during onboarding — see 1.a |
| GitHub Enterprise Server | A GitHub App you register in your GHES org — see 1.b |
[1.a] GitHub.com — install the managed flxbl-cloud app
On GitHub.com there is no manual App to build: during onboarding (or in Settings → Integrations → GitHub → Install GitHub App) you authorize the prebuilt flxbl-cloud app and pick which repositories it can access. No App ID or private key is copied. The server then verifies the installation when you continue onboarding.
This step happens in GitHub's console, so it is marked conceptual.
[1.b] GitHub Enterprise Server — register a GitHub App
GitHub Enterprise Server has no prebuilt app, so you register one:
- Open your GHES org's Settings → Developer settings → GitHub Apps and select New GitHub App.
- Give it a name and display information. The app's own Webhook URL and Webhook secret fields can be left blank: sfp server registers repository webhooks itself after the app is installed, to
https://<your-domain>/sfp/api/repository/webhook.
This step happens in the GHES console, so it is marked conceptual.
[1.c] Repository permissions
Grant the app these permissions. Each maps to an operation the server performs (clone and file writes, pull request and issue interaction, checks and statuses, webhook registration, team-member lookups):
| Repository permission | Level | Why |
|---|---|---|
| Contents | Read & write | Clone repositories, read and write files in the repo |
| Issues | Read & write | Comment, label, create and update issues |
| Checks | Read & write | Create and update CI/CD check runs |
| Commit statuses | Read & write | Set commit status for CI/CD |
| Pull requests | Read & write | Comment on, review, merge and label pull requests |
| Webhooks | Read & write | Create, update and delete repository webhooks |
| Members | Read-only | Resolve team members for environment approvers |
| Metadata | Read-only | Baseline access GitHub requires (installations, user and team lookups) |
If the app is missing Webhooks permission, repository webhook creation fails. The server reports this as: "Please update the GitHub App permissions to include Repository permissions > Webhooks > Read & Write."
The permission matrix is a reference table set in GitHub's console, so it is marked conceptual.
[1.d] Subscribe to events
Subscribe the app to these events — the exact set sfp server listens for:
push, pull_request, pull_request_review, pull_request_review_comment, issues, issue_comment
These are also the events sfp server writes on each repository webhook it registers.
The events list is configured in GitHub's console, so it is marked conceptual.
[1.e] Generate the private key and install the app
- In the app's General section, under Private keys, select Generate a private key and download the
.pemfile. It is shown once; store it securely. - Open the Install App tab, select Install, choose your organization, and grant the app the repositories (or all repositories) sfp server should reach.
This step happens in GitHub's console, so it is marked conceptual.
[2] Add the app credentials to the server
Enter the App ID (from the app settings page) and the private key (.pem contents) in Settings → Integrations → GitHub, or in the onboarding wizard's integration step. The server stores them encrypted at rest. They are not part of the sfp server init prompts — the CLI's secret collection does not ask for them. As an alternative to the UI, the running server also accepts GITHUB_APP_ID and GITHUB_APP_PRIVATE_KEY environment variables.

[2.a] GitHub Packages (npm) — optional registry token
If your pipelines publish or consume GitHub Packages (npm), configure a GITHUB_TOKEN with read:packages and write:packages under Settings → Integrations → npm Registry. GitHub Apps cannot operate on GitHub Packages; the server uses this token only to authenticate against npm.pkg.github.com. If you do not use GitHub Packages, this token is not needed.
Most setups do not reach this step, so it is marked conceptual.
[3] Verify the integration
Once the app is installed on a repository, the server registers the repository webhook itself — you do not configure webhooks on GitHub by hand. Confirm:
- In Settings → Webhooks, the repo's webhook is listed as active against
https://<your-domain>/sfp/api/repository/webhook. - The payload URL is reachable from GitHub.com over HTTPS — a server reachable only by SSH, VPN, or a bastion is not. See Webhook ingress for private servers when the server is private.
- In GitHub's Recent deliveries for that webhook, a delivery returns
2xxand the server log reports the signature was verified. See Troubleshooting → Webhooks for failures.

Prerequisites
Prepare a host for sfp-server before you run sfp server init — sizing, operating system, the container engine, network, DNS, TLS, firewall, and the registry secrets required at init time.
Self Hosted Supabase Configuration
Configure the bundled self-hosted Supabase that an sfp server provisions — the API gateway, GitHub login, keys, and day-to-day maintenance.