Chalk’s GitHub integration lets dashboard users install a GitHub App into their GitHub organization, connect Chalk projects to GitHub repositories, import repository contents into volumes, and open pull requests from a volume’s contents. A GitHub App powers the integration, and the metadata plane (the Chalk API server) holds its credentials.

In Chalk Cloud, Chalk operates this app for you. When you self-host the metadata plane, you register your own GitHub App and configure your API server with its credentials. This page walks metadata-plane administrators through that setup.


​
How the integration works

The API server authenticates to GitHub as a GitHub App:

  1. It signs a short-lived JWT with the app’s private key.
  2. It exchanges that JWT for installation access tokens, scoped to the GitHub organizations (or user accounts) that installed the app.
  3. It uses installation tokens to list repositories, branches, and pull requests, validate project↔repository connections, download repository archives for volume imports, and push branches and open pull requests from volumes.

No user-level OAuth is involved, and GitHub credentials are never sent to the browser: the dashboard talks only to the API server, which proxies all GitHub API access.


​
Step 1: Register a GitHub App

Create a new GitHub App at https://github.com/organizations/<your-org>/settings/apps/new (or Settings → Developer settings → GitHub Apps → New GitHub App for a personal account). Configure it as follows:

SettingValue
GitHub App nameA name for the app, such as Acme Chalk. GitHub derives the app’s URL slug from it, and you use the slug in Step 2.
Homepage URLYour dashboard URL, such as https://chalk.acme.com
Setup URLhttps://<your-dashboard-host>/github-redirect
Redirect on updateEnabled
WebhookDisabled (the integration does not consume webhooks)
Where can this App be installed?“Only on this account” works when all of your GitHub repositories are in one organization

The Setup URL is required. After a user installs the app, GitHub redirects their browser there with an installation_id and the state value from the install link, and that page records the installation with the API server. If the Setup URL is missing or points at the wrong host, the installation succeeds on GitHub but never appears in Chalk.

​
Repository permissions

Grant the following repository permissions:

PermissionAccessUsed for
MetadataRead-onlyListing the repositories an installation can access
ContentsRead and writeListing branches and downloading repository archives for volume imports (read), and pushing a branch for a pull request opened from a volume (write)
Pull requestsRead and writeListing pull requests (read), and opening a pull request from a volume (write)
WorkflowsRead and write (optional)Opening a pull request from a volume when the pull request adds, changes, or deletes files under .github/workflows/. Without this permission, GitHub rejects those pull requests.

A pull request opened from a volume makes the repository match the volume, so it deletes repository files that are not in the volume. If the repository has files under .github/workflows/ and the volume does not, the pull request deletes them and needs the Workflows permission.

No account permissions or event subscriptions are needed.

​
Generate a private key

After creating the app, scroll to Private keys and click Generate a private key. GitHub downloads a .pem file.

Keep the key in the format GitHub provides: an RSA (PKCS#1) PEM beginning with -----BEGIN RSA PRIVATE KEY-----. Do not convert it to PKCS#8 (-----BEGIN PRIVATE KEY-----); the API server only accepts the PKCS#1 format.

Note down from the app’s settings page:

  • App ID: a number, shown under “About”
  • Client ID: a string such as Iv23...
  • Slug: the final path segment of the app’s public page, https://github.com/apps/<slug>

​
Step 2: Configure the API server

Provide the app’s identity to the API server through environment variables:

Environment variableRequiredDescription
CHALK_GITHUB_APP_IDYesThe numeric App ID
CHALK_GITHUB_APP_SLUGYesThe app’s URL slug; the dashboard’s Install GitHub App button links to https://github.com/apps/<slug>/installations/new
CHALK_GITHUB_APP_PRIVATE_KEYYesThe full PEM contents of the private key, including the BEGIN/END lines
CHALK_GITHUB_APP_CLIENT_IDNoThe app’s client ID

Set all three required variables together. If only some are present, the API server logs an error at startup and disables the integration for every team without its own explicit configuration.

If the API server runs on Kubernetes, add the variables to the secret that already backs the API server’s environment:

kubectl -n <api-server-namespace> patch secret <api-server-env-secret> \
  --type merge \
  -p "$(jq -n --rawfile key chalk-app.private-key.pem '{stringData: {
    CHALK_GITHUB_APP_ID: "123456",
    CHALK_GITHUB_APP_SLUG: "acme-chalk",
    CHALK_GITHUB_APP_CLIENT_ID: "Iv23xxxxxxxxxxxxxxxx",
    CHALK_GITHUB_APP_PRIVATE_KEY: $key
  }}')"

