13 min read
By

When your own password manager becomes a supply-chain risk: the Bitwarden CLI incident of 22 April 2026

For about 90 minutes, the official Bitwarden CLI on npm was available in a tampered version. The incident is part of the larger Checkmarx supply-chain attack. We weren't hit, and that had little to do with luck.

Drei identische Kraftpapier-Versandkartons in einer Reihe auf Beton, der mittlere mit gebrochenem dunkelrotem Wachssiegel, daneben ein Messingstempel und eine Lupe.

TL;DR — the 90-second summary

What happened

On 22 April 2026 between 17:57 and 19:30 ET, @bitwarden/cli@2026.4.0 was distributed as a manipulated package via npm

Who is affected

only those who freshly installed 2026.4.0 via npm in this ~90-minute window — vault data and Bitwarden production not affected

Wider context

part of the Checkmarx supply-chain attack — CVE to follow

Fix

2026.4.1 as the clean release, clear the npm cache, rotate secrets, review CI logs

Four guardrails

npm ci against a lockfile, local entry point instead of -g, Renovate with cooling-off, no global installs in production

Lesson

not the source was compromised but the distribution path — the dominant attack class for three years

 

What is the problem?

On the evening of 22 April 2026, a manipulated version of the official Bitwarden command-line tool was distributed via npm under the name @bitwarden/cli@2026.4.0. According to Bitwarden's official statement, the package was available between 17:57 and 19:30 ET before access was revoked, the release pulled, and a clean version published as 2026.4.1. The incident is connected to the wider Checkmarx supply-chain attack. A CVE has been announced. End-user vault data and Bitwarden production systems are not affected. Only those who freshly installed 2026.4.0 via npm in that ~90-minute window are affected.

What happened that evening is not spectacular, it is exemplary. The code in the Bitwarden repository was at no point compromised. What was manipulated was the distribution path: the package distributed via npm as official version 2026.4.0 was not the package that would have emerged from the legitimate build process. Attacks of this kind — against the path between source and target, not against the source itself — have over the past three years become the dominant form of supply-chain compromise.

We were not among those affected. This is not a coincidence — it is the result of a very unspectacular pipeline discipline we have consistently enforced for years.

Impact: not the source, but the path

The reason this class of attacks works is simple: the build of a mature open-source project is usually well observed. The pipeline in between often is not. Credentials to npm accounts, access to maintainer rights, compromised build runners, weak identity federation between CI and registry: all entry points that are neither visible in the codebase nor surfaced by classical scanners. Bitwarden addresses exactly that area in its remediation: access was revoked, secret rotation recommended, the installation chain reviewed.

The Bitwarden CLI is privileged

Many teams still consider Bitwarden or Vaultwarden as tools that only appear in HR or office contexts. That has not been true for a long time. In modern DevOps setups, the Bitwarden CLI is a regular tool in CI pipelines and on developer machines — wherever passwords are needed for customer systems or third-party services that cannot be cleanly mapped to modern mechanisms like OPKSSH, OIDC or passkeys. That makes the Bitwarden CLI a privileged package: whoever controls it potentially gets very broad access to the secrets a company needs in production.

90 minutes are enough

That explains why this concrete incident looks bigger than its time window would suggest. 90 minutes are enough to plant real malicious routines on teams with an aggressive update strategy (global installs, automatic minor upgrades without a lockfile, direct shell invocations). The same structural pattern as the later npm EVM/DeFi cluster of 6 May — only there the attackers deliberately kept the distribution window open longer.

Who is affected?

Three profiles that surface regularly in pre-audits for this class of incident.

Anyone not using the Bitwarden CLI is not directly affected by this concrete incident. Structurally, the lesson applies to every Mittelstand company with a modern build chain — the next manipulated npm package will arrive.

Mitigation and immediate actions — four guardrails

Immediate quick start in the order we currently push pipelines through — each line knocks out a specific class of incidents.

 

