Releases: qaz741wsd856/warden-worker
v0.7.0 Release Notes
Highlights
- Added support for Bitwarden Auth Requests ("log in with device"), including request creation, pending request polling, approval responses, persistence, and notification delivery.
Web Vault
- Updated Web Vault to version
2026.4.1in documentation and workflows. - Added
/identity/accounts/prelogin/passwordas an alias of the existing prelogin endpoint for newer client compatibility. - Refreshed the CSS override layer.
Runtime and Performance
- Notification fan-out now runs through Cloudflare Workers
waitUntil(), so HTTP responses can return immediately while websocket and push delivery continues in the background. This should reduce response latency on notification-producing endpoints. - Database access now uses the D1 Sessions API. Per Cloudflare's D1 documentation, read replication requires Sessions API; after enabling D1 Global Read Replication in the Cloudflare dashboard (you have to enable it manually), some read-heavy endpoints may see lower query round-trip latency and faster responses.
Compatibility
- Added DuckDuckGo browser device detection.
- Improved WebDAV backup uploads by creating missing destination directories automatically in the backup workflow.
Fixes
- Added password history normalization in cipher creation and modification.
- Moved security stamp rotation to HeavyDO.
Maintenance
- Updated dependencies and refreshed related documentation and workflow references.
- Removed unused endpoints.
v0.6.1 — Hotfix: Attachment Decryption After Cipher Migration
Caution
Update ASAP!
Problem
When download attachments on newer Bitwarden mobile clients, they perform an automatic cipher migration and send updated attachment encryption keys (attachments2) as part of a standard cipher update (PUT /api/ciphers/{id}). The server was silently ignoring this payload, causing the attachment akey and encrypted fileName in the database to go stale. After the client completes migration, previously uploaded attachments may fail to decrypt because the server still holds the old encryption keys.
Fix
The update_cipher handler now processes the attachments2 field when present in the request body, updating each attachment's akey (encryption key) and file_name (encrypted filename) in the attachments table. This aligns the behavior with the upstream Vaultwarden implementation.
Recovery for affected users
If you are already experiencing attachment decryption failures, you can restore the previous attachment metadata using Cloudflare D1 Time Travel:
- Identify the timestamp before the migration occurred.
- Use the D1 Time Travel restore command to roll back the
attachmentstable:wrangler d1 time-travel restore vault1 --timestamp=<timestamp>
- After restoring, trigger a full vault sync from your client.
For more details on D1 Time Travel, see the Cloudflare D1 docs or the project's DB Backup & Recovery.
Remaining issues
When you enter the attachment preview screen of the attachment belonging to a cipher that needs to be migrated, the decryption will fail at first time (just after the cipher migration). But if you download the attachment or re-enter the screen again, the decryption will succeed. I currently don't know why this is happening, and Vaultwarden has the same issue.
v0.6.0 Release Notes
What's New
Bitwarden Send
Securely share encrypted text or files via a time-limited link. Text Sends work out of the box; file Sends require a storage backend (KV or R2), same as attachments.
- Full CRUD with password protection, expiry, max access count, and disable toggle
- Anonymous access for recipients (no account required)
- Streaming file upload/download via R2 or KV
- Automatic cleanup of expired Sends via scheduled task
Real-time Notifications
Vault changes now sync instantly to connected clients.
- WebSocket push for desktop apps and browser extensions (powered by Durable Objects)
- Mobile push notifications via Bitwarden push relay for official Android/iOS apps
Device Management
View and revoke active sessions from the web vault or mobile apps. Each login is now bound to a device record with a dedicated refresh token.
Cipher Archiving
Archive and unarchive vault items (single or bulk), matching the latest Bitwarden client UI.
Streaming Refactor (JS → Rust)
Attachment and Send file upload/download logic has been rewritten from JavaScript to Rust for better reliability and consistent handling.
Infrastructure & CI/CD
- Web vault updated to v2026.3.1
- GitHub Actions pinned to commit SHAs for supply-chain security
- Node.js 20 → 24, Wrangler 4.54 → 4.82, worker-build 0.7.5 → 0.8.1
- Optional
BASE_URLenv var for reverse proxy setups
Database Migrations
Three new D1 migrations are included and will be applied automatically:
| Migration | Change |
|---|---|
0010_add_devices.sql |
Adds devices table for device-bound authentication |
0011_add_sends.sql |
Adds sends and sends_pending tables |
0012_add_archived_at.sql |
Adds archived_at column to ciphers |
Breaking Changes
Caution
This update will force-logout all users. The authentication system has been migrated to a new device-bound refresh token model. All existing refresh tokens and 2fa remember tokens will be invalidated after the migration runs. If you don't get logged out automatically, you have to logout manually and login again.
Before updating, it is strongly recommended to export your vault data from Bitwarden client (Settings → Vault Options → Export Vault).
Your encrypted vault data (ciphers, folders, attachments) is fully preserved — only authentication sessions are reset.
New Environment Variables (Optional)
| Variable | Default | Description |
|---|---|---|
PUSH_ENABLED |
false |
Enable mobile push notifications |
PUSH_INSTALLATION_ID |
— | Bitwarden push relay installation ID (secret) |
PUSH_INSTALLATION_KEY |
— | Bitwarden push relay installation key (secret) |
PUSH_RELAY_URI |
https://push.bitwarden.com |
Push relay endpoint |
PUSH_IDENTITY_URI |
https://identity.bitwarden.com |
Push identity endpoint |
BASE_URL |
(from request) | Override base URL for file upload/download URLs |
SEND_TEXT_MAX_BYTES |
1887436 (~1.8 MiB) |
Max text Send size (D1 row limit) |
SEND_MAX_BYTES |
104857600 (100 MiB) |
Max file Send size |
USER_SEND_LIMIT_KB |
— | Per-user Send file storage quota (KB) |
SEND_TTL_SECS |
300 |
TTL for Send file upload/download URLs |
New Bindings (Optional)
| Binding | Purpose |
|---|---|
NOTIFY_DO (Durable Object) |
WebSocket notification hub. Remove to disable live sync. |
v0.5.0 Release Notes
Caution
Upgrade ASAP! The latest Bitwarden clients now encrypt each cipher with an individual key (stored in the key field). If you create or edit a cipher using a recent client while still connected to an older server that does not persist this field, the cipher data will become undecryptable. Please update your server to this release as soon as possible.
If you have already been affected, you can roll back the database to a point before the data corruption using D1 Time Travel.
✨ Features
- Cloudflare KV attachment storage — Added KV as an alternative backend for attachment storage alongside R2, providing more deployment flexibility.
- Row-based cipher fetching — Ciphers now can be fetched row-by-row from D1 instead of as a single large JSON blob, avoiding
SQLITE_TOOBIGerrors for large vaults. - Password hint endpoint — Added a dedicated endpoint for retrieving master password hints via the Accounts API.
- Cipher
keyfield — Added thekeyfield to the Cipher model and updated JSON serialization to handle null arrays gracefully. - WebDAV backup support — Enhanced the D1 backup workflow to support uploading backups to WebDAV destinations.
🐛 Bug Fixes
- Fixed empty-string
FolderIdnot being treated asnull. - Fixed URL pathname normalization to ensure consistent routing.
- Fixed sync behavior:
domainsis now correctly set tonullwhenexcludeDomainsis true; addedcultureto the profile response.
⚡ Performance
- Optimized JSON response building for ciphers and sync endpoints by appending directly to string buffers instead of constructing intermediate collections.
🔧 Refactoring
- Migrated JWT handling from the previous library to
jwt-compact. - Removed unnecessary serialization conditions for KDF parameters in identity and user models.
- Updated dependencies (
Cargo.lockrefresh).
📝 Documentation
- Added
SECURITY.md. - Updated D1 backup/restore playbook.
🔮 What's Next
Warning
Breaking change ahead. The next major version will introduce device management and a restructured JWT token scheme. This is a breaking update — all existing sessions will be forcibly logged out upon deployment. Please make sure to export your vault in advance.
v0.4.0 Release Notes
This release focuses on Security, Cloudflare Workers reliability and Bitwarden client compatibility.
✨ Highlights
- 🧱 Durable Objects CPU offload (optional): introduces a Rust Durable Object (
HeavyDo) and routes selected CPU-heavy endpoints (imports, password verification, etc.) through theHEAVY_DObinding. - 🔐 KDF / password hashing upgrade: server-side PBKDF2 moved to a pure Rust/WASM implementation and the minimum/default iteration count is raised to 600,000 (
PASSWORD_ITERATIONS). Iterations are stored per-user and upgraded automatically on successful login if below the configured minimum. - 🔒 Authentication hardening:
- Access and refresh tokens now include a
sstamp(security stamp) claim and are rejected if it doesn't match the current value in D1 (revokes tokens whensecurity_stampchanges, e.g. password/KDF/key changes). - JWT validation is pinned (HS256 + required
exp) with a small leeway to tolerate clock skew. - Invalid TOTP errors no longer include server timestamps.
- Access and refresh tokens now include a
- 🌐 Equivalent domains (URI matching): adds
/api/settings/domainswith optional D1-backed seeding of the global dataset. - 🧩 Compatibility endpoints: adds or stubs endpoints to reduce client 404s:
/api/alive,/api/now,/api/version/api/hibp/breach(stub: empty list)/api/accounts/tasks(stub: empty list)/api/auth-requests+/api/auth-requests/pending(stubs: empty list)
- 📎 Attachments: refactors streaming logic into
src/attachments.js; key rotation can now update attachment keys and encrypted filenames whenattachments2is provided. - 🚀 Deployment & Web Vault bundling: CI downloads a pinned Web Vault build (
bw_web_builds, defaultv2025.12.0), removes source maps (Cloudflare static asset per-file limits), supports UI overrides, and can bootstrap an empty D1 database fromsql/schema.sql.
⚠️ Important note (token invalidation)
This release changes the JWT claim set/validation. After upgrading, all previously issued access and refresh tokens will be rejected and clients will appear to be "forced logged out".
Before upgrading production, consider exporting your vault data as a precaution.
🧭 Upstream alignment (Vaultwarden 1.35.0)
Vaultwarden 1.35.0 introduced a few client-facing payload/endpoint expectations that are now mirrored here:
- New fields for newer clients:
AccountKeysandUserDecryptionOptionsadded to the/identity/connect/tokenresponse.userDecryption.masterPasswordUnlockadded on/api/sync(new + legacy inner keys preserved for client quirks).
- Stubbed tasks endpoint:
/api/accounts/tasksis implemented as an empty-list stub to avoid client errors. - Web Vault updated/pinned: deployment workflow pins and bundles Web Vault
v2025.12.0(viabw_web_builds).
🔧 Operational notes (Cloudflare Workers)
- 🧱 Why DO offload matters: on the Workers Free plan, Durable Objects have a much higher per-request CPU budget (30s). Offloading CPU-heavy routes helps avoid throttling on the main Worker.
- 🔐 Why KDF changed: higher CPU budget (via DO offload) makes it practical to run PBKDF2 in pure Rust/WASM at a much higher iteration count, improving security at the cost of more CPU time.
- ⏱️ Expected performance impact:
- Endpoints that verify the master password may feel significantly slower than before (often ~10×).
- Observability may show very high CPU time for password verification (example ballpark: ~350ms per verification; password changes can be ~2×).
- 📊 Metrics caveat: Durable Object CPU time appears under DO metrics and does not count toward the main Worker CPU metrics. Check both views for accurate capacity planning.
🗄️ Database changes
- New schema: includes
0007_add_password_iterations.sqland0008_add_eq_domains.sql. - Bootstrapping empty D1:
sql/schema.sqlincludes the latest schema so CI (or operators) can initialize an empty database in one step.
🧰 Deployment / migration checklist
- 🗄️ D1:
- For brand new DB: apply
sql/schema.sql. - For existing DB: apply migrations via Wrangler (
migrations/).
- For brand new DB: apply
- 🧱 Durable Objects (recommended):
- Ensure
HEAVY_DOis bound inwrangler.tomlif you want CPU offload.
- Ensure
- 🔐 Password iterations:
- Optional: set
PASSWORD_ITERATIONS(default/min is 600000). - Existing users are upgraded on successful login if below the configured minimum.
- Optional: set
- 🌐 Equivalent domains (optional):
- Seed
global_equivalent_domainsinto D1 if you wantglobalEquivalentDomainsto be non-empty.
- Seed
- 🖥️ Web Vault assets:
- Frontend assets are expected under
public/web-vault/. - Source maps are removed in CI (and should be removed locally too) to satisfy Cloudflare static asset limits.
- Frontend assets are expected under
v0.3.0 Release Notes
✨New Features
- Full Attachment Support:
- Implemented file attachment handling using Cloudflare R2.
- Implemented zero-copy streaming for both uploads and downloads to optimize memory usage and performance.
- Security Enhancements:
- TOTP Support: Added Two-Factor Authentication via TOTP and recovery codes.
- KDF Setting Support: Add support for changing the algorithm and iterations.
- Rate Limiting: Applied Cloudflare Worker built-in rate limiting to sensitive endpoints.
- Account & Vault Management:
- Added support for changing user profile (name and avatar color).
- Added "Purge Vault" endpoint to delete all ciphers and folders instantly.
- Configuration:
ALLOWED_EMAILSconfiguration now supports Glob patterns for more flexible registration control.
⚡ Improvements
-
Performance Optimization: Major refactor of sync and list operations using SQLite JSON Query
-
API Compatibility: Updated API version and filled in missing routes for better compatibility with upstream clients.
-
Deployment: Disabled workers.dev by default for security; updated GitHub Actions to handle R2 bindings.
🐛 Bug Fixes
-
iOS Compatibility: Fixed timestamp formatting issues that prevented iOS clients from logging in or syncing correctly.
-
Data Integrity: Fixed validation logic during key rotation and ensured correct cleaning of KDF parameters during registration.
v0.2.0 - Security Update & Vault Management
🛡️ Security Notice: Server-side Hashing
This update addresses a security vulnerability regarding how authentication credentials are stored.
- The Risk: Previously, the server stored the authentication hash exactly as received from the client. In the event of a database breach, an attacker could potentially use this stolen hash to "impersonate" you and log in to your account (Pass-the-Hash attack) to download or mess up your vault.
- What remains Safe: Your actual passwords remain secure. Due to the Zero-Knowledge architecture, your vault is encrypted with a key derived from your master password, which is never sent to the server. Even if an attacker logs in, they cannot decrypt your data without your master password.
- The Fix: We now apply a secondary, unique salt and hash to your credentials before storage (just like vaultwarden). This prevents attackers from using leaked database records to log in. Existing users need to LOG OUT and log in to complete migration.
Make sure your
CLOUDFLARE_API_TOKENin action secrets has permission to edit D1 and Worker if you use CI/CD deployment with GitHub Actions.
✨ New Features:
- Account Management: Added support for changing master passwords, rotating encryption keys, and deleting accounts.
- Trash & Auto-Cleanup: Implemented soft-delete (Trash) functionality and a daily cron job to purge old items.
- Improved Import: Better handling of folders and bulk data during imports.
- Automated Backups: Added workflows for daily encrypted D1 database backups to S3.
🐛 Fixes & Compatibility:
- Added API stubs for Devices, Emergency Access, and WebAuthn to prevent client-side errors.
- Fixed issues with null folder IDs and data synchronization timestamps.