Integrations

GitHub App permissions

GitHub App permissions are the granular scopes an installed GitHub App requests on a repository: contents (read source), pull requests (read+write), checks (write Check Runs), metadata (read repo info), etc. Each permission level (none / read / write / admin) controls what the App can do with that resource.

GitHub Apps vs OAuth Apps vs Personal Access Tokens

Three ways third-party tools authenticate to GitHub: OAuth Apps (act AS a user), GitHub Apps (act AS the app, on behalf of an installation), and Personal Access Tokens (act AS a user with a long-lived token).

GitHub Apps are the preferred modern path. They have granular permissions, short-lived installation tokens (1 hour), per-repo install scope, and audit-friendly per-app activity in the GitHub UI. OAuth Apps inherit the full scope of the user's GitHub account — typically far too broad for a tool that just needs to comment on PRs.

Apps require both a GitHub-side configuration (in the developer settings) and a per-customer installation. The user installs the App on their org/account, optionally scoped to specific repos, and the App then operates within that scope.

The permission model — granularity by resource

Each permission is a tuple of (resource, level). Resources include: actions, administration, checks, code-scanning, contents, deployments, environments, issues, members, metadata, packages, pages, pull-requests, repository-hooks, repository-projects, secret-scanning, secrets, statuses, vulnerability-alerts, workflows.

Levels: none (no access), read (GET-style), write (POST/PATCH/PUT), admin (DELETE + sensitive ops). Not every resource supports every level — some only have read; admin is rare.

The granularity is real. A code-review tool needs (contents: read, pull-requests: write, checks: write, metadata: read) — and nothing else. It can't access secrets, can't push code, can't manage members. The principle of least privilege applies aggressively here.

Webhook subscriptions — separate from permissions

Permissions control what the App can DO when it acts. Webhook subscriptions control what GitHub TELLS the App when things happen in the installed repos.

Common webhook events: pull_request (PR opened/closed/etc.), push (commit pushed), installation (App installed/uninstalled), installation_repositories (repos added/removed from install), check_run (CI run state changed), issues (issue opened/closed/commented).

Each subscription is opt-in per App. Most code-review tools subscribe to pull_request + push + installation events. Webhooks for things you don't need (members, issues, deployments) just add noise + processing cost — subscribe minimally.

Installation tokens — the runtime credential

When a GitHub App is installed on an org, GitHub issues an installation ID. The App can then exchange its private key (JWT-signed) for an installation token — a short-lived (1 hour) credential scoped to that installation's permissions on that installation's repos.

The flow per action: (1) App generates a JWT with its private key. (2) POST /app/installations/{installation_id}/access_tokens with JWT. (3) GitHub returns a token. (4) App uses that token for actual operations until expiry. (5) Refresh as needed.

Best practice: cache tokens in worker memory until expiry. Refresh proactively at the 55-minute mark to avoid 401s mid-operation. Never store installation tokens to disk — they're high-value secrets.

Auditing + reviewing App permissions

Installed App permissions are visible in github.com/settings/installations (for personal accounts) or github.com/organizations/{org}/settings/installations (for orgs).

Each install shows: which repositories the App can access, which permissions are granted, when it was installed, last activity. The org admin can revoke at any time.

Quarterly audit recommendation: walk every installed App, confirm the permissions match the stated function, revoke any not in active use. The github.com UI makes this 10-minute work per org.

GitHub also publishes the App's required permissions on the App's public listing (apps.github.com/lgtm-app, etc.). Read these BEFORE installing — if a 'PR comment bot' requests admin permission on contents, walk away.

Read LGTM's exact GitHub App permission set

Contents: read · PRs: write · Checks: write · Metadata: read · nothing else

Go to the product page

FAQs

What's the minimum set of permissions for a code-review GitHub App?

Typically four: (contents: read) — fetch the diff and indexed code. (pull-requests: write) — post review comments. (checks: write) — write Check Runs that branch protection can gate on. (metadata: read) — required by GitHub on every App, gets repo name + visibility. Plus webhook subscriptions to pull_request + push + installation events.

Can a GitHub App push code to my repo?

Only if you grant `contents: write` permission. Most code-review tools should NOT request this — they comment on PRs, they don't modify source. If an App asks for `contents: write` and isn't a deploy bot, ask why.

How long does an installation token live?

1 hour from issuance. Apps need to either refresh proactively (around 55 minutes) or accept occasional 401s and re-issue. Tokens are scoped to the specific installation — separate installations have separate tokens.

What's the difference between Personal Access Tokens (classic) and Fine-grained PATs?

Classic PATs grant scopes that apply to ALL repos your user can access. Fine-grained PATs (introduced 2022) are per-repo with GitHub-App-like granular permissions. For external-tool authentication, GitHub Apps are better than either PAT type — they don't expire as a function of the user's session, they have audit trails, and they don't break if the user leaves the org.

Can I limit a GitHub App's permissions AFTER installation?

Partially. You can change WHICH repositories the App has access to (add/remove individual repos or switch between 'all repos' and 'selected repos'). You can't change WHICH PERMISSIONS the App has on those repos — those are baked into the App's manifest by the App's developer. Update path: developer ships a new App version requesting fewer permissions; users re-confirm at installation.

How do I tell if an App is following least-privilege?

Read the App's listing page on github.com/apps. Check the permissions list. Cross-reference against the App's claimed functionality. A PR-comment bot needs PR write + Checks write + Contents read. If the bot asks for actions write or secrets read, dig deeper before installing.

Related across LGTM

Related terms