Vaultwarden
Vaultwarden is an alternative implentation of the Bitwarden password manager server. It works as a drop in replacement with all Bitwarden clients. It can handle a variety of types of data, it is an end to end encrypted service, with admins unable to view the passwords of users, and with the ability to create teams that can share items including TOTP MFA prompts.
Podman
We chose to use podman for the deployment of Vaultwarden. Podman is a system for deploying containerized application, it has the key advantage of not requiring root access for deploying containers, and having automation tighly integrated with Systemd through their quadlets feature. That allow us to integrate it into May First’s infrastucture without significant changes. This in theory could be deployed more widely to allow May First members to run applications in containers as well.
Podman , Quadlet and Systemd
Podman supports Quadlet, allowing you to define containers in a single .container file. Systemd automatically converts this file into a native service unit at startup. By placing the file in the correct directory and enabling the service, you can deploy, manage, restart, and monitor containers entirely through systemd.
As the unpriviledged site user we created the vaultwarden.container file in ~/.config/containers/systemd/ and ran systemctl --user daemon-reload to start the service initially. In order for a service to start at boot you would normally also need to enable lingering for the user’s systemd environment as root with loginctl enable-linger username. The control panel does this automatically when users create a scheduled job from the control panel, which we had already done previously for this user.
# ~/.config/containers/systemd/vaultwarden.container
[Unit]
Description=Vaultwarden Container
After=network.target
[Container]
Image=docker.io/vaultwarden/server:latest
#Podman will check if a new image is available and automatically download and restart the service.
#https://docs.podman.io/en/latest/markdown/podman-auto-update.1.html
#AutoUpdate=registry
# Environment variables pointing to secret files
Environment=DOMAIN=https://vaultwarden.mayfirst.org
Environment=ADMIN_TOKEN_FILE=/run/secrets/admin_token
Environment=SMTP_PASSWORD_FILE=/run/secrets/smtp_password
Environment=DATABASE_URL_FILE=/run/secrets/database_url
Environment=SMTP_FROM=NOREPLY@mayfirst.org
Environment=SMTP_HOST=mail.mayfirst.org
Environment=SMTP_PORT=465
Environment=SMTP_SECURITY=force_tls
Environment=SMTP_FROM_NAME=Vaultwarden
Environment=SMTP_USERNAME=vaultwardenmail
Environment=SIGNUPS_ALLOWED=False
Environment=ORG_EVENTS_ENABLED=False
# Secrets mounted as files
Secret=source=admin_token,target=admin_token
Secret=source=smtp_password,target=smtp_password
Secret=source=database_url,target=database_url
# Volume
Volume=/home/sites/383339/files/vaultwarden-podman-data/:/data/
# Port binding
PublishPort=8000:80
[Service]
Restart=always
[Install]
WantedBy=default.target
Upgrading
Most Podman deployments use server:latest when deploying instead of a specific version. In order to update the application, you can run podman pull followed by the specific image you want to pull, then restarting the quadlet. For more stability, a version can be specified, in which case to upgrade you’d have to manually change the version number in the Quadlet file, then restart the container.
Upgrading can be automated by setting up AutoUpdate. AutoUpdate pulls the latest image and restarts the container automatically. It is governed by a Systemd unit called podman-auto-update.service, which by default runs once a day.
Environment Variables
There are a set number of environment variables that must be predefined and passed to podman in order to successfully run Vaultwarden. Some of these enironment variables must be made into Podman Secrets, in order to pass them without potentially exposing passwords or configurations that would allow an attacked to comprimise your Vaultwarden deployment
ADMIN_TOKEN: This is in the form argon2 hash token, its used for access to the admin side of Vaultwarden. This environment variable is strictly neccesary, or you will not be able to manage your Vaultwarden instance. The hash token can be generated at argon2.online or using the argon2 command.
DOMAIN: The domain vaultwarden will be accessible at, note you must include the entire address including https:// or it will fail to start.
SMTP_FROM: This is the email address emails sent by Vaultwarden will be sent from.
SMTP_HOST: This must be a mail server that allows smtp.
SMTP_PORT: This should be 465 for TLS or 587 for STARTTLS. Other ports can be used, but only with caution.
SMTP_SECURITY: TLS or STARTTLS, make sure it matches the port number provided.
SMTP_FROM_NAME: The name the email address will diplay.
SMTP_USERNAME: The username for the email account used.
SMTP_PASSWORD: The password for the email account used.
DATABASE_URL: The podman implementation of Vaultwarden will also initilize its own database, but you may pass an external database with this variable.
ORG_EVENTS_ENABLED: toggle for logging.
Podman secrets and environment variables
In our continer definition we assign the contents of podman secrets to environment variables where necessary.
A Podman secret is an encrypted file managed by Podman and stored on the host under its container storage directories. Here they are stored in ~/.local/share/containers/storage/secrets/ by default. You can use podman secrets to securely store sensitive data, like passwords or keys, and make them available to your containers at run time.
We set up the secrets manually like this:
printf '************' | podman secret create --replace smtp_password -
You could also do something like this to type in the password manually without leaving traces in the bash history.
read -r -s -p "Password: " password; echo
printf '%s' "$password" | podman secret create --replace my_secret -
unset password
Administering Vaultwarden
The admin page for your Vaultwarden instance will be your domain, with /admin added to the end. By default Vartwarden is an invite only system, meaning you have to send an invite code to the email of a new user in order for them to create an account. Passwords can be entered in 2 locations, a personal vault or an organization collection. Personal vaults can only be viewed by the individual that created them, while items in an organization are able to be access by anyone in that organizations. Organizations are similarly invite only, and you are typically asked to verify the account being added to the organization with a seed phrase that is unique to each account.
Organizations are managed by users of Vaultwarden, rather than through the administration page. Each organization has several roles a member of an organization can inhabit, that being member, administrator, and owner; creating a specific organization owner account may be useful to enable access control. Under organizations there are collections, each organization has a default collection, and collections can be nested. Access control can be excersized over users, allowing different options such as read and write access to the collections, however access control is not possible for administrators or owners of the account.