FR
live

GitHub CLI’s signing key expires September 5, breaking Linux package installs

On Saturday, September 5, 2026, the PGP key that signs GitHub CLI’s APT and RPM repositories expires, and any gh install done before April 8 without a keyring update will start failing. Check your local keyring before the deadline and add the replacement key 7F38BBB59D064DBCB3D84D725612B36462313325.

A ring of identical grey metal keys on a dark surface, one amber key set apart to the side.

September 5, 2026. The PGP key that signs GitHub CLI (gh) Linux packages expires, at 12:44 UTC. April 8, 2026. GitHub had already published a keyring containing the replacement key — it was enough to reinstall per the instructions. September 2024. The same scenario broke the repositories for days and forced GitHub to extend the key in an emergency. Why it matters: any machine that installed gh via APT or RPM before April 8, 2026 and did nothing since will see its apt update, dnf update or yum install fail from Saturday — including CI/CD images rebuilt overnight.

A rotation announced, but a deadline that does not bend

GitHub was not caught off guard this time. Since April 8, 2026, issue #13118 in the cli/cli repository documents the rotation, and the published keyring files contain both keys: the old one — 2C6106201985B60E6C7AC87323F3D4EA75716059, which expires on September 5, 2026 — and the new one — 7F38BBB59D064DBCB3D84D725612B36462313325. Starting with the first release published after that date, the APT and RPM repository metadata will be signed only with the new key.

The problem is mechanical, not documentary. A system whose keyring holds only the old key will reject the new signature with an error like EXPKEYSIG or NO_PUBKEY, and the install or upgrade of gh will fail. The failure messages vary by package manager, but they all point to the same cause: the local key is stale.

The September 2024 precedent explains the caution. Back then the key expired with no rotation prepared, and GitHub had to extend the existing key in an emergency after a repository outage. This time the rotation is proactive — but it still requires each affected user to take the missing step.

Who is affected, and who is not

The scope is precise. You are affected if you installed gh from the official APT or RPM repositories before April 8, 2026 and have not re-run the install steps since. That is the typical case of a frozen container image, a VM golden image, or a machine provisioned months ago by an Ansible or Terraform script that never ran again.

You are not affected if you use Windows or macOS, build from source, or install gh via Homebrew, Conda, a community package manager, a direct .deb, or a standalone binary from GitHub Releases. Those channels do not go through the repositories’ PGP key.

The simple rule for those who do not remember the install date: inspect the local keyring. If it contains two public keys, you are already covered.

Checking your local keyring

The check takes one command. On Debian or Ubuntu, the keyring normally lives in /etc/apt/keyrings/:

bash
gpg --show-keys /etc/apt/keyrings/githubcli-archive-keyring.gpg

If the file is not there, try the older location /usr/share/keyrings/githubcli-archive-keyring.gpg, or read the repository source to find the path referenced by the signed-by= option:

bash
cat /etc/apt/sources.list.d/github-cli.list

If the output of gpg --show-keys shows two pub blocks — one with fingerprint 2C6106201985B60E6C7AC87323F3D4EA75716059 and one with 7F38BBB59D064DBCB3D84D725612B36462313325 — your keyring is up to date and there is nothing to do. A single, old fingerprint means you must fix it before Saturday.

Fixing APT and RPM

The fix is to re-import the keyring that holds both keys, then refresh the package. On Debian/Ubuntu:

bash
sudo mkdir -p -m 755 /etc/apt/keyrings
wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg \
  | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null
sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
  | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt update
sudo apt install gh

On Fedora, RHEL, CentOS or Amazon Linux 2, re-register the RPM repository, then update:

bash
# dnf (Fedora 41+, RHEL, CentOS)
sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
sudo dnf update gh

# yum (Amazon Linux 2)
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
sudo yum update gh

If a key-verification error persists after these steps, remove the old key from the RPM keyring before reinstalling. rpm -qa gpg-pubkey lists the keys; the old one is usually named gpg-pubkey-75716059-63172e8a. Remove it with rpm -e gpg-pubkey-75716059-63172e8a, then dnf remove gh followed by dnf install gh.

