wif.tax

GitHub

C REST/GraphQL API and Actions

Nothing outside GitHub can federate into the GitHub API: you hold a personal access token or a GitHub App private key, and the App key at least buys you one-hour installation tokens. In the other direction GitHub Actions is a proper OIDC issuer, so your workflows reach AWS, GCP, Azure and Vault without a single stored key.

Docs: docs.github.com · Checked 2026-09-16 · source YAML · dispute via PR

Inbound C

How a workload running anywhere authenticates to this product.

GitHub App: a JWT signed with a long-lived private key is exchanged for a one-hour installation access token. Personal access tokens (classic and fine-grained) are static keys.

We found no documented way to exchange an external OIDC token (from a cloud, a CI system, or SPIFFE) for GitHub API access; the only federation GitHub documents runs the other way, from Actions out to clouds. The GITHUB_TOKEN inside an Actions job is ambient identity on GitHub's own platform and does not count. If GitHub ships inbound OIDC we will happily re-grade.

Outbound A

How this product reaches into your cloud, repos, or other SaaS.

GitHub Actions is an OIDC issuer (https://token.actions.githubusercontent.com); AWS, GCP, Azure, Vault and any other OIDC-aware target trust it by sub and aud claims and hand back a short-lived credential, so no cloud secret is stored in GitHub.

Outbound here means Actions workflows deploying into your infrastructure. The sub claim (repo:org/repo:environment:prod and similar) is the trust boundary on the cloud side.

Hygiene for any static credential the product still issues

✓ Expiry enforceable
Passes for PATs: fine-grained tokens default to 30 days and org/enterprise owners can cap lifetime for both token types. GitHub App private keys are the exception: they never expire and no policy can force them to.
  • docs.github.com checked 2026-09-16
    “Organization owners can set maximum lifetime allowances for both fine-grained personal access tokens and personal access tokens (classic).”
  • docs.github.com checked 2026-09-16
    “If not provided, the default is 30 days, or less if the target has a token lifetime policy set.”
✗ Rotation via API
Revocation is possible via the API (org endpoints for fine-grained PATs, and an unauthenticated POST /credentials/revoke for any leaked token), but there is no API to create a PAT or a GitHub App private key; both are minted in the browser. Half a rotation loop is not a loop.
  • docs.github.com checked 2026-09-16
    “Limited to revoking a token's existing access.”
  • docs.github.com checked 2026-09-16
    “Any authenticated requests will return a 403.”
✓ Scoped keys
  • docs.github.com checked 2026-09-16
    “Each token can be further limited to only access specific repositories for that user or organization.”
✓ Last-used visible
The org fine-grained PAT endpoints return token_last_used_at, and the personal settings UI shows last use per token. GitHub also auto-revokes tokens unused for a year.
✓ Leak revocation
  • docs.github.com checked 2026-09-16
    “If a valid OAuth token, GitHub App token, or personal access token is pushed to a public repository or public gist, the token will be automatically revoked.”
  • docs.github.com checked 2026-09-16
    “GitHub Personal Access Token”

Notes

Headline C is driven entirely by the inbound surface. A GitHub App is the right way to run a machine against the API and its installation tokens are short-lived, but the root of trust is a PEM file that never expires. Fine-grained PATs are well-scoped and policy-capped but still static.

Badge

wif.tax grade C

[![wif.tax grade](https://wif.tax/badge/github-api.svg)](https://wif.tax/p/github-api/)