Traditionally, I've been storing my passwords in text-files in a more or less secure location. Not long ago, I transitioned to KeePass, but found it old fashioned and generally cumbersome. Especially the fact that the database is a single file makes it difficult to add and update passwords if you are part of a team. So I went looking for a self-hosted solution that would cost me little more than the labour I needed to put into it.
I quickly came up with a few options and put PassBolt, BitWarden and Psono on my shortlist. After weighing pros and cons, I ended up with PassBolt. PassBolt offered me the minimum feature set to the lowest cost, my own labour included.
The PassBolt licence regime is generous in that it allows unlimited users, groups and password sharing. Its basic features include managing your passwords in Chrome and Firefox plus command line integration for servers. Securitywise it's solid and based upon GPG-encryption. Each password is independently encrypted, even the database content like user profiles on the server is encrypted. You just have to make sure you generate your private key from a secure computer and that you keep your passphrase and key stored in a safe location.
Setup is super easy using the official PassBolt docker container + a MariaDb database container. I just added this to my existing docker-compose.yml file:
passbolt_db:
container_name: passbolt_db
image: mariadb:10.3
volumes:
- passbolt_db:/var/lib/mysql
networks:
- backend
environment:
- TZ=${DOCKER_TZ}
- MYSQL_ROOT_PASSWORD=${PASSBOLT_MYSQL_ROOT_PASSWORD}
- MYSQL_DATABASE=${PASSBOLT_MYSQL_DATABASE}
- MYSQL_USER=${PASSBOLT_MYSQL_USER}
- MYSQL_PASSWORD=${PASSBOLT_MYSQL_PASSWORD}
passbolt:
container_name: passbolt
image: passbolt/passbolt:2.12.0-debian
tty: true
depends_on:
- passbolt_db
networks:
- frontend
- backend
- email
volumes:
- passbolt_gpg:/var/www/passbolt/config/gpg
- passbolt_images:/var/www/passbolt/webroot/img/public
tmpfs:
- /run
command: ["/usr/bin/wait-for.sh", "-t", "0", "passbolt_db:3306", "--", "/docker-entrypoint.sh"]
environment:
- TZ=${DOCKER_TZ}
- APP_FULL_BASE_URL=${PASSBOLT_APP_FULL_BASE_URL}
- DATASOURCES_DEFAULT_HOST=${PASSBOLT_DATASOURCES_DEFAULT_HOST}
- DATASOURCES_DEFAULT_PORT=${PASSBOLT_DATASOURCES_DEFAULT_PORT}
- DATASOURCES_DEFAULT_USERNAME=${PASSBOLT_MYSQL_USER}
- DATASOURCES_DEFAULT_PASSWORD=${PASSBOLT_MYSQL_PASSWORD}
- DATASOURCES_DEFAULT_DATABASE=${PASSBOLT_MYSQL_DATABASE}
- PASSBOLT_REGISTRATION_PUBLIC=${PASSBOLT_REGISTRATION_PUBLIC}
- EMAIL_TRANSPORT_DEFAULT_HOST=smtp-relay
- EMAIL_TRANSPORT_DEFAULT_PORT=25
- EMAIL_DEFAULT_FROM=${NOTIFICATION_EMAIL}
- VIRTUAL_HOST=${PASSBOLT_DOMAIN}
- VIRTUAL_PORT=80
- VIRTUAL_PROTO=http
- LETSENCRYPT_HOST=${PASSBOLT_DOMAIN}
- LETSENCRYPT_EMAIL=${NOTIFICATION_EMAIL}
labels:
co.elastic.logs/disable: false
Then I ran:
docker-compose up -d
Once the containers were up and running, I initiated my admin account:
docker-compose exec passbolt su -m -c "/var/www/passbolt/bin/cake \
passbolt register_user \
-u <[email protected]> \
-f <yourname> \
-l <surname> \
-r admin" -s /bin/sh www-data
Now, I just had to follow the link I was given from the previous command, install the requested browser plugin (available for Chrome and Firefox) and follow the instructions. Then I was all set. The whole process, including looking up documentation to tailor my docker-compose file took me less than 40 minutes.
A word of warning though: remember to back up your db, gpg and images volumes regularly. Also, make sure you have tried recovering the volumes. That's actually an article for another day!