The integration is an org-level connection with a per-project repository: one GitHub App installation per Entri organization, and each project picks one installed repository, a branch, and a sync mode. File paths and formats are read from the repository’s
.nt3.yml (the same file nt3 pull uses).githubAppEnabled: false in GET /api/v1/config).
1. Create the GitHub App
Go to GitHub → Settings → Developer settings → GitHub Apps → New GitHub App, or create it under your organization’s settings if it should be organization-owned.Basic information
- Name: anything, e.g.
Entri Sync. The URL slug GitHub derives from it becomesGITHUB_APP_SLUG. - Homepage URL: your Entri instance, e.g.
https://entri.example.com.
Identifying and authorizing users
If connecting fails, Entri returns to the organization settings with areason:
- Callback URL:
https://<your-instance>/api/v1/integrations/github/setup-callback- For local development:
http://localhost:3333/api/v1/integrations/github/setup-callback
- For local development:
- Setup URL: leave blank. Because OAuth during installation is enabled, the callback URL handles the post-install redirect.
- Redirect on update: leave unchecked unless you want reconfiguration to re-run the callback. The callback handles
setup_action=updateeither way.
Webhook
- Uncheck Active. Entri does not use a webhook receiver; an uninstalled or suspended installation is detected the next time Entri requests an installation token.
Repository permissions
Grant exactly these (least privilege):
Do not grant
Workflows, Actions, Administration, or Secrets. Lacking Workflows is a second line of defense behind Entri’s own .github/ path denylist.
Where can this App be installed?
“Only on this account” is fine for a single organization. Choose “Any account” if other GitHub organizations will install it. When installing, we recommend Only select repositories rather than all repositories.2. Collect the credentials
From the App’s settings page:
Generate a dedicated state secret, used to sign the install
state parameter. Do not reuse ENCRYPTION_KEY:
GITHUB_BOT_EMAIL to control the committer email of sync commits (default: noreply@<hostname of APP_HOST>).
These are separate from
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET, which enable “Sign in with GitHub”. Don’t overwrite those.3. Configure your instance
Set the six variables in your deployment (Docker Compose.env, Helm values / Kubernetes Secret, or your platform’s secret store). ENCRYPTION_KEY must also be set, and APP_HOST must point at the public URL of the web app, because the callback redirects the browser there after installation.
Private key formatting
The.pem file is multi-line. In a .env file, store it as a single line with literal \n escapes, wrapped in double quotes:
\n back into real newlines. In Kubernetes, you can instead mount the PEM contents as-is in a Secret value. If token requests fail with a key-parse error after deploying, the newlines did not survive your secret store.
4. Verify end to end
- Create a test repository containing a valid
.nt3.yml(runnt3 initlocally and commit it). Make suresource_languagematches the Entri project’s source language. - In Entri, go to Settings → Organization → GitHub → Connect GitHub and install the App on the test repository. You are redirected back with a success message.
- In Settings → Project → GitHub Sync, select the repository, set the branch, choose a mode, and save.
- Click Sync now and check:
- Commit mode: a new bot commit appears on the branch with the expected files.
- Pull request mode: an
nt3/sync-*branch and an open PR appear; re-running updates the same PR. - No changes: re-running reports “Up to date” without creating an empty commit or PR.
- Protected branch in commit mode: a clear error suggests using PR mode.
- Disconnect from the organization settings and confirm the connection is removed.
Common failures
Known limitations
- Sync is additive / overwrite-only: stale translation files are never deleted from the repository.
- Sync is triggered manually (no webhook or schedule yet).
- Importing from GitHub into Entri is not supported; use
nt3 pushfor that direction. - Commits show as Unverified, which is normal for GitHub App tokens.