GitHub
Set up GitHub for Lunar. Create the GitHub App the Hub authenticates as, review the permissions it holds, and serve several organizations from one Hub.
The Hub authenticates with a GitHub App installed on your organization. The App vends short-lived installation tokens, which Lunar uses to read repositories and post results, so no long-lived credential is stored anywhere.
You create the App; Lunar never creates one on your behalf. Either flow below produces the same App.
This page covers the GitHub side only. The install steps that consume it are in Prerequisites → Step 5 for self-hosted, or the Dedicated setup steps.
Permissions
The App ends up with these permissions however you create it: the setup tool sets them for you, and the manual flow has you set them by hand. This is the list to hand a security reviewer.
actions
read
Read workflow runs for CI data collection
checks
write
Post policy results as PR checks
contents
read
Fetch config and source for policy evaluation
metadata
read
Required by GitHub on every App
pull_requests
write
Post PR comments and statuses
repository_hooks
write
Auto-register per-repo webhooks
organization_hooks
write
Auto-register organization-level webhooks
Events: push, pull_request, workflow_run.
App creation
Setup tool (recommended)
Follow the prompts. The tool uses GitHub's manifest flow to register the App with the permissions and events above.
Download the PEM private key when prompted. GitHub shows it exactly once — if you click past this page, you'll have to generate a new key from the App settings later.
Click Install App on GitHub and select the org. Choose All repositories unless you have a specific reason not to — Lunar's actual monitoring scope is configured in
lunar-config.yml, so a narrower scope here just means coming back to Org Settings → GitHub Apps → Lunar → Repository access every time you add a new repo to Lunar.
The hosted tool proxies the manifest exchange to GitHub and returns the credentials to your browser; we never persist them.
Manual setup (alternative)
Create the App by hand when the hosted tool can't reach your environment — either of these:
GitHub Enterprise Server. The App has to be created on your own GHES instance.
Air-gapped, or
earthly.devis otherwise unreachable from the browser session you would run the tool in.
Create the App at GitHub's App creation page (or for an org: Org Settings → Developer settings → GitHub Apps → New GitHub App). For GHES, create it on your GHES instance instead. GitHub's registering-a-github-app docs walk through every form field if you want a reference.
Set the permissions and events above, then fill in the rest:
Homepage URL — any URL works (e.g. your internal Lunar URL, or
https://earthly.dev/lunar).Webhook — uncheck "Active." The Hub registers its own per-repo webhooks at runtime; the App-level webhook is unused. URL can be a placeholder (e.g.
https://example.com/placeholder) — GitHub requires a value but nothing will ever hit it.Webhook secret — leave blank. Since you unchecked "Active" above, GitHub won't deliver App-level events. The Hub's per-repo webhook signing secret is a separate thing — see prereqs Step 6.
Where can this app be installed? — "Only on this account."
Then, once the App exists:
Generate a private key (App settings → "Private keys" → "Generate a private key"). Save the
.pemfile — GitHub does not show it again.Install the App on your organization (App settings → "Install App"). Choose All repositories unless you have a specific reason not to, for the same reason as above.
Whichever flow you used, you now hold four things: the owner, the App ID, the installation ID, and the PEM private key. Prereqs Step 5 lists where each one comes from. Confirm you have all four, and that the PEM is saved, before moving on.
Hub configuration (Dedicated)
Nothing to configure: Earthly runs the Hub and configures it for you. Continue at Dedicated → Deposit your credentials, where the PEM goes to your install rather than to Earthly. The self-hosted section below does not apply to you.
Hub configuration (self-hosted)
Those four values are what the Hub reads. Install Step 4 has the values block to paste; this is the reference behind it.
Owner
hub.github.app.owner
HUB_GITHUB_APP_OWNER
The org or user the App is installed on. Matching is case-insensitive and trimmed.
App ID
hub.github.app.id
HUB_GITHUB_APP_ID
Numeric. Quote it in YAML, or it renders as scientific notation.
Installation ID
hub.github.app.installId
HUB_GITHUB_APP_INSTALL_ID
Numeric, from the install URL.
Private key
mounted from lunar-github-app
HUB_GITHUB_APP_PRIVATE_KEY
The base64-encoded PEM.
Base URL
hub.github.baseUrl
HUB_GITHUB_BASE_URL
GHES only. Your instance's API endpoint.
Host
(none)
HUB_GITHUB_HOST
Defaults to github.com. On GHES set it to your instance hostname, so component names (<host>/org/repo) match what your manifests author.
All four App fields are required together. A partial configuration is rejected at startup.
Multiple organizations
When one Hub fronts several orgs that each install their own Lunar App, register one entry per owner in HUB_GITHUB_APPS instead of the single-App variables:
Each entry pins its own App credentials and installation; the Hub mints tokens scoped to the right org per request. Owner matching is case-insensitive and trimmed.
For the PEM files, the recommended pattern is one Kubernetes Secret with multiple keys, mounted as a single volume:
HUB_GITHUB_APPS is mutually exclusive with the single-App env vars (HUB_GITHUB_APP_OWNER / HUB_GITHUB_APP_ID / HUB_GITHUB_APP_PRIVATE_KEY / HUB_GITHUB_APP_INSTALL_ID). Use one mode or the other.
Next steps
Self-hosted installs carry these four values into Kubernetes secrets at prereqs Step 6, and into your chart values at install Step 4. On Dedicated you deposit the PEM into your install's secret drop instead.
For how GitHub and GitLab differ once Lunar is running, see Git Platforms.
Last updated
