GitHub Connection
Venelx clones your repo, reads commit metadata, and receives webhooks through a GitHub App OAuth flow. This page explains how connecting works, why you rarely need to think about tokens, and what to do when GitHub starts rejecting them.
How connecting works
- In the dashboard, go to Account → GitHub and click Connect GitHub.
- You're redirected to GitHub, where you authorize the Venelx GitHub App and choose which repositories it can access (all repos, or a selected set).
- GitHub redirects back to the API callback
(
https://api.venelx.com/api/github/callback), and Venelx stores the resulting user token plus a refresh token against your account.
From then on, builds and project imports use this connected identity automatically.
Token lifecycle — renewed silently
GitHub App user tokens expire after 8 hours. You don't have to re-authorize:
- Venelx stores the OAuth refresh token returned at connect time.
- Before an expiring token is used — and on a background sweeper that runs every 30
minutes (
GITHUB_TOKEN_SWEEP_INTERVAL_MINUTES) — the API exchanges the refresh token for a fresh user token and saves it. - This is invisible to you: builds keep cloning, webhooks keep flowing.
reconnect_required
If the stored refresh token itself stops working — you revoked the app on GitHub,
uninstalled it from the org, changed credentials, or GitHub invalidated the grant — the
API can no longer renew the token. The account flips to reconnect_required:
- The dashboard shows a one-click Reconnect CTA (banner / Account → GitHub).
- Clicking it replays the same OAuth flow and stores a fresh token + refresh token.
- Until you reconnect, operations that need GitHub (new builds, repo listing) fail with a token error.
Reconnecting takes seconds and does not change project settings, env vars, or signing — it only re-establishes the OAuth grant.
Credential priority
When Venelx needs a GitHub credential (cloning on a worker, API-side repo calls), it resolves one in this order:
- Project env —
GITHUB_TOKEN(orGH_TOKEN/GITHUB_PAT/GIT_TOKEN) set on the project. - Connected account — the OAuth user token from your connected GitHub account (auto-refreshed as above).
- Team secret — a token stored as a team-level secret.
- Server env —
GITHUB_TOKENon the API/worker process (last resort).
GITHUB_USER (any level) sets the git username paired with those tokens — default
x-access-token.
The first match wins, so a project-level PAT overrides the connected account for that
project only, and the connected account overrides team/server fallbacks everywhere else.
The MCP github_access tool reports which source a project resolves to
and whether it works.
Troubleshooting — "GitHub token rejected (HTTP 401)"
A 401 from GitHub means the credential Venelx presented was refused. Common causes and fixes:
| Cause | Why it happens | Fix |
|---|---|---|
| Expired token | GitHub App user tokens live 8h; if renewal also failed, the account is stale | Use the Reconnect CTA in the dashboard (one click) |
| Revoked / uninstalled app | The OAuth grant was revoked on GitHub, or the app was uninstalled from the org | Reconnect, and re-install the app for the org/repos when prompted |
| SSO-unauthorized PAT | A personal access token used against a SAML-SSO org must be explicitly authorized for that org | On GitHub → the PAT → Configure SSO → authorize for your organization |
| Wrong scopes | Classic PATs need repo (contents read) for private repos; fine-grained PATs need Contents: read on the repo | Re-mint the PAT with the right scopes and update the project env / team secret |
| Token typo / rotation | The stored PAT no longer exists (rotated, deleted) | Set a fresh token in the project env or team secret |
Quick diagnosis without the dashboard:
- MCP: the
github_accesstool returnsgithubAccess {ok, reason, message}plus the auth source label for a project. trigger_buildsurfacesskipReason: github_token_invalidwhen a build can't start because of GitHub auth.
GITHUB_* environment variables
Server-side variables (on the API; OAuth client fields also on a local worker that runs OAuth-dependent steps):
| Variable | Where | Purpose |
|---|---|---|
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET | API + local worker | OAuth app credentials — also used for the token refresh grant |
GITHUB_OAUTH_MODE | API | github_app (default) or oauth_app |
GITHUB_OAUTH_CALLBACK_URL | API | Must match the callback URL in the GitHub App settings (https://api.venelx.com/api/github/callback) |
GITHUB_APP_SLUG | API | Detects app install + permission approval |
GITHUB_OAUTH_SCOPES | API | Only for oauth_app mode (default repo user:email) |
GITHUB_TOKEN_SWEEP_INTERVAL_MINUTES | API | Proactive token-renewal sweep interval (default 30) |
GITHUB_TOKEN / GH_TOKEN / GITHUB_PAT / GIT_TOKEN | project env → team secret → server env | Clone credentials, resolved in priority order |
GITHUB_USER | any of the above | Git username paired with those tokens (default x-access-token) |