OAuthseus

GitHub (OAuth Apps and GitHub Apps)

Curated guide, researched and checked, updated 2026-10-30 · github.com

Download Markdown
Easy

15-45 minutes to register and test; no GitHub review to go public. Marketplace listing (optional) adds an unpublished-length review, reportedly 2-6 weeks.

GitHub has no app review for going public: you can register a GitHub App (recommended) or an OAuth App in minutes and any GitHub user can connect immediately. The real friction is on your users' side: organization owners must install a GitHub App on their org, or approve an OAuth App when OAuth app access restrictions are on (the default for new orgs). Only a GitHub Marketplace listing involves a GitHub review, and paid plans additionally need a verified-publisher organization and 100+ installs.

How long until your users can connect

Depends on who connects and what you ask for
Your work: 20–60 minWaiting on provider: noneUsers can connect

No GitHub approval is needed to register an app or make a GitHub App public. A GitHub review happens only if you submit a GitHub Marketplace listing (an onboarding expert reviews it; GitHub publishes no timeline). Separately, each customer organization's owner must install your GitHub App, or approve your OAuth App if OAuth app access restrictions are enabled; that wait depends on the customer, not GitHub.

Choose your launch path to filter the steps

Do these first

  1. 1Decide GitHub App (default) vs OAuth App; list exactly which repo/org permissions your agent needs
  2. 2Register a private GitHub App ("Only on this account") with a localhost callback and Device Flow if you ship a CLI
  3. 3Implement PKCE web flow or device flow plus 8-hour token refresh, and test end-to-end on your own account
  4. 4Switch to "Any account", add production callback URLs, and publish your install link with an org-owner help note
  5. 5Only if you want discovery or GitHub billing: prepare Marketplace assets and webhooks, then request publish

What you're actually registering

GitHub App (recommended) or OAuth App, registered under a personal account or organization in Developer settings. One GitHub App registration represents your agent product. Customers 'install' it on their user or org account and choose which repositories it can reach; each installation yields short-lived installation access tokens (app acting as itself). When a user 'authorizes' it, you get a user access token that can only reach resources both the user and the app installation can access. An OAuth App instead has no installation concept: each user authorization yields a scope-limited token acting as that user across everything they can see (subject to org approval).

GitHub App user access tokens expire after 8 hours with a refresh token valid 6 months (option "Expire user authorization tokens", on by default; strongly recommended). Using a refresh token invalidates it and the old access token. Installation access tokens expire after 1 hour and are minted with a JWT signed by the app's private key (keys never expire; up to 25 per app). OAuth Apps now also offer expiring tokens (8h / 6-month refresh) via "Expire user access tokens", enabled by default on new registrations; otherwise OAuth tokens live until revoked. The `scope` parameter grants nothing to a GitHub App; permissions come from the app registration. Authorization codes expire after 10 minutes.