# 1. Move Bitwarden CLI to 2026.4.1, clear npm cache
npm cache clean --force
npm uninstall -g @bitwarden/cli   # if installed globally
npm install -D @bitwarden/cli@2026.4.1   # as a dev dependency

# 2. Reset the lockfile and build reproducibly
rm -rf node_modules
npm ci

# 3. For suspicious builds: rotate secrets
bw login --apikey
bw config server vault.bitwarden.com

 

1. Reproducible installs via npm ci against a committed lockfile

Our builds do not install the "latest available" version, but exactly the one pinned in package-lock.json. A changed package therefore only enters the build via an explicit lockfile commit, not via spontaneous mirror drift. npm install has no place in CI.

2. A defined entry point locally and in CI

Developers invoke tooling via Makefiles; CI jobs invoke it via GitLab CI components that do the same: npm ci, then a controlled call of the locally installed CLI. Global npm install -g calls deliberately do not exist on our runners — they are exactly the installation path Bitwarden's remediation addresses.

3. Updates exclusively via Renovate with a cooling-off

New package versions are not updated from the shell but proposed by Renovate as a pull request and auto-merged on green pipelines. The filter before that is decisive: we let new versions "mature" for a defined time (typically 72–168 hours) before Renovate offers them as an update. In this concrete case 2026.4.0 would have never survived the cooling-off: by the time it would have qualified, Bitwarden had long shipped 2026.4.1.

4. No global installations in production paths

All tools live as dev dependencies in the respective project structure. That makes every version deterministically coupled to the repository, rollbacks trivial, and compromised installations precisely scopeable.

Detection and verification

Five core questions — in half an hour you know whether you could be affected and where the biggest lever sits.

Quick-check snippet for all repos on a developer host:

 

find ~/projects -name package-lock.json -exec \
  grep -l '"@bitwarden/cli"' {} \; | while read f; do
    echo "=== $f ==="
    grep -A2 '"@bitwarden/cli"' "$f" | head -10
done

Operator recommendation

What should be operationally in place for which build chain right now — depending on today's maturity.

Cross-references: the npm EVM/DeFi post for mirror topologies, the Composer CVE post for PHP pipeline discipline, the CI/CD concentration post for the structural reasoning.

Conclusion

The Bitwarden CLI incident of 22 April 2026 is, in security retrospect, one of those incidents that is not spectacular and still forces the right conclusions. It was not the Bitwarden repository that was compromised but the distribution path — and exactly that attack class has been the dominant one for three years.

The question is not whether such a window comes again. It is whether your pipeline would even notice it — and whether after noticing you know in the same hour which builds in the days before ran against the compromised version. With a lockfile, a local entry point, a cooling-off period and dev-dependency discipline, the answer moves from "hopefully" to "in two commands".

A longer write-up with Makefile and Renovate configurations and the reasoning why we continue to keep classical passwords in Vaultwarden for certain client scenarios is available (in German) at ole-hartwig.eu.

Frequently asked questions about the Bitwarden CLI incident

Immediate quick start in the order we currently push pipelines through — each line knocks out a specific class of incidents.

 

# 1. Move Bitwarden CLI to 2026.4.1, clear npm cache
npm cache clean --force
npm uninstall -g @bitwarden/cli   # if installed globally
npm install -D @bitwarden/cli@2026.4.1   # as a dev dependency

# 2. Reset the lockfile and build reproducibly
rm -rf node_modules
npm ci

# 3. For suspicious builds: rotate secrets
bw login --apikey
bw config server vault.bitwarden.com

 

1. Reproducible installs via npm ci against a committed lockfile

Our builds do not install the "latest available" version, but exactly the one pinned in package-lock.json. A changed package therefore only enters the build via an explicit lockfile commit, not via spontaneous mirror drift. npm install has no place in CI.

2. A defined entry point locally and in CI

