Client Work
Vaultwarden Provisioner
A Node.js tool that programmatically creates and provisions Vaultwarden (self-hosted Bitwarden) user accounts โ built for The IO Foundation, an NGO that needed to onboard dozens of team members to their password management system without doing it one account at a time. The client's Vaultwarden instance runs at vault.symboliccapital.net.
The Problem
Vaultwarden doesn't have a bulk account creation API. Bitwarden's official server does, but only for enterprise customers. The IO Foundation runs Vaultwarden specifically because it's self-hosted and free. They needed to onboard ~50 people. Creating accounts one at a time through the web UI was going to take hours of manual work and introduce errors.
The Hard Part
Bitwarden's authentication isn't a simple hash-the-password situation. It uses a multi-step Key Derivation Function chain: the master password goes through PBKDF2 with the email as salt, producing a master key, which then derives both the authentication hash (sent to the server) and the encryption key (never sent anywhere). Getting any step wrong means the account exists but nobody can log in.
There's no official documentation for this chain outside Bitwarden's source code. Cracking it meant reading their C# implementation and rebuilding it in Node.js with the hash-wasm library for the PBKDF2 operations.
email + masterPassword
โ PBKDF2-SHA256 (100,000 iterations)
โ masterKey
โ HKDF-expand โ stretchedMasterKey
โ PBKDF2-SHA256 (1 iteration) โ masterPasswordHash
โ sent to /api/accounts/register
Once the KDF chain was working and login was confirmed against a live Vaultwarden instance, the bulk onboarding tool (bulk.js) was straightforward โ read a CSV of names and emails, generate temporary passwords, run each through the chain, hit the registration endpoint, log the results.
Result
Working tool, delivered to client. Accounts provision correctly and users can log in. The client can re-run it any time they need to onboard a new batch of people. Total development time was a few focused sessions.
This is also the project that proved I could deliver technical work for a paying client โ not just build things for myself. The IO Foundation found me through my Symbolic Capital presence.