Join our Newsletter — 33% off our NHI Course
Home› Guides› GitHub Personal Access Tokens Security Guide: Fine-Grained Tokens,…
Guide Non-Human Identity (NHI)

GitHub Personal Access Tokens Security Guide: Fine-Grained Tokens, Expiry and Org Policies

PDF for newsletter subscribers · free to read online

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 26 October 2026 12 min read
On this page

GitHub personal access tokens let scripts, tools and integrations act with a user's permissions, and a single leaked token has repeatedly been enough to poison widely used software. Classic tokens can reach every repository a user can access across every organisation they belong to, and by default they never need to expire. GitHub now offers fine-grained tokens, organisation approval, maximum lifetime policies and token-level audit fields, but most of these controls are off, permissive or optional until an owner configures them. This guide explains how both token types work, which organisation and enterprise settings matter, how to detect token misuse and what a hardened baseline looks like. It is written for GitHub organisation and enterprise owners, platform engineers and security teams responsible for source code and CI/CD.

Key takeaways

  • Fine-grained tokens are the default choice for people, scoped to one resource owner, selected repositories and specific permissions, with a 366-day maximum lifetime by default at organisation level.
  • Classic tokens are the main risk: they span all of a user's organisations and repositories, have no expiry requirement by default and are not subject to approval, so restrict them unless a documented gap requires them.
  • Organisation policies do the real work: restrict classic tokens, keep approval required for fine-grained tokens and set maximum lifetimes for both types.
  • Automation should not run on a person's token. GitHub recommends GitHub Apps for long-lived integrations because they use short-lived tokens and do not depend on a user who may leave.
  • Every token action can be traced: the audit log records a SHA-256 hashed_token field, so a leaked token's activity can be scoped quickly once you hash it.

How identity and access work in GitHub

A personal access token (PAT) authenticates as the user who created it. It is used with the REST and GraphQL APIs and for Git over HTTPS (not SSH remotes). GitHub tells users to "treat your access tokens like passwords" and to prefer GitHub CLI or Git Credential Manager over creating a token at all. Tokens carry recognisable prefixes, which is what makes secret scanning and the revocation API effective.

PrefixCredentialBound toTypical lifetime
ghp_Personal access token (classic)A user, all their organisations and repositories, by OAuth scopeOptional expiry; revoked after one year unused
github_pat_Fine-grained personal access tokenA user, one resource owner, selected repositories, specific permissionsUser-selected, default 30 days; capped by policy
gho_OAuth app access tokenA user's authorisation of an OAuth appUntil revoked
ghu_ / ghr_GitHub App user access token and refresh tokenA user, through a GitHub AppEight hours by default, renewed with the refresh token
ghs_GitHub App installation access tokenThe app installation, not a personShort-lived

GitHub is rolling out a new stateless ghs_ format from 27 April 2026, so any tooling that validates token length or pattern should be checked.

Fine-grained versus classic tokens

PropertyFine-grainedClassic
ScopeOne user or organisation; all or selected repositories; per-permission read or writeBroad OAuth scopes such as repo, across all organisations the user belongs to
Organisation approvalRequired by default; pending tokens can read only public resourcesNot available
Organisation visibility and revocationOwners can list and revoke themOwners cannot list or revoke them in the token UI
ExpiryDefault 30 days at creation; organisation maximum 366 days by defaultNo requirement by default
SAML SSOAuthorised during creationMust be authorised per organisation with Configure SSO
Per-user limitUp to 50 tokensNot stated
Known gapsCannot contribute to public repositories where the user is not a member, act as an outside collaborator, span several organisations, access Packages or call the Checks APICovers these cases

Decision guidance: use a fine-grained token for any personal scripting against your own organisation. Use a classic token only for the documented gaps above, with a short expiry and an exception record. Use a GitHub App for anything that runs unattended, and the built-in GITHUB_TOKEN inside GitHub Actions. See the GitHub and GitHub Actions Security Guide.

Admin roles and privileged access

  • Organisation owners: set the organisation's token policy (Settings, Personal access tokens), approve or deny fine-grained token requests, and list and revoke active fine-grained tokens. Tokens created by owners are approved automatically, so owner accounts deserve the strongest protection.
  • Enterprise owners (GitHub Enterprise Cloud): can restrict or allow each token type for all organisations, require or disable approval enterprise-wide, and set maximum lifetimes that organisations may only tighten. Enterprise-level restrict and allow choices cannot be overridden by organisations.
  • Enterprise Managed Users: enterprise lifetime policies also apply to user namespaces because the enterprise owns those accounts. GitHub warns that setting a lifetime policy may interrupt services unless administrators are exempted.
  • Administrator exemption: the enterprise lifetime setting can exempt enterprise administrators. Treat this as an exception that needs a reason, because administrator tokens are the most valuable to steal.
  • Review delegation: GitHub's documentation describes token request review as an owner task; the REST endpoints for listing, reviewing and revoking fine-grained tokens can be called only by GitHub Apps, which lets you automate review without handing out owner rights to a person.

