Security & Monitoring10 min read

Passbolt on VPS: auditable team password vault, no subscription

Team password managers cost 4 to 6 dollars per user per month in 2026, without ever giving you access to the audit log. Passbolt Community Edition (AGPL-3.0) turns a VPS into a team vault: every secret is encrypted with the recipient's GPG key, no password ever transits in clear text, and you always know who looked at what. On a single vCPU with 2 GB of RAM, the entire stack fits — and if the team grows, you scale the server, you don't renegotiate a contract.

Why self-host your team password manager

A SaaS team secret manager solves the sharing problem but creates another: you control neither where the secrets reside nor who has access on the vendor side. When an employee leaves the agency, revocation depends on how quickly your admin acts on a third-party interface — and the audit log, when it exists, is usually reserved for Enterprise plans.

Passbolt Community Edition reverses this logic: every secret is encrypted on the client side with the recipient's GPG key before it ever reaches the server. Even a system administrator with root access to the database cannot read a password in clear text. The audit log records every consultation per entry and per user — what accounting teams call a non-repudiable trace.

What Passbolt CE brings to your agency

  • Per-recipient GPG encryption — the secret never leaves the client in clear text; the server stores only encrypted data, unreadable without the user's private key.
  • Granular audit log — who consulted, modified or shared each entry, with a timestamp; essential when a team member leaves.
  • Per-entry sharing, not per-folder — share client A's secret with person A only, without exposing client B's secrets.
  • Native REST API — integrate into your CI/CD pipelines to inject secrets on the fly without writing them to the repository.
  • Official browser extension — available on Chrome, Firefox and Edge; fills forms like a SaaS manager.
  • Free and open source (AGPL-3.0) — no user limit on Community Edition, the code is auditable on GitHub.
  • Vertical scalability — if the team doubles, upgrade the VPS; no contract renegotiation, no pricing tier to cross.

Requirements for installation

Passbolt CE with PostgreSQL 16 fits in 2 GB of RAM: plan roughly 1 GB for the Passbolt container and 512 MB for PostgreSQL, with the remainder covering the OS and buffers. A single vCPU is enough for a team of fewer than fifty people.

Stack requirements: Docker and Docker Compose installed, a domain name pointing to your VPS (Passbolt refuses to start over HTTP — HTTPS is a prerequisite, not an option), and outbound SMTP access (port 587/STARTTLS or 465/SSL). Without a configured SMTP server, the container will not start: invitations and account recovery go through email.

Deploying Passbolt CE on your VPS

01

Prepare the directory and retrieve the official configuration

Connect to your VPS via SSH and create a dedicated directory:

mkdir -p /opt/passbolt && cd /opt/passbolt
curl -fsSL https://raw.githubusercontent.com/passbolt/passbolt_docker/master/docker-compose/docker-compose-ce.yaml \
  -o docker-compose.yml

This file declares two services: db (image postgres:16) and passbolt (image passbolt/passbolt:latest-ce-non-root), with two named volumes to persist data. In production, pin a fixed version — replace latest-ce-non-root with the latest stable release tag available on the official Docker Hub.

02

Configure environment variables

Create a .env file in the root directory. The minimum required variables:

APP_FULL_BASE_URL=https://passbolt.yourdomain.com
DATABASE_HOST=db
DATABASE_PORT=5432
DATABASE_NAME=passbolt
DATABASE_USERNAME=passbolt
DATABASE_PASSWORD=strong_password
POSTGRES_PASSWORD=strong_password
EMAIL_TRANSPORT_DEFAULT_HOST=smtp.yourprovider.com
EMAIL_TRANSPORT_DEFAULT_PORT=587
EMAIL_TRANSPORT_DEFAULT_TLS=true
[email protected]
EMAIL_TRANSPORT_DEFAULT_PASSWORD=smtp_password
[email protected]

APP_FULL_BASE_URL must start with https:// — Passbolt uses this value to build links in invitation emails and as the JWT base.

03

Add a PostgreSQL healthcheck and start the stack

Edit docker-compose.yml to add a health condition on the db service — without it, Passbolt may start before PostgreSQL is ready to accept connections, causing a restart loop:

# In the db service, under the postgres:16 image:
healthcheck:
  test: ["CMD-SHELL", "pg_isready -U passbolt"]
  interval: 10s
  timeout: 5s
  retries: 5

# In the passbolt service:
depends_on:
  db:
    condition: service_healthy

Then start the stack:

docker compose up -d
docker compose logs -f passbolt

Wait for the logs to indicate that GPG configuration has been initialized before proceeding.

04

Retrieve and note the GPG fingerprint

On first start, Passbolt generates a server-side GPG key pair. Retrieve the fingerprint — you will need it if you need to reconfigure the environment:

docker compose exec passbolt su -s /bin/bash -c \
  "gpg --home /var/lib/passbolt/.gnupg --list-keys" www-data

