Providers / GitHub

Code hosting

GitHub API keys and credentials

What every GitHub credential a founder holds does, whether it expires, and what tends to break. Each fact links to GitHub's own docs.

Last checked 2026-11-07 · github.com

At a glance

CredentialExpiryPermissions
GitHub account loginNot documented–
Fine-grained personal access tokenYou chooseCan be scoped
Classic personal access tokenYou chooseCan be scoped
GitHub App private key (PEM)Doesn't expireFull access only
Deploy key (SSH)Doesn't expireCan be scoped

How to rotate the GitHub fine-grained token

  1. Create a replacement: Settings > Developer settings > Personal access tokens > Fine-grained tokens, click Generate new token, enter a token name, select an Expiration, choose Repository access, choose Permissions, and click Generate token GitHub docs
  2. Update wherever the old token was copied. For an Actions secret, the docs describe adding a repository secret (repository Settings, then New repository secret), an environment secret (Environments, pick the environment, then Add secret under Environment secrets) or an organization secret (New organization secret). The page read does not describe editing an existing secret's value in the web UI GitHub docs
  3. To change an Actions secret through the API, PUT /repos/{owner}/{repo}/actions/secrets/{secret_name} creates or updates it: the body is the value encrypted with LibSodium plus the key_id of the public key used, and the response is 201 on create or 204 on update. The page says classic tokens need the repo scope for this endpoint GitHub docs
  4. GitHub says organization and repository secrets are read when a workflow run is queued, and environment secrets when a job referencing the environment starts. Run or re-run a workflow after changing the secret GitHub docs
  5. Delete the old token: on the same Personal access tokens page, click Delete to the right of the token you want to remove GitHub docs

Can the old and new key work at the same time? Yes. Yes, by creating a new token rather than regenerating. A new token is a separate credential, so the old one keeps working until it expires or you delete it. The docs pages read do not describe a Regenerate button or what it keeps (scopes, expiry), so this entry does not use it.

Revoking the old one: Delete the old token from Settings > Developer settings > Personal access tokens. GitHub notes that deleting a token that was used to create a deploy key also deletes that deploy key. A leaked token belonging to someone else can be reported through the REST API revocation route.

Source: docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens, checked

Does the GitHub fine-grained token expire?

It's up to you: you can set an expiry for the GitHub fine-grained token.

What breaks when the GitHub fine-grained token expires

GitHub's token expiration page (https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/token-expiration-and-revocation) says that on reaching its expiration date the token is automatically revoked, and an expired or revoked token cannot be restored; you create a new one. The pages read do not give the exact error that git, the API or Actions returns for an expired token. An organization or enterprise owner can set a maximum lifetime policy that blocks tokens with infinite lifetimes; the pages read do not describe the error returned for a blocked token. The docs do not describe any email sent when a token expires or is about to, and do not say how organization owners are notified.

Other things that often go wrong with GitHub:

How to rotate the GitHub classic token

  1. Create a replacement: Settings > Developer settings > Personal access tokens > Tokens (classic), then Generate new token (classic). Add a note, select an Expiration (a default option or Custom date), select the scopes, and click Generate token GitHub docs
  2. Update wherever the old token was copied. For an Actions secret, the docs describe adding a repository secret (repository Settings, then New repository secret), an environment secret (Environments, pick the environment, then Add secret under Environment secrets) or an organization secret (New organization secret). The page read does not describe editing an existing secret's value in the web UI GitHub docs
  3. To change an Actions secret through the API, PUT /repos/{owner}/{repo}/actions/secrets/{secret_name} creates or updates it: the body is the value encrypted with LibSodium plus the key_id of the public key used, and the response is 201 on create or 204 on update. The page says classic tokens need the repo scope for this endpoint GitHub docs
  4. GitHub says organization and repository secrets are read when a workflow run is queued, and environment secrets when a job referencing the environment starts. Run or re-run a workflow after changing the secret GitHub docs
  5. Delete the old token: on the same page, click Delete to the right of the token you want to remove GitHub docs

Can the old and new key work at the same time? Yes. Yes, by creating a new token rather than regenerating. A new token is a separate credential, so the old one keeps working until it expires or you delete it. The docs pages read do not describe a Regenerate button or what it keeps (scopes, expiry), so this entry does not use it. The docs read describe the organization lifetime policy only for fine-grained tokens.

Revoking the old one: Delete the old token from Settings > Developer settings > Personal access tokens. GitHub notes that deleting a token that was used to create a deploy key also deletes that deploy key. A leaked token belonging to someone else can be reported through the REST API revocation route.

Source: docs.github.com/en/authentication/keeping-your-account-and-data-secure/token-expiration-and-revocation, checked

Does the GitHub classic token expire?

It's up to you: you can set an expiry for the GitHub classic token.

What breaks when the GitHub classic token expires

GitHub says that on reaching its expiration date the token is automatically revoked, and an expired or revoked token cannot be restored; you create a new one. GitHub also revokes a personal access token that has not been used in one year. The pages read do not give the error returned to git, the API or Actions, and do not describe expiry emails.

