Skip to content
repo-sdk
Esc
navigateopen⌘Jpreview
On this page

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! } }),
});
PropType
token?string

Classic/fine-grained PAT or OAuth token, sent as Bearer.

Typestring

GitHub 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
    },
  }),
});
PropType
appId?string | number

The GitHub App id.

Typestring | number
privateKey?string

The app private key, PEM-encoded (PKCS#1 or PKCS#8).

Typestring
installationId?string | number

The installation to act as. Optional for single-installation apps.

Typestring | number
owner?string

Org or user whose installation to act as; alternative to installationId.

Typestring

Private 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_repo covers the reads — add admin:repo_hook if you also manage webhooks.
  • read:org — required to list organization namespaces.
  • user:email — required only for users.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.

Was this page helpful?