---
id: platform/github-integration
title: GitHub integration
description: Connect GitHub repositories to a Bex workspace, deploy private code, configure automatic deployment, and troubleshoot missing repositories or pushes.
keywords: [bex, github, github app, push to deploy, private repo]
last_updated: 2026-09-23
---

Connect GitHub to a Bex workspace to discover granted repositories and build
private code. GitHub repository access is separate from
[signing in with GitHub](./sso.md); a successful login does not authorize builds
from every repository your account can see.

## Before connecting

Your platform operator must configure the GitHub App, its credentials and
callbacks, and signed webhook delivery. Workspace admins connect installations;
ordinary users do not supply the platform's GitHub App private key in a service
variable. An unconfigured integration can return `503`.

On a configured installation, no separate webhook is needed for every repository
covered by that GitHub App. This depends on app-wide webhook setup; it is not a
promise that any arbitrary Git URL will receive automatic deployments.

## Connect repositories to a workspace

Use the dashboard's GitHub connection flow in the intended workspace:

1. Start the connection as a workspace admin.
2. Install or authorize the configured GitHub App for the account and repositories
   you want Bex to access. Complete any organization approval GitHub requires.
3. Complete the return/authorization flow to bind the installation to Bex.
4. Check the workspace's repository list before creating a service.

The equivalent start/list API calls use an admin user's authorized OAuth access
token as `BEX_TOKEN` and an explicit workspace ID. A machine API key has the
developer role and cannot start a GitHub connection. See
[API authentication and permissions](./api.md).

```bash
export BEX_WORKSPACE_ID='replace-with-workspace-id'

curl --fail-with-body --silent --show-error \
  -X POST "$BEX_API_URL/v1/git/connect?ownerId=$BEX_WORKSPACE_ID" \
  -H "Authorization: Bearer $BEX_TOKEN"

# Open the returned installUrl and complete the browser flow, then:
curl --fail-with-body --silent --show-error \
  "$BEX_API_URL/v1/repos?ownerId=$BEX_WORKSPACE_ID" \
  -H "Authorization: Bearer $BEX_TOKEN"
```

For an already installed GitHub App, the claim flow starts at
`POST /v1/git/claim?ownerId=…` and returns `claimUrl`. Complete that authorization
flow; an installation ID supplied by itself does not prove ownership.

A workspace can have multiple connections. Inspect them with
`GET /v1/git/connections?ownerId=…`. Repositories shown are the grants from those
connections, not an unrestricted inventory of GitHub.

## Deploy and enable automatic updates

Create a service from the repository, choose the tracked branch, and configure
its [build/runtime](./web-services.md) or [Dockerfile](./docker-deploys.md).
For a monorepo, check the root directory, command paths, and build filters.
Private builds use installation credentials supplied by the platform; do not
embed a personal token in the repository URL or Dockerfile.

Automatic deployment requires the service's auto-deploy setting, a matching
repository and branch, a valid webhook delivery, and any configured build filter
to allow the changed paths. A matching push can start a deployment; it does not
prove the build or application will succeed. Inspect the deployment's commit
and [logs](./logging.md).

For [Blueprints](./app-resource.md), use `autoDeployTrigger: commit` or `off` as
appropriate. `checksPass` is not implemented CI gating. GitHub integration also
does not imply automatic PR preview environments.

## Disconnect an installation

As an admin, identify the connection and use its returned numeric installation
ID with `DELETE /v1/git/connections/{installationId}?ownerId=…`. The old singular
`/v1/git/connection` route is ambiguous when several installations are connected.

Removing the workspace connection can prevent later private clones and push
updates. It is separate from deleting a deployed service. Review and revoke the
GitHub-side installation grant as needed, especially if other workspaces use it.

## Troubleshooting

| Symptom | Check |
| --- | --- |
| Repository missing | Selected workspace, installation account, repository grant, organization approval, and connection health. |
| Private clone fails | Repository/branch spelling and current installation access; authorization can change after service creation. |
| Push causes no deployment | Tracked branch, auto-deploy setting, build filters, and GitHub App webhook delivery. |
| Callback or claim fails | Restart the connection flow; inspect the returned error for expired state, authorization, or ambiguous installation. |
| Build starts but fails | Build commands, root directory, runtime dependencies, and build logs; a successful Git connection only establishes source access. |

See [how deploys work](./how-deploys-work.md) for deployment stages and
[secrets](./secrets.md) for application credentials.

See [monorepo builds](./monorepos.md) for root-directory and shared-source examples.