How to rotate the GitHub App private key

  1. Open your account settings from your profile picture (for an organization-owned app, go to Your organizations and click Settings beside the organization), then Developer settings > GitHub Apps GitHub docs
  2. Click Edit next to the app, go to Credentials, and under Key pairs click New key. Store the downloaded file: GitHub keeps only the public part. The PEM is in PKCS#1 RSAPrivateKey format GitHub docs
  3. Deploy the new private key to wherever your app signs its JWTs and confirm it works. The docs say to use multiple keys to rotate without downtime GitHub docs
  4. Under Key pairs, click Delete next to the old key and confirm by clicking Delete again GitHub docs

Can the old and new key work at the same time? Yes. An app can have up to 25 private keys, and GitHub recommends multiple keys so you can rotate without downtime. If the app has only one key you must generate a new one before deleting it.

Revoking the old one: Delete the old key under Credentials > Key pairs. Private keys do not expire and must be revoked manually.

Source: docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/managing-private-keys-for-github-apps, checked

Does the GitHub App private key expire?

No. The GitHub App private key doesn't expire on its own: it works until you revoke it.

What breaks when the GitHub App private key expires

Private keys do not expire, so there is no expiry failure. A deleted key can no longer be used; the docs read do not give the exact error returned to an app still signing with it.

How to rotate the GitHub deploy key

  1. Generate a new key pair on the server with ssh-keygen and note where it is saved. Use a dedicated pair for each repository: a deploy key cannot be reused across repositories GitHub docs
  2. In the repository, open Settings, click Deploy Keys in the sidebar, then Add deploy key. Enter a title, paste the new public key, tick Allow write access only if the deployment needs to push, and click Add key GitHub docs
  3. Point the server at the new private key and check it works, for example with git clone git@github.com:OWNER/REPO.git GitHub docs
  4. Remove the old key through the REST API: DELETE /repos/{owner}/{repo}/keys/{key_id} returns 204. Find the key_id with GET /repos/{owner}/{repo}/keys. The managing-deploy-keys page does not document a web UI removal step GitHub docs

Can the old and new key work at the same time? GitHub's docs don't say. The docs do not state a per-repository key limit or whether two deploy keys can be active on one repository at once; each deploy key is a separate entry added to the repository, so a new key can be added before the old one is removed, but the pages read do not say so outright.

Revoking the old one: Delete the old key with DELETE /repos/{owner}/{repo}/keys/{key_id}. A deploy key created with a personal access token is also deleted when that token is deleted.

Source: docs.github.com/en/authentication/connecting-to-github-with-ssh/managing-deploy-keys, checked

Does the GitHub deploy key expire?

No. The GitHub deploy key doesn't expire on its own: it works until you revoke it.

What breaks when the GitHub deploy key expires

Deploy keys have no expiry date in the docs read. The exact git error after a key is removed is not documented there.

Each credential

GitHub account login

Organization owners can enforce policies on tokens and access.

GitHub docs

Fine-grained personal access token

Expiration is chosen at creation. Docs: infinite lifetimes are allowed but may be blocked by an organization or enterprise maximum-lifetime policy (the org policy page says fine-grained tokens default to a 366-day maximum unless the owner changes it). The docs give no general maximum for the creation form; the URL pre-fill accepts expires_in of 1 to 366 or none, defaulting to 30 days if omitted. Organization owners can read token_expires_at and token_expired through the org personal-access-tokens REST endpoints. Access is scoped per repository and per permission. Tokens unused for a year are removed automatically.

GitHub docs

Classic personal access token

Expiration is optional: the creation steps say to choose a default option or a custom date to give the token an expiration, and GitHub strongly recommends one. Tokens unused for a year are removed automatically. Org owners can set a maximum lifetime for classic tokens too, but by default classic tokens have no expiration requirement. Access uses OAuth-style scopes, less granular than fine-grained tokens.

GitHub docs

GitHub App private key (PEM)

Private keys do not expire and must be revoked manually by deleting them. Up to 25 keys per app. Deleting the only key requires creating a new one first. GitHub stores only the public key, so the downloaded PEM cannot be recovered.

GitHub docs

Deploy key (SSH)

Deploy keys have no expiry date. They are read-only by default and can be given write access when added. Each key grants access to one repository and cannot be reused across repositories. The managing-deploy-keys page has no removal steps; the REST API documents DELETE /repos/{owner}/{repo}/keys/{key_id}. Keys are immutable: to change one, remove it and add a new one.

GitHub docs

Renewals and billing

Where to find it in GitHub

What GitHub's docs don't say

We couldn't confirm these from official docs, so don't rely on them either way:

Rotating or replacing a GitHub key

The steps are the same for most providers: make the new key, deploy it everywhere the old one is used, check it works, then revoke the old one. Our guides walk through it:

Sources

Keep track of every GitHub key

StackHangar stores your GitHub keys in an encrypted vault, grouped by the product they belong to, warns you before they expire, and walks you through rotating them. We can't read your secrets.