From 2ad29d02d26334c6ac40d2fc25a0cf1b72c58dd0 Mon Sep 17 00:00:00 2001 From: jferrl Date: Sat, 31 Oct 2026 16:40:18 +0100 Subject: [PATCH] chore: cut the v1.12.0 changelog Leads with Security: the --exec key leak, the key echoed in errors, the GH_HOST port and mismatch, and the unforwarded SIGINT are in released versions, so each item names the ones it affects, as the basis for an advisory. Six changes are under Changed, among them --exec revoking the token, the GH_HOST refusal, and tokens reporting Valid() == false inside the skew rather than oauth2's 10s. --- CHANGELOG.md | 62 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e905a7..f046b74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,42 +14,48 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 > That `v2.0.2` tag is the only thing carrying the retraction — the `v2/` directory no > longer exists on `main` — so the tag must not be deleted or the retraction is lost. -## [Unreleased] +## [v1.12.0] - 2026-10-31 `githubauth token --exec` now revokes the token when the command exits, and the CLI can find the installation and narrow the token on its own. A security review closed six -ways a credential could reach somewhere it should not, listed under Security. Four -changes can affect existing code or scripts; they are listed under Changed. +ways a credential could reach somewhere it should not, listed under Security with the +released versions each affects; upgrade if you use `--exec` or pass the key through the +environment. Six changes can affect existing code or scripts; they are listed under +Changed. ### Security - `githubauth token --exec` and `jwt --exec` no longer pass `$GITHUB_APP_PRIVATE_KEY` to - the command, nor to the `git` that reads a clone's origin, in any letter case on - Windows. A child that leaked its environment leaked the key that mints tokens for every - installation, past `--repos`, `--permissions` and revocation + the command, in any letter case on Windows. A child that leaked its environment leaked + the key that mints tokens for every installation, past `--repos`, `--permissions` and + revocation. Affects v1.10.0 and v1.11.0. The `git` that reads a clone's origin, new in + this release, never gets it either (#93) - A `--key` that is neither PEM nor a readable file, such as a base64-encoded key from a CI secret, was repeated in full in the error, and so in logs and agent transcripts. The - error no longer includes a value longer than a path + error no longer includes a value longer than a path. Affects v1.10.0 and v1.11.0 (#93) - `--exec` set `$GH_HOST` without the API URL's port, so `gh` sent the credential to port - 443 of that host. The port is kept, and a clone's https origin must name the same port - as the API for the token to be scoped to it + 443 of that host. The port is kept. Affects v1.11.0, which began setting `$GH_HOST`. A + clone's https origin, new in this release, must name the API's port too (#93) - An exported `$GH_HOST` naming another instance than an installation token's made `gh` send the token there. `githubauth token --exec` now exits 2 before minting (see Changed). The JWT is not checked: it is signed locally, and only you know which instance its App - lives on + lives on. Affects v1.10.0 and v1.11.0 (#93) - A SIGINT sent to githubauth alone, as a supervisor does, left the command running with the credential. On Linux and macOS, unless the command is in the terminal's foreground job, - where a Ctrl-C reaches it directly, SIGINT is now passed on like SIGTERM + where a Ctrl-C reaches it directly, SIGINT is now passed on like SIGTERM. Affects + v1.10.0 and v1.11.0 (#93) - Every GitHub Action in the workflows is pinned to a commit. The release job holds the token that publishes the Homebrew cask and the gh extension, and a moved tag could have - run code with it. A successful API response is also capped at 16 MiB + run code with it. A successful API response is also capped at 16 MiB (#93) ### Added - `RevokeInstallationToken` ends an installation token before its hour is up. `githubauth token --exec` calls it once the command exits; `--keep` leaves the token - valid. A revocation that fails is reported on stderr, the token then stays valid until - it expires, and the exit code stays the command's. A cached source that handed the token + valid. A revocation that fails leaves the token valid until it expires: after a command + that ran, githubauth warns on stderr and keeps the command's exit code; when the + command never started, the failure joins githubauth's own error report, the JSON + document under `--agent`. A cached source that handed the token out keeps returning it, so build a new one (#87, #88) - `githubauth token --permissions contents:read,pull_requests:write` scopes the token below what the App was granted. Any permission name GitHub has is accepted; GitHub @@ -64,7 +70,7 @@ changes can affect existing code or scripts; they are listed under Changed. `ExtraPermissions` and, for a token limited to some repositories, `ExtraRepositories`. `githubauth token --json` prints both (#90) - `NewApplicationTokenSource(12345, key)` compiles: `Identifier` admits `~int`, so an - untyped constant needs no `int64(...)` conversion + untyped constant needs no `int64(...)` conversion (#95) - The CLI is a GitHub CLI extension: `gh extension install jferrl/gh-githubauth`, run as `gh githubauth` (#91) @@ -74,12 +80,16 @@ changes can affect existing code or scripts; they are listed under Changed. command leaves running on the token starts getting 401s. `--keep` restores the old behaviour (#87) - **An exported `$GH_HOST` that differs from the installation token's instance exits 2** - under `token --exec`, before anything is minted. It used to be kept, which v1.11.0 suggested for a - `--base-url` proxy in front of github.com; set it inside the command instead: - `--exec -- env GH_HOST=github.com gh …` + under `token --exec`, before anything is minted. It used to be kept, which v1.11.0 + suggested for a `--base-url` proxy in front of github.com; set it inside the command + instead: `--exec -- env GH_HOST=github.com gh …` (#93) - `NewPersonalAccessTokenSource("")`'s error now reads "personal access token is required", like the package's other missing-argument errors. Match errors with - `errors.Is`/`errors.As`, not their text + `errors.Is`/`errors.As`, not their text (#96) +- **A token from this package reports `Valid() == false` once it is inside the skew**, 30s + before expiry by default, where it reported `true` until oauth2's 10s. The cache now + stores the skew in the tokens it returns, which is what lets `oauth2.NewClient` honour + it. Code that checks `tok.Valid()` itself sees the change (#95) - **`InstallationPermissions` is no longer comparable**, because `Other` is a map. Code that compares two values with `==` or uses one as a map key no longer compiles (#88) - **Comparing installation token values, `*a == *b`, now panics** when GitHub's answer @@ -93,17 +103,17 @@ changes can affect existing code or scripts; they are listed under Changed. expiry, not 30s.** `NewClient` added its own cache over this package's. `ReuseTokenSourceWithSkew` is now oauth2's cache with the longer window, which `NewClient` uses as is. It works on copies of the tokens it caches, so caches sharing a - source no longer race + source no longer race (#95) - A `Retry-After` past about 292 years overflowed to a negative wait and retried at once. - It is capped at an hour, as documented + It is capped at an hour, as documented (#95) - `$GITHUB_APP_INSTALLATION_ID` or `$GITHUB_APP_ID` past the int64 range became the - largest int64 instead of being reported as malformed -- One `WithApplicationTokenExpiration` value applied by concurrent constructors raced + largest int64 instead of being reported as malformed (#95) +- One `WithApplicationTokenExpiration` value applied by concurrent constructors raced (#95) - `--json` or `--agent` after a malformed flag, as in `token --bogus --json`, still - produced a plain-text error; it now produces the JSON document -- `githubauth version` and `help` exited 0 when stdout could not be written + produced a plain-text error; it now produces the JSON document (#95) +- `githubauth version` and `help` exited 0 when stdout could not be written (#95) - Errors from a missing key file or a command that cannot start now wrap their cause, so - `errors.Is(err, fs.ErrNotExist)` and `exec.ErrNotFound` match + `errors.Is(err, fs.ErrNotExist)` and `exec.ErrNotFound` match (#95) - The exit-2 hint for a 422 names `--permissions` as well as `--repos`, and the exit-5 hint for a 404 names `--owner` (#88)