Developers invoke tooling via Makefiles; CI jobs invoke it via GitLab CI components that do the same: npm ci, then a controlled call of the locally installed CLI. Global npm install -g calls deliberately do not exist on our runners — they are exactly the installation path Bitwarden's remediation addresses.

3. Updates exclusively via Renovate with a cooling-off

New package versions are not updated from the shell but proposed by Renovate as a pull request and auto-merged on green pipelines. The filter before that is decisive: we let new versions "mature" for a defined time (typically 72–168 hours) before Renovate offers them as an update. In this concrete case 2026.4.0 would have never survived the cooling-off: by the time it would have qualified, Bitwarden had long shipped 2026.4.1.

4. No global installations in production paths

All tools live as dev dependencies in the respective project structure. That makes every version deterministically coupled to the repository, rollbacks trivial, and compromised installations precisely scopeable.

Why do you still keep passwords at all — aren't there OIDC, passkeys and OPKSSH?+

Wherever it's technically feasible, yes. But many client systems, legacy panels, SFTP access and older SaaS dashboards support neither passkeys nor OPKSSH nor OIDC. There the shared secret stays, and the clean answer is a centrally managed vault — not a text file on a developer laptop. Our goal is to keep the vault as empty as possible; pragmatically, it won't disappear in the foreseeable future.

How much effort is it to retrofit these guard rails?+

Less than most teams assume. npm ci and Renovate can usually be introduced within a few days. Consolidating the entry points takes a little longer — cleaning up wherever today there are global installations, manual updates or divergent shell calls. Typically two to four weeks for a clean overall picture, depending on how grown the pipelines are.

What is meant by "maturation window", and how long should it be?+

A maturation window means Renovate or a comparable tool only proposes a new package version after a defined minimum duration — say 48 hours for sensitive packages, 24 hours across the board. That gives the community and registries time to detect and pull a compromised release. Exceptions apply for packages with a known, actively exploited vulnerability.

Isn't a lockfile enough on its own to prevent incidents like this?+

A lockfile is the necessary foundation, but not sufficient on its own. It prevents a new version sliding spontaneously into the build — it doesn't prevent someone actively making a lockfile update commit without checking what they're pulling. Only the combination of lockfile, automated updates with a maturation window and a single, disciplined installation path actually holds.

We don't use the Bitwarden CLI at all — does this affect us?+

The specific incident only if you installed @bitwarden/cli@2026.4.0 via npm during the roughly 90-minute window. The underlying problem affects you even without Bitwarden: every npm or comparable registry integration in your pipeline is potentially exposed to the same attacks. The question isn't whether your setup is "correct", it's whether it would structurally absorb the next incident.

Before the next registry incident — let's talk about your pipeline.

Impact: not the source, but the path

The reason this class of attacks works is simple: the build of a mature open-source project is usually well observed. The pipeline in between often is not. Credentials to npm accounts, access to maintainer rights, compromised build runners, weak identity federation between CI and registry: all entry points that are neither visible in the codebase nor surfaced by classical scanners. Bitwarden addresses exactly that area in its remediation: access was revoked, secret rotation recommended, the installation chain reviewed.

The Bitwarden CLI is privileged

Many teams still consider Bitwarden or Vaultwarden as tools that only appear in HR or office contexts. That has not been true for a long time. In modern DevOps setups, the Bitwarden CLI is a regular tool in CI pipelines and on developer machines — wherever passwords are needed for customer systems or third-party services that cannot be cleanly mapped to modern mechanisms like OPKSSH, OIDC or passkeys. That makes the Bitwarden CLI a privileged package: whoever controls it potentially gets very broad access to the secrets a company needs in production.

90 minutes are enough

That explains why this concrete incident looks bigger than its time window would suggest. 90 minutes are enough to plant real malicious routines on teams with an aggressive update strategy (global installs, automatic minor upgrades without a lockfile, direct shell invocations). The same structural pattern as the later npm EVM/DeFi cluster of 6 May — only there the attackers deliberately kept the distribution window open longer.

Book a slot directly