Then restart the API server pods so they pick up the new environment. On a successful boot, the API server logs:

githubapp: default GitHub App enabled from environment

This environment-provided app acts as the default for every team on the metadata plane. A team can override it with its own GitHub App through the GitHubAppService/UpsertGitHubAppConfig RPC; an explicit per-team configuration always takes precedence over the environment default.


​
Step 3: Verify

  1. In the dashboard, open Settings → Team → GitHub. The app card shows your app’s slug and App ID instead of a “not configured” notice.
  2. Click Install GitHub App. You land on the app’s installation page on GitHub. Pick an organization and confirm.
  3. GitHub redirects back to /github-redirect on your dashboard, which records the installation and links back to the settings page. The new installation appears in the Installations list.
  4. Connect a project to a repository under Connected projects. On a volume page, use Import from GitHub to clone a repository into the volume, or Open pull request to open a pull request from the volume’s contents.

Start every installation with Install GitHub App in the dashboard. The link it opens carries a signed state value that ties the installation to your Chalk team, and the link expires after 30 minutes. An installation started from the app’s page on GitHub has no state, and the redirect page shows Finish this installation from Chalk instead of recording it.


​
Troubleshooting

SymptomLikely cause
failed_precondition: GitHub App not configured for this teamThe CHALK_GITHUB_APP_* variables are not visible to the API server process (not set, set on the wrong deployment, or the pods were not restarted after the change), and the team has no explicit configuration.
githubapp: ignoring invalid default GitHub App env configuration in API server logsThe variables are partially set, or CHALK_GITHUB_APP_ID is not a number. Set all of CHALK_GITHUB_APP_ID, CHALK_GITHUB_APP_SLUG, and CHALK_GITHUB_APP_PRIVATE_KEY.
The redirect page shows Finish this installation from ChalkThe installation was started from GitHub instead of from Chalk. Click Install GitHub App in Settings → Team → GitHub. The app is already installed on the GitHub account, so GitHub only asks you to confirm.
the GitHub installation link is invalid or has expired; start the installation again from ChalkThe install link is more than 30 minutes old, or the private key was rotated after the link was created. Click Install GitHub App again.
the GitHub account "<account>" is already connected to a different Chalk team; disconnect it there firstEach GitHub account can be connected to one Chalk team. Remove the installation from the other team’s Installations list, then install again.
Install completes on GitHub but never appears in the dashboardThe app’s Setup URL does not point at https://<your-dashboard-host>/github-redirect, or the installing user’s browser could not reach the dashboard afterwards. Fix the Setup URL, then click Install GitHub App again. Refresh from GitHub updates installations Chalk already has and does not add new ones.
Errors mentioning the private key when listing repositories or completing an installationThe key was converted to PKCS#8. Re-download the key from GitHub (it must begin with -----BEGIN RSA PRIVATE KEY-----), or rotate it and configure the new one.
Repository missing from the pickerThe installation only grants access to selected repositories. Update the repository selection for the installation on GitHub, then click Refresh from GitHub.
Opening a pull request from a volume fails on files under .github/workflows/The app does not have the Workflows permission. Add it in the app’s settings on GitHub, then accept the updated permissions for the installation.

​
Key rotation

To rotate the app’s private key:

  1. Generate a new private key on the GitHub App settings page.
  2. Update CHALK_GITHUB_APP_PRIVATE_KEY wherever the API server’s environment is managed.
  3. Restart the API server pods.
  4. Delete the old key on GitHub once the restart is complete.

Installation tokens are short-lived and re-minted on demand, so no other state needs to change. Install links created before the restart stop working; start any installation in progress again from the dashboard.