Add Vaultwarden password manager role with PostgreSQL and SSO support

- Implement complete Vaultwarden deployment using Podman Quadlet
- PostgreSQL backend via Unix socket with 777 permissions
- Caddy reverse proxy with WebSocket support for live sync
- Control-node admin token hashing using argon2 (OWASP preset)
- Idempotent token hashing with deterministic salt generation
- Full Authentik SSO integration following official guide
- SMTP email configuration support (optional)
- Invitation-only user registration by default
- Comprehensive documentation with setup and troubleshooting guides

Technical Details:
- Container: vaultwarden/server:latest from Docker Hub
- Database: PostgreSQL via /var/run/postgresql socket
- Port: 8080 (localhost only, proxied by Caddy)
- Domain: vault.jnss.me
- Admin token: Hashed on control node with argon2id
- SSO: OpenID Connect with offline_access scope support

Role includes automatic argon2 installation on control node if needed.
This commit is contained in:
2025-12-21 16:13:25 +01:00
parent 89b43180fc
commit bfd6f22f0e
14 changed files with 1346 additions and 3 deletions

View File

@@ -0,0 +1,35 @@
# Vaultwarden Password Manager
{{ vaultwarden_domain }} {
# Notifications endpoint (WebSocket for live sync)
@websocket {
path /notifications/hub
}
reverse_proxy @websocket http://127.0.0.1:{{ vaultwarden_http_port }} {
header_up Upgrade {http.request.header.Upgrade}
header_up Connection {http.request.header.Connection}
}
# Regular HTTP traffic
reverse_proxy http://127.0.0.1:{{ vaultwarden_http_port }} {
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-Proto https
header_up X-Forwarded-For {remote_host}
}
# Security headers
header {
X-Frame-Options SAMEORIGIN
X-Content-Type-Options nosniff
X-XSS-Protection "1; mode=block"
Referrer-Policy strict-origin-when-cross-origin
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
}
# Logging
log {
output file {{ caddy_log_dir }}/vaultwarden.log
level INFO
format json
}
}

View File

@@ -0,0 +1,26 @@
[Unit]
Description=Vaultwarden Password Manager Container
After=network-online.target postgresql.service
Wants=network-online.target
[Container]
ContainerName=vaultwarden
Image={{ vaultwarden_image }}:{{ vaultwarden_version }}
EnvironmentFile={{ vaultwarden_home }}/.env
# Volume mounts
# Application data (includes database, attachments, sends, icons, etc.)
Volume={{ vaultwarden_data_dir }}:/data:Z
# Infrastructure socket (PostgreSQL access with 777 permissions on host)
Volume={{ postgresql_unix_socket_directories }}:{{ postgresql_unix_socket_directories }}:Z
# Expose HTTP port to localhost only (Caddy will reverse proxy)
PublishPort=127.0.0.1:{{ vaultwarden_http_port }}:80
[Service]
Restart=always
TimeoutStartSec=300
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,73 @@
# Vaultwarden Environment Configuration
# Generated by Ansible - DO NOT EDIT MANUALLY
# =================================================================
# Database Configuration (PostgreSQL via Unix Socket)
# =================================================================
DATABASE_URL=postgresql://{{ vaultwarden_db_user }}:{{ vaultwarden_db_password }}@/{{ vaultwarden_db_name }}?host={{ postgresql_unix_socket_directories }}
# =================================================================
# Domain Configuration
# =================================================================
DOMAIN=https://{{ vaultwarden_domain }}
# =================================================================
# Admin Configuration
# =================================================================
ADMIN_TOKEN={{ vaultwarden_admin_token_hashed }}
# =================================================================
# Registration and Invitation Controls
# =================================================================
SIGNUPS_ALLOWED={{ vaultwarden_signups_allowed | lower }}
INVITATIONS_ALLOWED={{ vaultwarden_invitations_allowed | lower }}
SHOW_PASSWORD_HINT={{ vaultwarden_show_password_hint | lower }}
# =================================================================
# WebSocket Configuration (for live sync)
# =================================================================
WEBSOCKET_ENABLED={{ vaultwarden_websocket_enabled | lower }}
# =================================================================
# SMTP Configuration (Optional)
# =================================================================
{% if vaultwarden_smtp_enabled %}
SMTP_HOST={{ vaultwarden_smtp_host }}
SMTP_PORT={{ vaultwarden_smtp_port }}
SMTP_FROM={{ vaultwarden_smtp_from }}
SMTP_SECURITY={{ vaultwarden_smtp_security }}
{% if vaultwarden_smtp_username %}
SMTP_USERNAME={{ vaultwarden_smtp_username }}
SMTP_PASSWORD={{ vaultwarden_smtp_password }}
{% endif %}
{% endif %}
# =================================================================
# SSO Configuration (Optional - Authentik Integration)
# =================================================================
{% if vaultwarden_sso_enabled %}
SSO_ENABLED=true
SSO_ONLY={{ vaultwarden_sso_only | lower }}
SSO_CLIENT_ID={{ vaultwarden_sso_client_id }}
SSO_CLIENT_SECRET={{ vaultwarden_sso_client_secret }}
SSO_AUTHORITY={{ vaultwarden_sso_authority }}
SSO_SCOPES="{{ vaultwarden_sso_scopes }}"
SSO_SIGNUPS_MATCH_EMAIL={{ vaultwarden_sso_signups_match_email | lower }}
SSO_ALLOW_UNKNOWN_EMAIL_VERIFICATION={{ vaultwarden_sso_allow_unknown_email_verification | lower }}
SSO_CLIENT_CACHE_EXPIRATION={{ vaultwarden_sso_client_cache_expiration }}
{% if vaultwarden_sso_signups_domains_whitelist %}
SSO_SIGNUPS_DOMAINS_WHITELIST={{ vaultwarden_sso_signups_domains_whitelist }}
{% endif %}
{% endif %}
# =================================================================
# Security and Performance
# =================================================================
# Disable user registration via email (use admin panel or invitations)
SIGNUPS_VERIFY=false
# Log level (trace, debug, info, warn, error, off)
LOG_LEVEL=info
# Rocket configuration
ROCKET_WORKERS=10