How to Turn On GitHub Immutable Releases After the OVHcloud CLI Backdoor
OVHcloud's CLI releases were swapped for malware because immutability was off. Here is what the setting locks and how to enable it without breaking releases.
On this page 9 sections
To stop an attacker from swapping files in your published releases, turn on GitHub's release immutability. In a repository, open Settings, find the Releases section, and select "Enable release immutability." It locks each new release's tag and assets, so nobody can alter them after publishing. It does not touch releases you already made.
The setting matters because of what happened to OVHcloud on October 19, 2026. An attacker used a hijacked developer account to replace binaries in the company's official CLI releases on GitHub. OVHcloud's CEO said immutability was switched off, so a user with the right permissions could modify existing releases without any checks from the CI/CD pipeline. This guide explains the incident, what the setting locks, how to enable it for a repository or an organization, and how to adjust your release workflow so it does not break. It is written for maintainers who ship binaries, containers, or archives through GitHub Releases. Backtrace covers DevOps and developer security, and release integrity is one of the cheapest wins in the field.
What happened to the OVHcloud CLI?
An attacker hijacked a developer's GitHub account, gained access to the OVHcloud CLI repository, and modified releases to carry information-stealing malware. The bad release appeared at 14:47 Paris time on October 19, 2026. A customer reported it, and OVHcloud blocked it at 16:21. That is about an hour and a half of exposure.
The affected versions are v0.11.0 through v0.15.0, according to CEO Octave Klaba. Versions v0.10.0 and v0.16.0 are clean. Source builds and Docker images were not affected. Klaba said the payload aimed to retrieve secrets from the disk, and he told affected users to change every secret on the machine. OVHcloud says its CI/CD pipelines, including unit tests, functional tests, and CVE detection, were not affected. The attacker reportedly uploaded locally built malicious packages instead of tampering with the pipeline. BleepingComputer's report has the full timeline.
OpenSourceMalware has linked the attack to the GlassWorm campaign and reported that the GitHub account had been compromised for over six months, with a suspicious history rewrite on March 5, 2026. Those attribution details come from that group, and OVHcloud has not confirmed them. What is confirmed is the control gap: the release could be edited after publication.
What does GitHub's release immutability lock?
An immutable release cannot change its Git tag or its assets after publication. The tag stays pinned to one commit and cannot be moved. It also cannot be deleted while the release exists, and even after you delete the release, you cannot reuse the tag name. Files such as binaries and archives cannot be modified or deleted.
Some fields stay editable. You can still change the release title and notes, and you can toggle the pre-release and latest flags. That keeps normal housekeeping possible without opening a path for file swaps.
Creating an immutable release also generates an attestation that records the tag, the commit SHA, and the assets. Consumers can use it to confirm that what they downloaded matches what was published. GitHub also protects against repository resurrection: if you delete a repository and recreate it with the same name, you cannot reuse tags tied to immutable releases in the original. GitHub's immutable releases documentation covers the details.
How do you enable immutable releases?
You can enable the setting per repository or across an organization. Use the repository path first if you want to test on one project.
- Open the repository on GitHub and click Settings. If you do not see it, open the More menu and choose Settings.
- Scroll to the Releases section.
- Select "Enable release immutability."
For an organization, the path is slightly different. Open the organization's Settings, and in the sidebar under "Code, planning, and automation," open the Repository dropdown and click General. In the Releases section, open the "No policy" dropdown and choose All repositories or Selected repositories. If you pick Selected repositories, click the gear icon, choose the repositories, and confirm. GitHub's guide on preventing changes to your releases lists the same steps. It warns that immutability applies only to future releases, so older releases stay editable.
How should you change your release workflow?
Because assets lock at publication, the order of operations matters. GitHub recommends a three-step flow: create the release as a draft, attach every asset, then publish. If your pipeline publishes first and uploads files afterward, the upload will fail once the release is locked.
Check your existing automation for these patterns. Scripts that upload assets after creating a published release need to switch to draft-first. Jobs that overwrite an asset to fix a bad build need a new version tag instead. Release notes tools that edit the body are fine, since notes remain editable.
Also review who can publish. Immutability protects against swapping files after the fact, but a stolen token can still publish a new malicious release. Pair the setting with reviewed pull requests for workflow changes and short-lived credentials. Our guide to GitHub Actions workflow lockfiles shows how to pin the dependencies your release job runs, and our checklist for checking repos for the GhostAction workflow covers the stolen-token side of the same problem.
Which of your existing releases should you audit?
Because immutability covers only future releases, your back catalog is still editable. Start with the releases people download most, since those are the ones an attacker would target. List each release, record the checksum of every asset today, and store that record somewhere the repository's maintainers cannot edit, such as a separate signed file or an internal wiki with limited access.
Then compare those checksums with any copies you or your users saved earlier. A mismatch means an asset changed after publication. If you cannot find an earlier copy, check the release's edit history and the audit log for asset uploads or deletions by accounts that do not normally publish.
For high-value tools, consider cutting a fresh patch release after you enable the setting. The new release gets the lock and an attestation, and you can tell users to move to it. It is a small change that gives them something firm to verify against.
Why did a customer catch the bad release and not your pipeline?
OVHcloud says a customer report led to the block, not an automated alert. That detail is a useful prompt for any team. Your CI can pass every test and still ship a file nobody built. Pipeline checks look at the code you built, while a swapped asset sits outside that path.
Add one monitor that watches the published artifact, not just the build. A scheduled job can download each latest release asset and compare its hash with the value recorded at publish time. Alert on any difference, and alert on release edits made outside your pipeline's service account. It is a small script, and it would have shortened an hour-and-a-half window.
What should users of a tampered release do?
Treat the machine as compromised if it ran an affected binary. OVHcloud's advice is to update to v0.16.0 or remove the CLI, clean the system, and rotate or revoke every secret on the machine. Updating the tool does not revoke a key that was already copied, which is why rotation matters more than the upgrade.
Make a list before you rotate. Include cloud provider keys, SSH keys, API tokens in shell history and dotfiles, browser-saved credentials, and tokens in local configuration files. Rotate the ones with the highest blast radius first, such as production cloud credentials and package publishing tokens. Our account of the Shai-Hulud and Tensorlake npm compromise response walks through a prioritized rotation plan.
How can consumers protect themselves from tampered binaries?
Consumers cannot enable maintainers' settings, but they can reduce risk. Pin to a specific version and verify its checksum or attestation before you run it. Prefer builds from source or container images when a project offers them, since OVHcloud's source builds and Docker images were not affected. Run unfamiliar CLIs in a disposable environment before giving them access to your real credentials.
At Backtrace, we treat a new binary from a familiar project the same way we treat any download: check where it came from, and give it the fewest permissions that let it do its job. If your team publishes its own tools, add an SBOM step, which our SBOM generation how-to covers.
Conclusion
OVHcloud's incident shows a plain gap: a published release that anyone with enough permission could edit. GitHub's immutability setting closes that gap for future releases, and it takes one checkbox in a repository or one policy at the organization level. The cost is a draft-first publishing flow, which most pipelines can adopt in an afternoon.
Enable it on your most-downloaded repository today, test one release through the draft flow, and then roll it out across the organization. Rotate secrets on any machine that ran a suspect binary, and do not wait for confirmation.