I Do Not Recommend Bitwarden
- title
- I Do Not Recommend Bitwarden
- type
- summary
- summary
- After years of self-hosting, Marius's case against Bitwarden β investor capture, enterprise architecture, security incidents, and a divide-and-conquer credential split as the way forward
- parent
- supply-chain-security
- tags
- password-manager, security, self-hosting, open-source, supply-chain
- created
- 2026-05-02
- updated
- 2026-05-02
Marius wrote a guide four years ago on running vaultwarden as a bitwarden backend on hardened OpenBSD. This post is the followup: he no longer recommends Bitwarden, and explains why across architecture, licensing, UX, and a five-incident security pattern. The piece ends with a divide-and-conquer credential split that abandons the single-vault model.
The investor angle
Bitwarden took $100M from PSG growth equity (and Battery Ventures) in 2022. Marius treats this as the predictable inflection point: open-source product + investor needing returns = rent-seeking trajectory, the freeware as bait, the SaaS subscription as the actual product. The SDK licensing episode in late 2024 reads as evidence β @bitwarden/sdk-internal shipped with a clause forbidding use "with software other than Bitwarden (including non-compatible implementations of Bitwarden)." After community backlash and a Phoronix writeup, Bitwarden called it a packaging bug and relicensed to GPLv3. Technically resolved, philosophically revealing.
Architecture mismatch
The official Bitwarden server is a heavyweight C# / .NET / MSSQL Express stack that won't speak PostgreSQL or MariaDB. Self-hosters routed around it years ago by running vaultwarden (Rust, by dani-garcia), which has roughly three times the GitHub stars of the official server. Bitwarden's response to that data point was to hire Vaultwarden's main developer and then ship "Bitwarden lite" β still .NET, still ~3Γ the RAM of Vaultwarden β instead of adopting the community implementation. NIH, in Marius's reading, won over engineering.
Client paper-cuts
Migration is broken in both directions. Importing from competitors fails on common formats with at least one well-documented bug ignored despite being on the marketing page. Moving items between an organization vault and a personal vault, ten years in, has no UI β the official workaround is exporting to unencrypted JSON, editing, re-importing. The export drops attachments, trash, password history, and timestamps along the way.
Client updates ship breaking protocol changes without warning. F-Droid auto-updated the Android client overnight while Marius was traveling and locked him out of his vault until he could reach his self-hosted backend. The Android app went through a full .NET MAUI β Kotlin rewrite in 2024, with regressions still showing up in quarterly releases.
UX is the persistent bottom note: noticeable delay on every unlock because the client tries to reach the backend even in offline mode, no way to disable sync-on-unlock, the vault list's clickable list items open the entry instead of filling the form (the small Fill button does the fill), Wayland Flatpak issues, biometric login on iOS broken, "Log-In suggestions not showing" as a recurring HN complaint. Feature requests from 2021 (basic edit history) still untouched. MSP resellers publicly call it "glacial feature development."
The CLI is its own problem: bw list outputs every credential in full without an opt-in flag, and the whole CLI is a Node.js / TypeScript program with the dependency surface that implies. The latter is what made the 2026 supply-chain incident possible.
Five-incident security pattern
Marius's argument hinges less on any single incident and more on the shape they form together:
- 2023 β KDF flaw. Wladimir Palant showed Bitwarden's advertised 200,001 PBKDF2 iterations were ~100,000 in practice for the encryption key β server-side iterations were applied only to the login hash. Default client-side iterations were also at 100,000, below OWASP, despite being raised since 2020. Bitwarden eventually moved to 600,000 iterations and added Argon2 β for new accounts; existing users had to update their KDF settings manually. Same mistake LastPass made before them.
- 2023 β Windows Hello bypass. RedTeam Pentesting's "Bitwarden Heist" (CVE-2023-27706): low-privilege processes could pull the vault key out of DPAPI without prompting Windows Hello or the master password. Fix shipped months after disclosure in 2023.4.0.
- 2023 β Cross-origin autofill. CVE-2023-27974: the browser extension autofilled credentials into cross-domain iframes if the base domain matched. Bitwarden's response was that iframes "must be handled this way for compatibility reasons."
- 2025 β DOM-based clickjacking. Marek TΓ³th's August 2025 disclosure: the extension could be tricked into autofilling credit card and personal data on a malicious page after a single click. Reported April 2025, classified moderate severity, patched in 2025.8.2 on the embargo expiration date.
- 2026 β Shai-Hulud / Checkmarx supply-chain attack. Bitwarden's
@bitwarden/cli2026.4.0 was published with abw1.jspayload via a compromised GitHub Action in their CI/CD pipeline. The payload pulled the Bun runtime, decrypted the Shai-Hulud worm, and harvested GitHub/npm tokens, SSH keys, shell history, AWS/GCP/Azure credentials, GitHub Actions secrets, and MCP configs. Stolen data was exfiltrated by auto-creating a public repo on the victim's GitHub. The malicious version was live for ~19 hours; 334 developers pulled it. Bitwarden's official statement noted no end-user vault data was accessed β true and beside the point. See supply-chain-security for the broader pattern.
The pattern Marius names is reactive rather than proactive security, "working as intended" responses to embarrassing findings, and the structural fragility of shipping a security CLI through npm when most of the ecosystem has moved to single static binaries.
Way forward: divide and conquer
Marius's replacement is not another single vault but a deliberate split into five credential groups, each tool chosen for its specific job. See credential-compartmentalization for the concept page.
- Group A β client/professional work. A SaaS password manager with sharing, SSO, audit logs. Proprietary trade-off accepted because scope is bounded.
- Group B β accounts containing PII (banks, online shops). A second cloud password manager, different vendor, different master password, different recovery β so a compromise of A doesn't cascade into B. Mobile client should not require Google Play Services (he runs GrapheneOS).
- Group C β accounts without PII (forums, throwaway services). KeePassXC / KeePassChi / KeePassDX with the
.kdbxfile synced via Syncthing. The file is itself encrypted, so Syncthing compromise doesn't directly expose secrets. - Group D β infrastructure (servers, SSH, CI). Personal infra credentials stored as group C; automation credentials in HashiCorp Vault for proper policies, token-based auth, short-lived credentials, and audit logs. Eyeing Infisical.
- Group E β one-off CLI secrets (API keys, tokens). The
passutility β GPG-encrypted file per secret in a Git repo on his own infrastructure, synced manually.
The point is not that the alternatives are universally better. It's that "one size fits all" turned out to mean "one size fits poorly," and that compartmentalization caps the blast radius of any single breach to one credential category instead of the whole vault.
See also
- bitwarden β entity page, founding, ownership, product split
- vaultwarden β Rust-based community-built Bitwarden-compatible server
- credential-compartmentalization β Marius's divide-and-conquer pattern as a reusable concept
- supply-chain-security β the Shai-Hulud / Bitwarden CLI incident in context
- living-off-the-land β adjacent attack pattern: legitimate tools as malware
- hold-on-to-your-hardware β earlier Marius post; same author
- marius-blog β author's blog as a tracked source