Version: 5.9.0 | Config Location: /etc/passbolt/passbolt.php | Environment: Docker env vars
Passbolt combines web application security with OpenPGP key management. Proper configuration is critical for secret confidentiality, user experience, and operational efficiency. This guide covers all configuration aspects from basic settings to advanced SSO integration.
| File/Location | Purpose | Format |
|---|---|---|
config/passbolt.php |
Main application configuration | PHP array |
.env (Docker) |
Environment variables | Key-value pairs |
config/app.php |
CakePHP framework settings | PHP array |
/etc/passbolt/gpg/ |
GPG key storage | Directory |
File: config/passbolt.php or Docker environment variables
<?php
return [
'App' => [
// Full base URL (REQUIRED)
'fullBaseUrl' => 'https://passbolt.your-domain.com',
// Registration public URL
'registrationPublicUrl' => 'https://passbolt.your-domain.com',
],
// Database configuration
'Datasources' => [
'default' => [
'host' => 'mariadb',
'port' => 3306,
'username' => 'passbolt',
'password' => 'your-secure-password',
'database' => 'passbolt',
'encoding' => 'utf8mb4',
'timezone' => 'UTC',
],
],
// Email configuration
'EmailTransport' => [
'default' => [
'host' => 'smtp.your-domain.com',
'port' => 587,
'username' => 'passbolt@your-domain.com',
'password' => 'your-smtp-password',
'tls' => true,
'timeout' => 30,
],
],
'Email' => [
'default' => [
'from' => 'passbolt@your-domain.com',
'fromName' => 'Passbolt',
],
],
];
For Docker deployments, use environment variables in docker-compose.yml:
services:
passbolt:
environment:
# === Application Settings ===
APP_FULL_BASE_URL: https://passbolt.your-domain.com
PASSBOLT_REGISTRATION_PUBLIC_URL: https://passbolt.your-domain.com
# === Database Configuration ===
DATASOURCES_DEFAULT_HOST: mariadb
DATASOURCES_DEFAULT_PORT: 3306
DATASOURCES_DEFAULT_USERNAME: passbolt
DATASOURCES_DEFAULT_PASSWORD: ${DB_PASSWORD}
DATASOURCES_DEFAULT_DATABASE: passbolt
DATASOURCES_DEFAULT_ENCODING: utf8mb4
# === Email/SMTP Configuration ===
EMAIL_DEFAULT_FROM_NAME: "Passbolt"
EMAIL_DEFAULT_FROM: passbolt@your-domain.com
EMAIL_TRANSPORT_DEFAULT_HOST: smtp.your-domain.com
EMAIL_TRANSPORT_DEFAULT_PORT: 587
EMAIL_TRANSPORT_DEFAULT_USERNAME: ${SMTP_USERNAME}
EMAIL_TRANSPORT_DEFAULT_PASSWORD: ${SMTP_PASSWORD}
EMAIL_TRANSPORT_DEFAULT_TLS: true
EMAIL_TRANSPORT_DEFAULT_TIMEOUT: 30
# === Security Settings ===
PASSBOLT_SECURITY_SALT: ${SECURITY_SALT}
PASSBOLT_SSL_FORCE: true
# === GPG Configuration ===
PASSBOLT_GPG_SERVER_KEY_EMAIL: passbolt@your-domain.com
PASSBOLT_GPG_SERVER_KEY_NAME: "Passbolt Server"
# === JWT Authentication ===
PASSBOLT_JWT_TOKENS_ENABLED: true
PASSBOLT_JWT_TOKENS_EXPIRES: "+1 hour"
# === Feature Flags (v5.x+) ===
PASSBOLT_FEATURE_ENCRYPTED_METADATA: true
PASSBOLT_FEATURE_STANDALONE_NOTES: true
PASSBOLT_FEATURE_DYNAMIC_ROLES: true
Recommended Configuration:
# /etc/mysql/mariadb.conf.d/99-passbolt.cnf
[mysqld]
# Character set
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# Performance tuning
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
# Connection settings
max_connections = 200
wait_timeout = 600
interactive_timeout = 600
# Query cache (MariaDB 10.1+)
query_cache_type = 1
query_cache_size = 64M
query_cache_limit = 2M
For high-traffic deployments:
'Datasources' => [
'default' => [
// Connection pooling
'persistent' => true,
'flags' => [
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
],
// Timezone
'timezone' => 'UTC',
// Quote identifiers
'quoteIdentifiers' => false,
],
],
Gmail/Google Workspace:
EMAIL_TRANSPORT_DEFAULT_HOST: smtp.gmail.com
EMAIL_TRANSPORT_DEFAULT_PORT: 587
EMAIL_TRANSPORT_DEFAULT_USERNAME: passbolt@your-domain.com
EMAIL_TRANSPORT_DEFAULT_PASSWORD: your-app-password
EMAIL_TRANSPORT_DEFAULT_TLS: true
Microsoft 365/Exchange Online:
EMAIL_TRANSPORT_DEFAULT_HOST: smtp.office365.com
EMAIL_TRANSPORT_DEFAULT_PORT: 587
EMAIL_TRANSPORT_DEFAULT_USERNAME: passbolt@your-domain.com
EMAIL_TRANSPORT_DEFAULT_PASSWORD: your-password
EMAIL_TRANSPORT_DEFAULT_TLS: true
SendGrid:
EMAIL_TRANSPORT_DEFAULT_HOST: smtp.sendgrid.net
EMAIL_TRANSPORT_DEFAULT_PORT: 587
EMAIL_TRANSPORT_DEFAULT_USERNAME: apikey
EMAIL_TRANSPORT_DEFAULT_PASSWORD: your-sendgrid-api-key
EMAIL_TRANSPORT_DEFAULT_TLS: true
Mailgun:
EMAIL_TRANSPORT_DEFAULT_HOST: smtp.mailgun.org
EMAIL_TRANSPORT_DEFAULT_PORT: 587
EMAIL_TRANSPORT_DEFAULT_USERNAME: postmaster@your-domain.com
EMAIL_TRANSPORT_DEFAULT_PASSWORD: your-mailgun-password
EMAIL_TRANSPORT_DEFAULT_TLS: true
Postfix Local Relay:
EMAIL_TRANSPORT_DEFAULT_HOST: localhost
EMAIL_TRANSPORT_DEFAULT_PORT: 25
EMAIL_TRANSPORT_DEFAULT_USERNAME: null
EMAIL_TRANSPORT_DEFAULT_PASSWORD: null
EMAIL_TRANSPORT_DEFAULT_TLS: null
Customize email templates in templates/email/:
# Copy default templates
cp -r /usr/share/php/passbolt/templates/email/html \
/etc/passbolt/templates/email/html
# Edit templates
nano /etc/passbolt/templates/email/html/welcome.php
Prerequisites:
https://passbolt.your-domain.com/auth/oidc/callbackConfiguration:
// config/passbolt.php
'Passbolt' => [
'Authentication' => [
'oidc' => [
'enabled' => true,
// Provider settings
'provider' => [
'name' => 'Keycloak',
'issuer' => 'https://keycloak.your-domain.com/realms/your-realm',
'authorization_endpoint' => 'https://keycloak.your-domain.com/realms/your-realm/protocol/openid-connect/auth',
'token_endpoint' => 'https://keycloak.your-domain.com/realms/your-realm/protocol/openid-connect/token',
'userinfo_endpoint' => 'https://keycloak.your-domain.com/realms/your-realm/protocol/openid-connect/userinfo',
'jwks_uri' => 'https://keycloak.your-domain.com/realms/your-realm/protocol/openid-connect/certs',
'end_session_endpoint' => 'https://keycloak.your-domain.com/realms/your-realm/protocol/openid-connect/logout',
],
// Client credentials
'client_id' => 'passbolt',
'client_secret' => 'your-client-secret',
// Scopes
'scope' => 'openid email profile',
// Claims mapping
'claims' => [
'email' => 'email',
'first_name' => 'given_name',
'last_name' => 'family_name',
],
// Security settings
'verify_ssl' => true,
'prompt' => 'login',
// User provisioning
'auto_provision' => true,
'auto_provision_default_group' => 'Users',
'auto_provision_default_role' => 'user',
],
],
],
Client Settings:
Client ID: passbolt
Client Protocol: openid-connect
Access Type: confidential
Valid Redirect URIs: https://passbolt.your-domain.com/auth/oidc/callback
Web Origins: https://passbolt.your-domain.com
Mappers:
Name: email
Mapper Type: User Property
Property: email
Token Claim Name: email
Name: given_name
Mapper Type: User Property
Property: firstName
Token Claim Name: given_name
Name: family_name
Mapper Type: User Property
Property: lastName
Token Claim Name: family_name
'Passbolt' => [
'Authentication' => [
'oidc' => [
'enabled' => true,
'provider' => [
'name' => 'Azure AD',
'issuer' => 'https://login.microsoftonline.com/{tenant-id}/v2.0',
'authorization_endpoint' => 'https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/authorize',
'token_endpoint' => 'https://login.microsoftonline.com/{tenant-id}/oauth2/v2.0/token',
'userinfo_endpoint' => 'https://graph.microsoft.com/oidc/userinfo',
'jwks_uri' => 'https://login.microsoftonline.com/{tenant-id}/discovery/v2.0/keys',
],
'client_id' => 'your-application-id',
'client_secret' => 'your-client-secret',
'scope' => 'openid email profile',
'claims' => [
'email' => 'email',
'first_name' => 'given_name',
'last_name' => 'family_name',
],
],
],
],
'Passbolt' => [
'Authentication' => [
'oidc' => [
'enabled' => true,
'provider' => [
'name' => 'Google',
'issuer' => 'https://accounts.google.com',
'authorization_endpoint' => 'https://accounts.google.com/o/oauth2/v2/auth',
'token_endpoint' => 'https://oauth2.googleapis.com/token',
'userinfo_endpoint' => 'https://www.googleapis.com/oauth2/v2/userinfo',
'jwks_uri' => 'https://www.googleapis.com/oauth2/v3/certs',
],
'client_id' => 'your-google-client-id',
'client_secret' => 'your-google-client-secret',
'scope' => 'openid email profile',
],
],
],
'Passbolt' => [
'Authentication' => [
'saml' => [
'enabled' => true,
'idp' => [
'entity_id' => 'https://idp.your-domain.com/saml',
'sso_url' => 'https://idp.your-domain.com/saml/sso',
'slo_url' => 'https://idp.your-domain.com/saml/slo',
'x509cert' => '-----BEGIN CERTIFICATE-----...',
],
'sp' => [
'entity_id' => 'https://passbolt.your-domain.com',
'acs_url' => 'https://passbolt.your-domain.com/auth/saml/acs',
'slo_url' => 'https://passbolt.your-domain.com/auth/saml/slo',
],
'security' => [
'signature_algorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
'digest_algorithm' => 'http://www.w3.org/2001/04/xmlenc#sha256',
],
],
],
],
'Passbolt' => [
'Authentication' => [
'ldap' => [
'enabled' => true,
// Server settings
'host' => 'ldap.your-domain.com',
'port' => 389,
'use_ssl' => false,
'use_tls' => true,
// Bind settings
'bind_dn' => 'cn=passbolt,ou=services,dc=example,dc=com',
'bind_password' => 'your-ldap-password',
// User search
'base_dn' => 'dc=example,dc=com',
'filter' => '(objectClass=inetOrgPerson)',
'user_field' => 'uid',
'email_field' => 'mail',
'first_name_field' => 'givenName',
'last_name_field' => 'sn',
// Group sync (optional)
'group_base_dn' => 'ou=groups,dc=example,dc=com',
'group_filter' => '(objectClass=groupOfNames)',
'group_member_field' => 'member',
],
],
],
'Passbolt' => [
'Authentication' => [
'ldap' => [
'enabled' => true,
'host' => 'ad.your-domain.com',
'port' => 636,
'use_ssl' => true,
'use_tls' => false,
'bind_dn' => 'CN=Passbolt Service,CN=Users,DC=example,DC=com',
'bind_password' => 'your-ad-password',
'base_dn' => 'DC=example,DC=com',
'filter' => '(&(objectClass=user)(objectCategory=person))',
'user_field' => 'sAMAccountName',
'email_field' => 'mail',
'first_name_field' => 'givenName',
'last_name_field' => 'sn',
],
],
],
# Generate server GPG key
docker compose exec passbolt su -m -c \
"gpg --batch --gen-key" -s /bin/sh www-data <<EOF
Key-Type: RSA
Key-Length: 4096
Name-Real: Passbolt Server
Name-Email: passbolt@your-domain.com
Expire-Date: 0
%no-protection
%commit
EOF
# Export public key
docker compose exec passbolt gpg --export \
--armor passbolt@your-domain.com > server_public.key
# Backup private key securely
docker compose exec passbolt gpg --export-secret-keys \
--armor passbolt@your-domain.com > server_private.key.asc
chmod 600 server_private.key.asc
Encrypted Metadata Key Rotation (v5.6+):
⚠️ Important: Key rotation is disabled while a previous migration is in progress. Ensure all users have updated clients before rotating.
Enforce key verification during onboarding:
'Passbolt' => [
'Security' => [
// Require key verification on first login
'require_key_verification' => true,
// Key strength requirements
'min_key_length' => 2048,
'allowed_algorithms' => ['RSA', 'EdDSA'],
],
],
Default Roles:
Custom Roles (max 2):
'Passbolt' => [
'Roles' => [
'custom' => [
[
'name' => 'Manager',
'description' => 'Team manager with group management',
'permissions' => [
'groups.create' => true,
'groups.edit' => true,
'users.view' => true,
],
],
[
'name' => 'Auditor',
'description' => 'Read-only audit access',
'permissions' => [
'logs.view' => true,
'reports.view' => true,
'users.view' => true,
'resources.view' => true,
],
],
],
],
],
'Passbolt' => [
'Groups' => [
// Default group for new users
'default_group' => 'Users',
// Auto-assign groups by email domain
'auto_assign' => [
[
'domain' => 'engineering.your-domain.com',
'group' => 'Engineering',
],
[
'domain' => 'operations.your-domain.com',
'group' => 'Operations',
],
],
],
],
'Session' => [
// Session timeout (2 hours)
'timeout' => 7200,
// Cookie settings
'cookie' => [
'secure' => true,
'httpOnly' => true,
'sameSite' => 'Strict',
],
// Session handler
'handler' => [
'engine' => 'Cache',
'config' => 'default',
],
],
'Passbolt' => [
'Authentication' => [
// MFA settings
'mfa' => [
'enabled' => true,
'required_for_admins' => true,
'required_for_roles' => ['admin', 'manager'],
// TOTP settings
'totp' => [
'issuer' => 'Passbolt',
'digits' => 6,
'period' => 30,
'algorithm' => 'SHA1',
],
],
// Password policy
'password_policy' => [
'min_length' => 12,
'require_uppercase' => true,
'require_lowercase' => true,
'require_numbers' => true,
'require_special' => true,
'max_age_days' => 90,
],
// Account lockout
'lockout' => [
'enabled' => true,
'max_attempts' => 5,
'lockout_duration_minutes' => 30,
],
],
],
What to Backup:
| Component | Location | Frequency |
|---|---|---|
| Database | MariaDB/MySQL | Daily |
| GPG Keys | /etc/passbolt/gpg/ |
After changes |
| Configuration | config/passbolt.php |
After changes |
| Environment | .env file |
After changes |
Backup Script:
#!/bin/bash
set -e
BACKUP_DIR="/backup/passbolt/$(date +%F)"
mkdir -p $BACKUP_DIR
# Database backup
mysqldump -u passbolt -p${DB_PASSWORD} \
--single-transaction \
--routines \
--triggers \
passbolt > $BACKUP_DIR/database.sql
# GPG keys backup
gpg --export-secret-keys --armor passbolt@your-domain.com \
> $BACKUP_DIR/gpg-keys.asc
chmod 600 $BACKUP_DIR/gpg-keys.asc
# Configuration backup
cp /etc/passbolt/passbolt.php $BACKUP_DIR/
cp /etc/passbolt/.env $BACKUP_DIR/ 2>/dev/null || true
# Compress backup
tar -czf $BACKUP_DIR.tar.gz -C $BACKUP_DIR .
rm -rf $BACKUP_DIR
# Upload to remote storage (optional)
# aws s3 cp $BACKUP_DIR.tar.gz s3://your-bucket/passbolt/
# Cleanup old backups
find /backup/passbolt -name "*.tar.gz" -mtime +30 -delete
echo "Backup completed: $BACKUP_DIR.tar.gz"
Test Recovery Quarterly:
# 1. Restore to test environment
tar -xzf passbolt_backup_2025-01-15.tar.gz -C /tmp/restore
# 2. Restore database
mysql -u root -p passbolt < /tmp/restore/database.sql
# 3. Import GPG keys
gpg --import /tmp/restore/gpg-keys.asc
# 4. Restore configuration
cp /tmp/restore/passbolt.php /etc/passbolt/
# 5. Verify functionality
sudo -u www-data /usr/share/php/passbolt/bin/cake passbolt healthcheck
# 6. Test login and decryption
# - Login with test account
# - Decrypt shared secret
# - Verify API token operations
# /etc/php/8.2/fpm/pool.d/passbolt.conf
[passbolt]
user = www-data
group = www-data
listen = /run/php/passbolt-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660
pm = dynamic
pm.max_children = 20
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.max_requests = 500
php_admin_value[upload_max_filesize] = 10M
php_admin_value[post_max_size] = 10M
php_admin_value[max_execution_time] = 60
php_admin_value[memory_limit] = 256M
server {
listen 443 ssl http2;
server_name passbolt.your-domain.com;
root /usr/share/php/passbolt/webroot;
index index.php;
# SSL configuration
ssl_certificate /etc/letsencrypt/live/passbolt.your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/passbolt.your-domain.com/privkey.pem;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Gzip compression
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
# Cache static assets
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/passbolt-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_read_timeout 60;
}
}
'Log' => [
'debug' => [
'className' => 'Cake\Log\Engine\FileLog',
'path' => LOGS,
'level' => 'debug',
'scopes' => [],
'file' => 'debug',
],
'error' => [
'className' => 'Cake\Log\Engine\FileLog',
'path' => LOGS,
'level' => 'error',
'scopes' => [],
'file' => 'error',
],
'audit' => [
'className' => 'Cake\Log\Engine\SyslogLog',
'prefix' => 'passbolt-audit-',
],
],
| Endpoint | Purpose | Response |
|---|---|---|
/health.json |
Basic health check | {"status": "OK"} |
/healthcheck |
Detailed health check | HTML report |
cake passbolt healthcheck |
CLI health check | Console output |
Any questions?
Feel free to contact us. Find all contact information on our contact page.