What you'll need

  • GitHub account (personal or organization owner)

    Register under your personal account or under an org you own (or where you are a GitHub App manager). Each account can register up to 100 GitHub Apps and up to 100 OAuth Apps. For a product, register under an organization so the app survives staff changes and is eligible for paid Marketplace plans.

  • Globally unique app name (max 34 characters)

    GitHub App names must be unique across GitHub and cannot match an existing account name unless it is your own. The slug (lowercased, spaces to '-') appears in the UI when the app acts.

  • Homepage URL

    Required. If you lack a site, a public repository URL or the owning account URL is acceptable.

  • Callback URL(s) (web flow) or Device Flow enabled (CLI/headless agents)

    Both GitHub Apps and OAuth Apps accept up to 10 callback URLs; pass `redirect_uri` to choose one, otherwise the first is used. Optional wildcard matching for subdomains/subdirectories exists but is a security risk. Headless agents should enable Device Flow (no callback or client secret needed).

  • Minimum permissions (GitHub App) or scopes (OAuth App)

    Pick Read-only / Read & write / No access per permission. Changing permissions later forces every installation owner to re-approve, so get them right before going public.

  • Private key (GitHub App) and client secret

    Generate a private key (PEM, PKCS#1) to sign JWTs for installation tokens; generate a client secret for the web flow token exchange. Store both in a secrets manager.

  • Org owner action at each customer organization

    GitHub App: only an org owner or repo admin can install (members can request). OAuth App: if OAuth app access restrictions are enabled, an org owner must approve the app before members' tokens can reach org resources. Restrictions are on by default for new orgs.

  • Marketplace listing assets and policies

    Publisher contact info, description, pricing plan, valid privacy policy link, support link or email, logo, feature card and screenshots, Marketplace plan-change webhooks, and value beyond authentication. Only org owners (not GitHub App managers) can submit org-owned listings.

  • Publisher verification (paid plans or Marketplace badge only)

    App must be owned by an organization; org needs accurate profile and email, org-wide two-factor authentication required, and a verified domain with a 'Verified' badge on the org profile.

  • Install / user thresholds for paid plans

    Paid apps: GitHub Apps should have at least 100 installations; OAuth Apps at least 200 users. Must handle Marketplace purchase events (new, upgrade, downgrade, cancel, free trial) and support monthly and annual billing.

Step by step

10 steps
  1. 1

    Decide: GitHub App (default) vs OAuth App

    About 5–15 min

    An agent can do this

    Pure decision; an agent can apply this rubric to your product requirements.

    1. Pick a GitHub App unless you need enterprise-level resources (the enterprise object itself), which only OAuth Apps can be granted.
    2. GitHub App advantages for an AI agent: fine-grained permissions (e.g. read-only contents instead of `repo`), users choose specific repositories, expiring tokens, rate limits that scale with installations, a built-in webhook, and no dependency on org OAuth app policies.
    3. Decide whether the agent acts as the user (user access token via web or device flow), as itself (installation token via private key + JWT), or both. Agents that open PRs as a bot use installation tokens; agents that act 'as you' use user access tokens.
    4. For CLI or terminal agents without a browser redirect, plan to use the device flow.
  2. 2

    Open Developer settings > GitHub Apps

    About 1–3 min

    You do this

    Requires your GitHub login (and org owner rights if registering under an org).

    1. Click your profile picture (upper-right) and click "Settings". For an org-owned app: "Your organizations" > "Settings" next to the org.
    2. In the left sidebar click "Developer settings", then "GitHub Apps".
    3. Click "New GitHub App".
    Registering a GitHub AppPointer ready: highlights “Developer settings”
  3. 3

    Fill in the New GitHub App form

    About 10–25 min

    Agent prepares, you submit

    An agent can draft every value (name, URLs, permission list); you paste them while logged in and click create.

    1. "GitHub App name": unique, 34 characters max.
    2. "Homepage URL": your product site (or repo URL).
    3. "Callback URL": your OAuth redirect (e.g. https://yourapp.com/auth/github/callback). Click "Add callback URL" to add a localhost dev URL too (up to 10 total).
    4. Leave "Expire user authorization tokens" selected (8h tokens + 6-month refresh tokens).
    5. Select "Request user authorization (OAuth) during installation" if you want the install and user login to happen in one hop (this disables "Setup URL").
    6. Select "Enable Device Flow" for CLI/terminal agents.
    7. Webhooks: deselect "Active" if the agent does not react to events; otherwise set "Webhook URL" and a "Webhook secret" and keep SSL verification enabled.
    8. "Permissions": set only what the agent needs (e.g. Repository > Contents: Read-only, Issues: Read & write).
    9. "Where can this GitHub App be installed?": "Only on this account" for testing, "Any account" to let customers connect.
    10. Click "Create GitHub App". Note the App ID and Client ID shown on the settings page.
    Callback URL
    https://YOUR_DOMAIN/auth/github/callback
    Add http://localhost:3000/auth/github/callback as a second URL for development.
    Expire user authorization tokens
    checked
    GitHub strongly recommends leaving this on.
    Where can this GitHub App be installed?
    Any account
    Use 'Only on this account' while testing.
  4. 4

    Generate a client secret and a private key

    About 3–10 min

    You do this

    Secrets are shown/downloaded once in your logged-in browser; store them yourself (an agent can then wire them into env vars).

    1. Developer settings > GitHub Apps > click "Edit" next to your app.
    2. Under the app's credentials, generate a client secret (needed for the web flow code exchange; not needed for the device flow) and copy it immediately.
    3. In the left sidebar click "Key pairs", then "New key". A PEM file downloads; GitHub keeps only the public half.
    4. Store Client ID, client secret, App ID and the PEM in your secrets manager. Keep at least two keys if you want zero-downtime rotation (max 25).
    Managing private keys for GitHub AppsPointer ready: highlights “Edit”
  5. 5

    (OAuth App path) Register a new OAuth App

    About 5–10 min

    Agent prepares, you submit

    Agent drafts the values; you submit while logged in.

    1. Settings > "Developer settings" > "OAuth apps" > "New OAuth App" (shows "Register a new application" if you have never created one).
    2. Fill "Application name", "Homepage URL", optional "Application description" and "Authorization callback URL". Click "Add callback URL" for more (up to 10).
    3. Check "Enable Device Flow" for CLI agents.
    4. "Expire user access tokens" is enabled by default; leave it on and implement refresh, or uncheck only if your code cannot handle refresh yet.
    5. Click "Register application", then generate a client secret on the app page.
    6. Only use information you consider public in the registration.
    Authorization callback URL
    https://YOUR_DOMAIN/auth/github/callback
    Creating an OAuth appScopes for OAuth appsPointer ready: highlights “OAuth apps”
  6. 6

    Implement the user authorization flow (web flow with PKCE, or device flow)

    About 1–4 hours

    An agent can do this

    Pure code work; a coding agent can implement and unit-test this with your client ID/secret in env vars.

    1. Web flow: redirect to https://github.com/login/oauth/authorize with client_id, redirect_uri, a random state, and PKCE code_challenge (S256 only; 'plain' unsupported). Exchange the code (valid 10 minutes) at POST https://github.com/login/oauth/access_token.
    2. Device flow: POST https://github.com/login/device/code with client_id; show user_code and https://github.com/login/device; poll POST https://github.com/login/oauth/access_token at the returned interval (default 5s). Codes expire after 900 seconds. A slow_down error adds 5 seconds to the interval. No client secret needed.
    3. Store refresh_token (ghr_ prefix) and expires_in (28800s). Refresh before expiry; each refresh rotates both tokens, so persist the new pair atomically.
    4. For GitHub App bot actions: sign a JWT with the private key, then create an installation access token (1-hour lifetime) per installation.
    5. Do not send `scope` for GitHub Apps except `offline_access`; permissions come from the app registration.
  7. 7

    Make the GitHub App public and share the install link

    About 2–5 min

    You do this

    Requires your logged-in session on the app's settings page.

    1. If you registered with "Only on this account", open the app settings ("Edit") > "Advanced" and change visibility to public. No review is triggered.
    2. Share https://github.com/apps/YOUR-APP-SLUG (landing page with an "Install" button) or https://github.com/apps/YOUR-APP-SLUG/installations/new.
    3. Tell org customers that an org owner (or repo admin for selected repos) must click "Install" and choose "All repositories" or selected ones.
    Making a GitHub App public or privateModifying a GitHub App registrationPointer ready: highlights “Edit”
  8. 8

    Get org access at each customer organization

    About 5–15 min

    You do this

    Must be done by the customer's org owner in their own GitHub session; neither you nor an agent can do it for them.

    1. GitHub App: an org owner installs it from the app's landing page; members can only request installation.
    2. OAuth App with restrictions on: the member first authorizes the app for their personal account, then goes to Settings > "Applications" > "Authorized OAuth Apps" tab > app > "Request access" next to the org > "Request approval from owners".
    3. The org owner approves at Org Settings > "Third-party Access" > "OAuth app policy" > "Review" > "Grant access".
    4. Provide customers a short help article with these exact steps.
    Approving OAuth apps for your organizationRequesting organization approval for OAuth appsPointer ready: highlights “Authorized OAuth Apps”
  9. 9

    (Paid Marketplace only) Request publisher verification

    About 30–120 min

    You do this

    Org owner must enable org 2FA, verify a domain via DNS, and click Request Verification.

    1. Transfer the app to an organization if it is personally owned.
    2. Org Settings > "Developer settings" > "Publisher Verification".
    3. Complete the checklist: accurate profile and email, org two-factor authentication required, verified domain showing a 'Verified' badge.
    4. Click "Request Verification" and wait for GitHub to notify you (no published timeline).
    Applying for publisher verificationVerifying a domain for your organizationPointer ready: highlights “Developer settings”
  10. 10

    (Marketplace) Draft the listing and request publish

    About 4–16 hours

    Agent prepares, you submit

    Agent can write the description, pricing copy and plan-change webhook handler; you upload images, accept the Developer Agreement and submit.

    1. App must be public. On the app settings page scroll to the Marketplace section and click "List in Marketplace" (or go to https://github.com/marketplace/new and click "Create draft listing").
    2. Complete contact info, description, logo, feature card, screenshots, privacy policy link, support link/email and at least one pricing plan.
    3. Implement Marketplace webhook events for plan changes and cancellations.
    4. On the listing "Overview", accept the GitHub Marketplace Developer Agreement and click "Request publish" (some doc pages call it "Submit for review").
    5. An onboarding expert contacts you; respond promptly to their questions.

What can block you, and the way around

  • Users can sign in but the agent cannot see org repositories (OAuth App)

    You'll see: API calls for org private repos return 404/403 or empty lists; webhooks from org private repos stop arriving.

    Do this: The org has OAuth app access restrictions enabled (default for new orgs). Ask the user to click "Request access" for the org under Settings > Applications > Authorized OAuth Apps, and have an org owner grant access under "OAuth app policy". Long-term: switch to a GitHub App, which is not subject to org application policies.

  • GitHub App user token cannot access a repo the user clearly can

    You'll see: User access token returns 404 for a repo the user owns or belongs to.

    Do this: User access tokens only reach resources both the user and the app can access. The app must be installed on that account/org and the repo included in the installation. Send the user to https://github.com/apps/YOUR-SLUG/installations/new.

  • Org members cannot install your GitHub App

    You'll see: Non-owner members only see a 'request' option; installation stalls waiting on an org owner.

    Do this: Only org owners (or repo admins for their repos) can install. Give customers an owner-facing install link and explanation of the minimal permissions requested.

  • Tokens suddenly invalid after 8 hours, or refresh fails

    You'll see: 401 Bad credentials after ~8 hours; refresh requests fail after a refresh token was already used once.

    Do this: Expiring tokens are on by default. Refresh with grant_type=refresh_token before expiry and atomically persist the new access + refresh token; each refresh token is single-use. Refresh tokens expire after 6 months, after which the user must re-authorize.

  • redirect_uri mismatch

    You'll see: GitHub shows a redirect_uri mismatch error instead of the consent screen.

    Do this: Register every environment's callback (up to 10) and pass the matching redirect_uri explicitly; without it GitHub uses the first registered URL. Avoid wildcard matching unless you control every subdomain/path.

  • Device flow errors: device_flow_disabled or slow_down

    You'll see: Polling returns device_flow_disabled, or repeated slow_down errors.

    Do this: Tick "Enable Device Flow" in app settings; respect the returned interval (default 5s) and add 5s after each slow_down. Restart the flow after 900 seconds.

  • Rate limits hit by an agent doing many API calls

    You'll see: 403/429 with x-ratelimit-remaining: 0, or secondary rate limit errors when creating content quickly.

    Do this: User tokens share the user's 5,000 req/hour; installation tokens start at 5,000/hour and scale with repos and users (15,000 on GitHub Enterprise Cloud). Prefer installation tokens for bulk work, use conditional requests, and keep content creation under 80/minute and 500/hour.

  • Paid Marketplace listing blocked

    You'll see: Cannot add a paid plan or request verification.

    Do this: Transfer the app to an organization, require 2FA for the org, verify a domain, complete Publisher Verification, and reach 100 installations (GitHub App) / 200 users (OAuth App). Launch as a free listing or off-Marketplace first.

What we checked

0 tested 34 documented 0 inferred 1 unverified
  • CorrectedOAuth Apps allow only one callback URL (commonly repeated advice)Current 'Creating an OAuth app' doc says you can enter up to 10 callback URLs via 'Add callback URL'. The older 'GitHub Apps allow multiple, OAuth Apps one' distinction no longer holds; both allow up to 10.Read against official docs, 2026-10-30
  • CorrectedOAuth App tokens never expire'Creating an OAuth app' now shows 'Expire user access tokens' enabled by default (8h access token, 6-month refresh token). The 'Deciding when to build a GitHub App' page still states OAuth tokens do not expire until revoked, so GitHub's own docs are inconsistent; existing apps keep long-lived tokens unless switched.Read against official docs, 2026-10-30
  • CorrectedGitHub App private key generated via 'Generate a private key' buttonCurrent docs describe app settings sidebar 'Key pairs' > 'New key' within a 'Credentials' section; the older single 'Generate a private key' button wording is outdated.Read against official docs, 2026-10-30
  • ConfirmedGitHub App user tokens expire after 8 hours with 6-month refresh tokensRefreshing user access tokens: expires_in always 28800, refresh_token_expires_in 15897600; 'Expire user authorization tokens' strongly recommended. The page also labels expiring tokens as an optional feature subject to change.Read against official docs, 2026-10-30
  • ConfirmedNo GitHub review required to make a GitHub App publicMaking a GitHub App public or private and Registering a GitHub App describe visibility as a setting with no review; only Marketplace listing involves an onboarding expert review.Read against official docs, 2026-10-30
  • ConfirmedOrg owners must approve OAuth appsOnly when OAuth app access restrictions are enabled, which is the default for new organizations. Orgs without restrictions let any member-authorized OAuth app access private org resources. GitHub Apps are not subject to these policies but require owner/admin installation.Read against official docs, 2026-10-30
  • CorrectedMarketplace verification required for all listingsPublisher verification is only required for paid plans or the Marketplace badge; free listings need only the general listing requirements. Paid apps also need 100 installs (GitHub App) / 200 users (OAuth App).Read against official docs, 2026-10-30
  • ConfirmedPKCE support in GitHub web flowGenerating a user access token lists code_challenge / code_challenge_method as strongly recommended; only S256 supported.Read against official docs, 2026-10-30
  • Couldn't verifyMarketplace review timelineSubmitting your listing for publication says only that an onboarding expert will reach out; no duration published. Community range 2-6 weeks recorded as unverified.Read against official docs, 2026-10-30
  • ConfirmedAutomated: developer console (https://github.com/settings/developers)Console is live and sits behind sign-in: redirected to github.com ("Sign in to GitHub · GitHub"). An agent cannot go further without your account.Live HTTP probe, 2026-10-30
  • ConfirmedAutomated: authorize endpoint with a fake client_id (https://github.com/login/oauth/authorize)Endpoint is live; responded 302 redirecting to github.com (usually sign-in before client validation).Live HTTP probe, 2026-10-30
  • ConfirmedAutomated: 34 quotes re-fetched and matched against their cited pages34 of 34 quotes found verbatim in the live page HTML. 21/21 source URLs returned HTTP 200.Read against official docs, 2026-10-30

What we couldn't confirm

  • GitHub publishes no review timeline for Marketplace listings or publisher verification; the 2-6 week range is community-reported (unverified), and a 2018 GitHub blog post cited ~2 weeks.
  • Exact current button label for generating a client secret on a GitHub App settings page (we used 'Generate a new client secret') is not stated in the docs we read; private-key labels are now 'Key pairs' > 'New key'.
  • Marketplace submit button label differs across docs: 'Request publish' (Submitting your listing) vs 'Submit for review' (Drafting a listing).
  • The 'Advanced' page location for changing GitHub App visibility is inferred from Modifying a GitHub App registration; the exact control label was not captured.
  • Refresh token lifetime: GitHub App docs say six months; OAuth App docs say six months 'without use'. Whether GitHub App refresh tokens are also use-based was not confirmed.
  • The 'Deciding when to build a GitHub App' page still says OAuth app tokens do not expire until revoked, while the OAuth App creation page says expiring tokens are enabled by default for new apps; behavior for existing OAuth Apps is opt-in.

Sources

  1. s1Creating an OAuth app (official docs, accessed 2026-10-30)
  2. s2Registering a GitHub App (official docs, accessed 2026-10-30)
  3. s3Differences between GitHub Apps and OAuth apps (official docs, accessed 2026-10-30)
  4. s4Deciding when to build a GitHub App (official docs, accessed 2026-10-30)
  5. s5Refreshing user access tokens (official docs, accessed 2026-10-30)
  6. s6About the user authorization callback URL (official docs, accessed 2026-10-30)
  7. s7Authorizing OAuth apps (official docs, accessed 2026-10-30)
  8. s8Generating a user access token for a GitHub App (official docs, accessed 2026-10-30)
  9. s9About OAuth app access restrictions (official docs, accessed 2026-10-30)
  10. s10Approving OAuth apps for your organization (official docs, accessed 2026-10-30)
  11. s11Requesting organization approval for OAuth apps (official docs, accessed 2026-10-30)
  12. s12Making a GitHub App public or private (official docs, accessed 2026-10-30)
  13. s13Rate limits for the REST API (official docs, accessed 2026-10-30)
  14. s14About GitHub Marketplace for apps (official docs, accessed 2026-10-30)
  15. s15Requirements for listing an app (official docs, accessed 2026-10-30)
  16. s16Applying for publisher verification for your organization (official docs, accessed 2026-10-30)
  17. s17Submitting your listing for publication (official docs, accessed 2026-10-30)
  18. s18Navigating GitHub Marketplace App Submissions: Understanding Review Timelines and Support (DevActivity) (community, accessed 2026-10-30)
  19. s19GitHub Marketplace one year after release (GitHub Blog, Japanese, 2018) (official blog, accessed 2026-10-30)
  20. s20Drafting a listing for your app (official docs, accessed 2026-10-30)
  21. s21Managing private keys for GitHub Apps (official docs, accessed 2026-10-30)
  22. p1Live probe (console): Console is live and sits behind sign-in: redirected to github.com ("Sign in to GitHub · GitHub"). An (probe, accessed 2026-10-30)
  23. p2Live probe (authorize-endpoint): Endpoint is live; responded 302 redirecting to github.com (usually sign-in before client validation) (probe, accessed 2026-10-30)