The fingerprint is the 40-character hexadecimal string under the pub line. Note it: if PASSBOLT_GPG_SERVER_KEY_FINGERPRINT does not match the key in the container's keyring, Passbolt will refuse to start with the error The OpenPGP server key fingerprint does not match.

05

Configure the HTTPS reverse proxy

Passbolt must be served exclusively over HTTPS. If you are using nginx as a reverse proxy on the same VPS, a minimal example configuration:

server {
    listen 443 ssl;
    server_name passbolt.yourdomain.com;

    ssl_certificate     /etc/letsencrypt/live/passbolt.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/passbolt.yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }
}

Obtain your certificate with Certbot (certbot --nginx -d passbolt.yourdomain.com) before enabling the block. The Passbolt browser extension will not work on an HTTP domain or with a self-signed certificate.

06

Create the first administrator account

Once the container is running and the domain is accessible over HTTPS, create the administrator account:

docker compose exec passbolt su -s /bin/bash www-data \
  -c "/var/www/passbolt/bin/cake passbolt register_user \
  -u [email protected] \
  -f FirstName \
  -l LastName \
  -r admin"

The command generates a single-use invitation link. Open it in the browser where the Passbolt extension is installed — the extension will guide the setup of your personal GPG key. Once the administrator is configured, invite team members from the web interface.

Hardening: access control, backups and key rotation

Restrict database port access to the Passbolt container only (Docker Networks handles this by default with Compose internal networks). Schedule a daily backup of the PostgreSQL volume with docker compose exec db pg_dump to external storage — GPG-encrypted secrets are worthless without the database that indexes them.

For server GPG key rotation, follow the procedure documented on docs.passbolt.com: the interface guides each user to re-encrypt their secrets with the server's new public key. Do not attempt to manually replace keyring files inside the volume — Passbolt will detect a fingerprint mismatch and refuse to start.

Passbolt CE vs Bitwarden Teams vs Vaultwarden

CriterionPassbolt CEBitwarden Teams / Vaultwarden
Monthly cost€0 (self-hosted)Bitwarden Teams: $4/user/month · Vaultwarden: €0 (self-hosted)
EncryptionPer-recipient GPG — the server never sees a secret in clear textAES-256 server-side (Bitwarden and Vaultwarden) — the server decrypts to serve you
Per-entry audit logYes, native CE — who consulted, modified, shared each secretBitwarden Enterprise: yes · Bitwarden Teams: no · Vaultwarden: no
Granular sharingPer entry and per user, with read/update/owner rightsPer folder (collection) — all or nothing
Stable REST APIYes, documented and versioned — usable in CI/CDBitwarden: official API · Vaultwarden: unofficial API, not guaranteed
LDAP / Active DirectoryPassbolt Pro (paid) · CE: manual invitation onlyBitwarden Enterprise: yes · Vaultwarden: no
Browser extensionOfficial extension Chrome/Firefox/EdgeBitwarden extension (Vaultwarden-compatible) Chrome/Firefox/Edge/Safari

Troubleshooting — real error messages

The OpenPGP server key fingerprint does not match on startup: the PASSBOLT_GPG_SERVER_KEY_FINGERPRINT variable in your .env does not match the key in the container's keyring. Check the fingerprint with gpg --list-keys inside the container, then update the variable. This typically occurs after recreating the container without persisting the GPG volume.

Could not send email during an invitation: EMAIL_TRANSPORT_DEFAULT_HOST is missing or incorrect, or port 25 is blocked by your VPS (the default at most providers). Switch to port 587 with EMAIL_TRANSPORT_DEFAULT_TLS=true (STARTTLS) or port 465 with SSL implicit, depending on your SMTP server's configuration.

passbolt container in unhealthy state or restart loop: run docker compose logs passbolt and look for database connection errors. The most common cause is PostgreSQL not yet being ready when Passbolt tried to connect. Add the depends_on with condition: service_healthy and the pg_isready healthcheck on the db service (described in step 3).

Extension not recognized by the browser: the Passbolt extension requires HTTPS with a valid certificate. Verify that APP_FULL_BASE_URL starts with https:// and that the certificate is trusted by your browser. Clear the extension's cache and cookies (passbolt_data in the extension's storage) before attempting a new login.

Your agency controls its credentials, with no external dependency

Passbolt Community Edition replaces a SaaS subscription with a three-component stack — Docker, PostgreSQL and a reverse proxy — that fits on the VPS you may already have. Per-recipient GPG encryption and per-entry audit logging are not paid options: they are part of the open source core, auditable line by line on GitHub.

When a collaborator leaves the agency, you revoke their access in the interface, and the secrets they held remain encrypted with keys they no longer own. That is the fundamental property that tools designed for personal use — Vaultwarden included — cannot offer you.

Your agency manages credentials for multiple clients

An auditable vault on your own VPS prevents an employee departure from becoming a data leak. Explore our VPS plans and the administration option to delegate stack maintenance.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.