Keep the owner count small, enforce phishing-resistant MFA on owner accounts and review owner membership quarterly. See the Privileged Access Management Guide.

Integrations, API tokens and service accounts

The most common PAT failure is not a careless person but an integration built on a person's token. GitHub's own guidance explains why that is fragile: a PAT is tied to a user, so automation breaks or keeps working on borrowed authority when that user changes role or leaves. A GitHub App installed on an organisation does not depend on any user, does not consume a seat, uses fine-grained permissions and receives short-lived installation tokens.

Use caseRecommended credentialWhy
Workflow in the same repositoryGITHUB_TOKEN with minimal permissions:Created per job and expires with it
Workflow touching other repositories or organisationsGitHub App installation tokenShort-lived, scoped, not tied to a person
Third-party SaaS integrationGitHub App from the vendorOwner-visible installation with explicit permissions
Deploying to cloud from ActionsOIDC federation to the cloud providerRemoves stored cloud keys entirely
Personal scripting and API testingFine-grained PAT, short expiry, selected repositoriesGitHub suggests PATs for testing and short-lived scripts
"Machine user" with a PATAvoid; migrate to a GitHub AppShared password-equivalent with no natural owner

Where a token must exist, store it in a secrets manager or Actions or Codespaces secrets, never in code, issue one token per integration so it can be revoked alone, and record an owner. Be especially careful with tokens stored as repository secrets in workflows triggered by pull_request_target, which can expose secrets to code from forks. A maintainer's PAT stored that way in a SpotBugs workflow was the starting point of the SpotBugs token leak that led to the reviewdog and tj-actions compromises. See the OWASP CI/CD Top 10 CICD-SEC-4 Poisoned Pipeline Execution Guide.

Logging and detection

For actions performed outside the web UI, the audit log records token details: hashed_token (the SHA-256 hash of the token, base64 encoded), programmatic_access_type and token_scopes. When a token leaks, hash the value locally (GitHub documents openssl dgst -sha256 -binary piped to base64), then search hashed_token:"VALUE" in the audit log UI or via the phrase parameter of GET /orgs/{org}/audit-log. UI and API searches do not return Git events, so export the log to review clone and push activity.

What to watchSourceWhy
Changes to auto-approval of token requests (auto_approve_personal_access_token_requests.enable and .disable)Organisation audit logTurning off approval silently widens access
Token activity from unexpected IP ranges or at unusual volumeAudit log streamed to SIEM, filtered by hashed_token and programmatic_access_typeStolen tokens are used from attacker infrastructure
Mass clone or archive download by one tokenExported Git eventsTypical of source code theft
Workflow file changes, new releases and tag moves by a bot or personal tokenAudit log and repository eventsTypical of supply chain compromise
Push protection bypassesSecurity alerts, audit log, owner emailA secret was knowingly committed
Pending fine-grained token requestsDaily owner email and pending requests listUnreviewed requests stall work or get rubber-stamped

Prevention at the edge: user push protection is enabled by default and blocks pushing secrets to public repositories; repository push protection requires GitHub Secret Protection and is off until enabled. It covers command line pushes, web commits, uploads and REST API requests, and every bypass creates an alert and an audit entry. See the Git Secret Scanning Guide.

Metrics

  • Number of classic tokens able to access the organisation (target zero once classic access is restricted).
  • Percentage of active fine-grained tokens with expiry of 90 days or less.
  • Number of integrations running on personal tokens versus GitHub Apps.
  • Median time from secret scanning alert on a GitHub token to revocation.
  • Push protection bypasses per month, by reason.

Hardening baseline

SettingDefaultRecommended
Classic token access to organisationAllowedRestrict, with exceptions handled through a GitHub App or a temporary policy change
Fine-grained token accessAllowedAllow
Require approval of fine-grained tokensRequiredKeep required; automate triage with a GitHub App calling the review endpoints
Fine-grained maximum lifetime366 days90 days or less for most organisations; shorter for write access to production code
Classic maximum lifetimeNoneSet one (for example 30 days) even if classic access is restricted, as a backstop
Repository push protectionOffEnable at organisation or enterprise level with delegated bypass
SAML SSONot configuredEnforce, so tokens need a linked identity and revoking it cuts access