Recognizing the failure in logs

The symptom is unmistakable. On APT, the error names the expired or missing key outright:

bash
W: Failed to fetch https://cli.github.com/packages/dists/stable/InRelease
   The following signatures were invalid: EXPKEYSIG 23F3D4EA75716059 GitHub CLI
   The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 5612B36462313325

On RPM, the message varies — Signature verification failed, or a repomd.xml signed “with an unknown key” — but the diagnosis is the same: the keyring does not hold the new key. In a pipeline, the failure rarely surfaces as a clean message: it is an apt-get install gh exiting non-zero in the middle of a Dockerfile, with no one inspecting the cause. Hence the value of running the verification command ahead of time rather than discovering the expiry in production.

Why this is more than an annoyance

An expiring signing key is not a vulnerability in the classic sense. But it produces the same symptom as a supply-chain attack: the package manager refuses to validate what it receives. That is exactly the behavior you want to preserve — signature verification must fail when it can no longer prove a package’s origin. The lesson is therefore not “disable verification,” but “manage rotations like infrastructure.”

The real impact concentrates in pipelines. A CI/CD image that installs gh via apt and rebuilds nightly will fail silently from Saturday if its recipe has not been touched since April. The fix is not an application patch, but an update to the image recipe — propagated through the Dockerfiles, Ansible playbooks and Terraform modules that pin machine state.

The deeper practice is to never let a keyring or repository sit fallow. Signing-key rotations at GitHub, Docker, Microsoft or Google all follow the same cycle: announcement, publication of a replacement key, expiry. A team that provisions by code should treat a key’s expiration date as a maintenance deadline to plan, no different from a TLS certificate.

Preventing the next expiry

The one-off fix is not enough: the replacement key has its own end date, and other repositories will follow the same cycle. Two habits reduce the burden. First, fold the keyring check into the base image and its tests, so a broken recipe fails in CI rather than in production. Second, treat third-party repositories as dependencies to renew: an inventory of keys and certificates with their expiry dates, reviewed monthly, costs less than waking up to an outage.

The same reflex applies to the tooling around your images. Tools like Renovate or Dependabot will happily bump the gh version inside a Dockerfile without ever touching the repository key that verifies it. If the bump does not also refresh the keyring, the “updated” image fails at build time. The fix is to encode the keyring import as part of the same recipe that pins the package, so a version bump and a keyring refresh move together.

Verdict

If you install gh via APT or RPM, run the one-command check today (gpg --show-keys on the keyring) and re-import the two-key keyring before September 5. It is five minutes per machine, against a pipeline outage on Monday morning.

If you maintain images or playbooks, update the recipe that installs gh and force a rebuild of your base images. Do not “fix” it by disabling signature verification: you would trade a scheduled outage for a permanent supply-chain hole.

In every case, treat this deadline as a reminder: signing keys, like certificates, have an end date. An inventory of upcoming expirations — repository keys, internal certificates, rotation secrets — beats waking up to a Saturday outage.

References

The cyber brief, every Tuesday

The flaws that matter and the patches to apply, in a ten-minute read.

No spam. One-click unsubscribe.
read next

On the same topic

Kubernetes 1.34 leaves support and all three clouds charge $438 a month

Moved into maintenance mode on August 27, 2026, Kubernetes 1.34 reaches end of life on October 27, at which point AWS, Azure and Google all bill $0.60 per cluster per hour — $438 a month — to keep patching it. Upgrade before the deadline: the surcharge buys no features, only the survival of an outdated control plane.

Pulumi now runs your Terraform as-is and makes HCL a first-class language

In August 2026, Pulumi brought its Terraform backend, cross-language module conversion, and an OpenTofu-compatible HCL runtime to general availability. Terraform teams can keep their code and state while gaining remote execution, preventive policies, and Neo code reviews.

← Back to the feed

Type at least two characters.

navigate open esc dismiss