Install Vaultwarden
Give the company a shared password vault that you own yourselves, with Bitwarden's apps pointed at your own server.
Last reviewed:
What you get out of this
Ask the company where the password to the Instagram account is. The answer is usually a message in a group chat from long ago, or a note with the person who happened to create the account. Then someone else needs to access the same account, and the search begins.
Vaultwarden solves that. The company gets a shared vault where all logins are stored encrypted, each person has their own account with their own master password, and you share what needs to be shared instead of sending it. You also avoid the other problem: when the same password is used everywhere, it only takes one service leaking for all accounts to be left open.
What you need before you start
- Docker on Windows or Linux Mint. Install Docker covers the installation, and this guide builds on it.
- Very little of the computer. Vaultwarden is written in Rust and uses under 100 MB of memory, which makes it the lightest system in this entire section.
- One master password per person in the company. It should be long, it should be unique, and it should be possible to remember. Four randomly chosen words in a row are both safer and easier to remember than
Hejsan123!. - The Chrome, Edge or Firefox browser on everyone's computers. The extension is installed from there.
- One appointed person responsible for making the backup. A password vault without a backup is one single hard drive failure away from disaster.
Time required and difficulty level
The server is up and running in ten minutes. Allow another hour to set up accounts, install the extension on everyone's computers and move in the passwords you already have. The difficulty level is low in technical terms. What requires some thought is the routines: who gets to see what, and what you do on the day someone forgets their master password.
What Vaultwarden is, and how it relates to Bitwarden
Bitwarden is a well-known password manager with apps for computer, browser and mobile. The server behind it is open source but heavy to run yourself. Vaultwarden is a rewrite of that server, made to be small enough to run on a simple machine, and it speaks the same language as Bitwarden.
That means you use Bitwarden's regular apps and extensions, but point them at your own server instead of at Bitwarden's. You get features that otherwise cost money, such as shared collections and file attachments, and you pay nothing.
One thing should be said straight out: the encryption happens in your browser before anything is sent to the server. The server only stores unreadable blocks, and the master password never leaves the computer. That is also why no one, neither you nor anyone else, can recover a forgotten master password. If someone loses theirs, the account is gone and must be created again.
The files you paste in
Create a folder called vaultwarden and a file in it called compose.yaml:
services:
vaultwarden:
image: vaultwarden/server:latest
restart: unless-stopped
ports:
- "8000:80"
environment:
- DOMAIN=http://localhost:8000
- SIGNUPS_ALLOWED=true
- ADMIN_TOKEN=BYT_UT_MIG
volumes:
- vw_data:/data
volumes:
vw_data:
Replace ADMIN_TOKEN with a long random string. On Mint, openssl rand -base64 48 gives you a good one, on Windows you use the password generator in your browser. That string is the key to the admin page and should be treated like a root password: it is stored with the person responsible for the server, and is not shared with the whole company.
Vaultwarden accepts a plain string as the token but also writes a warning in the log that a hashed token is better. For an installation that is only reached from the company's own computer, it works as it stands. If you run the server on the internet, you should follow the warning, and the hashing is done inside the container, that is, only after it has started once:
docker compose exec vaultwarden /vaultwarden hash
The command asks for your token twice and then prints a long string that starts with $argon2id$. That string goes on the ADMIN_TOKEN line, and there is a trap there that locks out more people than it should: dollar signs have a meaning of their own in compose.yaml. Every $ in the hash must therefore be written as two, that is $$, otherwise Docker reads the string as something other than what it is and the admin page does not accept your password. Do not put quotation marks around the value, because then the quotation marks become part of the string and the token never matches:
- ADMIN_TOKEN=$$argon2id$$v=19$$m=65540,t=3,p=4$$...
Check that you can get into /admin before you continue. This is where a company locks itself out of its own server.
SIGNUPS_ALLOWED=true means that anyone who reaches the address can create an account. You need it while the company registers, and you should close it right afterwards. It has its own section further down, and it is the most important step in the whole guide.
Windows: start Vaultwarden
Check that Docker Desktop is running, open PowerShell and run:
cd $HOME\Documents\vaultwarden
docker compose up -d
The image is small, so the download takes under a minute. Check with docker compose ps and then open http://localhost:8000. Click Create account and register the first account with the company's shared email address.
Linux Mint: start Vaultwarden
Open Terminal and run:
cd ~/vaultwarden
docker compose up -d
docker compose logs --tail 20
The log should say that the server is listening on port 80 inside the container. Open http://localhost:8000 and create the first account.
Here comes the limitation that decides how you can use the installation. Browsers require a secure connection for the kind of encryption the Bitwarden extension uses, with a single exception: addresses that start with http://localhost count as secure anyway. The server therefore works perfectly on the computer it runs on, and refuses in the extension as soon as a colleague browses to http://192.168.1.42:8000.
You have two ways forward from there. Either everyone runs their own Vaultwarden locally, which works but does not give you a shared vault. Or you put the server on a cloud server with a domain name and HTTPS, and then the whole company reaches the same vault from their own computers and phones. A small cloud server is enough, Domain and email takes care of the domain, and a reverse proxy such as Caddy handles the certificate for you.
In that case, change DOMAIN in the compose file to https://valv.erdoman.se or whatever you choose. The line is used for links in email and for two-factor login, and if it is wrong those parts stop working.
Accounts for the company
- Have every person in the company go to the address and create their own account with their own email address. Never share one account between several people, the whole point is to see who did what.
- Create an organization from the first account: click New and select Organization. Name it after the company.
- Invite the other accounts to the organization. The invitations appear under Members, and since no email server is connected you approve them manually there.
- Create collections for what should be shared, for example
Sociala medier,WebbhotellandEkonomi. Give the person responsible for finances access to the finance collection, not to everything. - Turn on two-factor login on your own account under Security. The Aegis, Bitwarden Authenticator or Google Authenticator apps all work.
Close registration
When everyone in the company has an account, change the line in the compose file to SIGNUPS_ALLOWED=false and run docker compose up -d again. Now no one can create an account on their own, and new members are invited from the organization instead.
If you skip this step, the company's password server is open to anyone who finds the address. Set a reminder the same day you install.
The browser extension and the mobile app
Install Bitwarden Password Manager from the Chrome Web Store, Microsoft Edge Add-ons or Firefox Add-ons. Before you log in, select Self-hosted in the Logging in on drop-down list in the login box and enter the server address, that is http://localhost:8000 or your domain name. If you miss that step, the extension logs in to Bitwarden's own cloud service and finds none of your passwords.
The mobile app is also called Bitwarden and works the same way: select your own server in the login box, enter the address, log in. The app requires the server to be reachable over HTTPS, so it only works if you have put the server on a real address.
Then move in the passwords you already have. Let the extension save every login for a week going forward, and at the same time replace the passwords that are reused in several places. The generator in the extension creates new ones for you.
Back up
Everything is in the volume vw_data: the database, the attachments and the keys. Make a copy like this, and do it every month:
docker compose stop
docker run --rm -v vaultwarden_vw_data:/data -v "$PWD":/backup alpine tar czf /backup/vaultwarden-backup.tar.gz /data
docker compose start
The server shuts down during the copy, and that is on purpose: a database file that is copied in the middle of a write can become unusable. It takes ten seconds. Check the volume name with docker volume ls first, it consists of the folder name plus the volume's. Put the copy on another disk or another machine.
If you run the command in PowerShell on Windows, write -v "${PWD}:/backup" with the curly brackets. $PWD works in PowerShell too, basically, but without the curly brackets the quotation mark right after can be interpreted as a separate argument, so the safe form has them.
The contents of the copy are encrypted, but treat it as sensitive anyway. Anyone who has the file can try to guess the master password at their leisure, and that is exactly why the master passwords should be long.
Test the restore at least once a year. A backup that has never been read back is a hope, not a copy.
How you know it worked
docker compose psshows vaultwarden asrunning.- You log in to the web vault at
http://localhost:8000. - A saved password is still there after
docker compose restart. - The browser extension fills in the login automatically on a real site.
- A password in a shared collection is visible to another person in the company.
SIGNUPS_ALLOWEDis set tofalseand new accounts cannot be created from outside.- The backup is on a different machine than the server.
If something goes wrong
The extension says the server cannot be reached. Nine times out of ten, the server address is not set in the extension, or http:// and the port number are missing.
Everything works in the browser but not in the extension from another computer. That is the requirement for a secure connection. See the section on Linux Mint above.
"You need to log in as a user" on the admin page. The token in ADMIN_TOKEN does not match the one you enter, or the line has been commented out. The address is http://localhost:8000/admin.
Someone has forgotten their master password. It cannot be reset, and that is intentional. Delete the account from the admin page, let the person create a new one and share the collections again. The passwords that only existed in that account are gone.
Port 8000 is taken. Change the left number in ports, for example to 8001:80, and change DOMAIN to the same port.
What you do next
Decide on two routines and write them down where the company writes things down. The first: every new account you create during the year goes into the vault the same day, not later. The second: the backup is taken on the first of the month by a named person.
Then you have a place to put all the passwords that the other guides create. Install Nextcloud gives the company a file area, Install n8n automates what is done by hand, and Install Odoo sets up the business system. All three create passwords you will need again.