GitHub authentication
Authenticate the GitHub provider with a token or a GitHub App.
The github provider from repo-sdk/github authenticates with either a token (classic/fine-grained PAT
or OAuth token) or GitHub App credentials, and supports GitHub Enterprise Server via baseUrl.
Token auth
Pass a token — a classic or fine-grained personal access token, or an OAuth token — and the SDK sends it
as a Bearer credential on every request.
import { createClient } from 'repo-sdk';
import { github } from 'repo-sdk/github';
const client = createClient({
provider: github({ auth: { token: process.env.GITHUB_TOKEN! } }),
});
token?string
Classic/fine-grained PAT or OAuth token, sent as Bearer.
stringGitHub App auth
Supply your app’s credentials and the SDK signs a short-lived RS256 JWT, resolves the installation, and mints (and caches/refreshes) an installation access token for you.
const client = createClient({
provider: github({
auth: {
appId: process.env.GITHUB_APP_ID!,
privateKey: process.env.GITHUB_APP_PRIVATE_KEY!,
installationId: process.env.GITHUB_INSTALLATION_ID, // optional — see below
},
}),
});
appId?string | number
The GitHub App id.
string | numberprivateKey?string
The app private key, PEM-encoded (PKCS#1 or PKCS#8).
stringinstallationId?string | number
The installation to act as. Optional for single-installation apps.
string | numberowner?string
Org or user whose installation to act as; alternative to installationId.
stringPrivate key formats
Both PEM encodings are accepted as-is — you do not need to convert between them:
- PKCS#8 —
-----BEGIN PRIVATE KEY----- - PKCS#1 —
-----BEGIN RSA PRIVATE KEY-----(the format GitHub downloads by default; the SDK wraps it in a PKCS#8 envelope internally)
Resolving the installation
installationId is optional. Without it, resolution depends on how many installations the app has:
| Installations | Behavior |
|---|---|
| exactly one | Omit installationId — the SDK auto-detects the single installation. |
| zero | Throws RepoError with code: 'unauthorized' (“not installed anywhere”). |
| more than one | Throws RepoError with code: 'validation' — pass installationId or owner. |
For apps installed on many accounts (multi-tenant), pass owner instead of a numeric installation id
and the SDK looks the installation up by account name — no need to store installation ids yourself:
github({
auth: {
appId: process.env.GITHUB_APP_ID!,
privateKey: process.env.GITHUB_APP_PRIVATE_KEY!,
owner: 'capawesome-team',
},
});
The lookup tries /orgs/{owner}/installation first and falls back to /users/{owner}/installation,
then caches the resolved id for the lifetime of the provider. If the app is not installed on that
account, a RepoError with code: 'not_found' is thrown. installationId and owner are mutually
exclusive — passing both throws a validation error.
Using the installation token outside the SDK
getInstallationToken() on the GitHub provider returns the current installation token (minting or
refreshing it on demand) together with its expiry, so the SDK can act as your single GitHub App token
manager — hand the token to the git CLI, Octokit, or any other tool:
const provider = github({ auth: { appId, privateKey, owner: 'capawesome-team' } });
const { token, expiresAt } = await provider.getInstallationToken();
// e.g. git clone https://x-access-token:<token>@github.com/owner/repo.git
The token is the same cached one the SDK uses for its own API calls. Under token auth the method
throws RepoError with code: 'unsupported'.
Scopes
Pick the token scope for what you’ll do.
Classic personal access tokens:
repo— required for repository read access (private and public) and for repository webhook management. For public repositories only,public_repocovers the reads — addadmin:repo_hookif you also manage webhooks.read:org— required to list organization namespaces.user:email— required only forusers.me({ includeEmail: true })when the account hides its public email.
Fine-grained personal access tokens (repository permissions unless noted):
- Metadata — read: the mandatory baseline; covers discovery, tags, branches, and ref search.
- Contents — read: required for commits, archive downloads, and clone access.
- Webhooks — read and write: required to create, update, or delete webhooks.
- Email addresses — read (an account permission): required for
users.me({ includeEmail: true }).
GitHub App auth uses the installation’s permissions rather than token scopes — grant the app the equivalent Contents (read), Metadata (read), and Webhooks (read and write) repository permissions.
GitHub Enterprise Server
Point baseUrl at your GHES API root (/api/v3). It applies to both token and GitHub App auth, and the
SDK derives the matching git host for clone URLs automatically.
github({
auth: { token: process.env.GITHUB_TOKEN! },
baseUrl: 'https://ghe.example.com/api/v3',
});
Discover repositories
List namespaces and repositories once you’re authenticated.
Expiring tokens
auth: { tokenProvider } mints the bearer token per request, with one forced-refresh retry on 401 —
see Expiring tokens for the contract.