Two behaviours matter when you tighten policy. First, setting a maximum lifetime "does not revoke or disable" existing tokens: non-compliant tokens owned by members are blocked from the organisation and users discover it when API calls fail. Second, restricting tokens does not disable SSH keys that were created with them. Plan communications and an SSH key review accordingly.

Rolling out the baseline

  1. Inventory: list fine-grained tokens with organisation access, export audit log entries with programmatic_access_type for 90 days to find classic token and OAuth usage, and identify integrations running on personal tokens.
  2. Migrate automation: move CI and integrations to GITHUB_TOKEN, GitHub Apps or OIDC before touching policy.
  3. Pilot: apply lifetime limits and classic restriction in a test organisation or a low-risk organisation first and watch for rejected API calls.
  4. Announce and enforce: give a dated notice, then set fine-grained maximum lifetime, a classic maximum lifetime and finally restrict classic access.
  5. Roll back safely: if a critical integration fails, re-allow classic access or raise the lifetime temporarily with an expiry date for the exception, rather than removing the policy permanently.
  6. Operate: review pending requests daily, review active tokens quarterly and include token revocation in leaver processing. See the Employee Offboarding Security Guide.

Small organisations can usually restrict classic tokens immediately and rely on owner approval. Large enterprises should set the enterprise policy, automate approval triage and treat GitHub tokens as non-human identities in their inventory. See the SaaS API Token Security Guide.

Framework mapping

FrameworkRelevant entries
MITRE ATT&CK v20T1528 Steal Application Access Token; T1550.001 Application Access Token; T1552.001 Credentials In Files; T1213.003 Code Repositories; T1195.002 Compromise Software Supply Chain
NIST SP 800-53 Rev. 5IA-5 Authenticator Management; IA-5(7) No Embedded Unencrypted Static Authenticators; AC-6 Least Privilege; AC-2(3) Disable Accounts; AU-6 Audit Record Review
NIST CSF 2.0PR.AA-01, PR.AA-05, DE.CM-03
OWASP Non-Human Identities Top 10NHI2 Secret Leakage, NHI7 Long-Lived Secrets

Common misconfigurations

  • Classic tokens left allowed: any member's repo-scoped token reaches every organisation they belong to and owners cannot see it. Restrict classic access.
  • "No expiration" tokens: unlimited lifetimes are allowed unless a maximum lifetime policy blocks them. The Home Depot token exposure left a leaked GitHub token usable for more than a year. See the OWASP NHI Top 10 NHI7 Long-Lived Secrets Guide.
  • Bot accounts holding personal tokens: a privileged PAT for a bot or service account is a shared secret with broad reach. In the Trivy supply chain attack a stolen PAT and a non-atomic rotation left valid credentials behind, which were later used to publish a malicious release.
  • Rotation after exposure delayed: the SpotBugs token was taken in December 2024 and used in March 2025. Rotate any token exposed to untrusted code immediately, even with no sign of misuse.
  • Tokens in code and config: committed tokens are revoked automatically when found in a public repository or gist, but not in private repositories, so private leaks persist. See the OWASP NHI Top 10 NHI2 Secret Leakage Guide.
  • Offboarding that ignores tokens: removal from the organisation ends a classic token's SSO authorisation there, but the token still works on the user's personal and other repositories. Ask leavers to revoke tokens and check for SSH keys created by tokens.

Practitioner checklist

  • Restrict classic personal access tokens at organisation or enterprise level.
  • Keep administrator approval required for fine-grained tokens and review the queue daily.
  • Set maximum lifetimes for both token types, 90 days or less for fine-grained tokens.
  • Migrate CI and integrations from personal tokens to GITHUB_TOKEN, GitHub Apps or OIDC.
  • Enforce SAML SSO and phishing-resistant MFA for owners.
  • Enable repository push protection with delegated bypass and alert on every bypass.
  • Stream the audit log to the SIEM and document the hashed_token lookup in the leak runbook.
  • Use POST /credentials/revoke (unauthenticated, up to 1,000 credentials per request) to revoke GitHub tokens you find exposed but do not own.
  • Add GitHub tokens to the NHI inventory with an owner, purpose and expiry.

Standards and references

Related NHI Mgmt Group resources: GitHub and GitHub Actions Security Guide · GitLab Tokens Security Guide · Secrets Management Guide · CI/CD Pipeline Identity Security Guide

PDF for subscribers

Take this guide with you

Every section, table and checklist in one PDF, with links to the sources and related guides. Subscribe to our weekly NHI & AI Identity Journal and we’ll email you a download link.

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 26 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org

PDF Downloads for Newsletter Subscribers

Get the guide

Enter your details and we’ll email you a download link.

The full guide is free to read online. The PDF is a thank you for subscribing.

Fill in all fields marked * and tick the PDF box to continue.