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:
331
roles/vaultwarden/README.md
Normal file
331
roles/vaultwarden/README.md
Normal file
@@ -0,0 +1,331 @@
|
||||
# Vaultwarden Password Manager Role
|
||||
|
||||
Self-contained Vaultwarden (Bitwarden-compatible) password manager deployment using Podman and PostgreSQL.
|
||||
|
||||
## Overview
|
||||
|
||||
This role deploys Vaultwarden as a Podman Quadlet container with:
|
||||
- **PostgreSQL backend** via Unix socket (777 permissions)
|
||||
- **Caddy reverse proxy** with HTTPS and WebSocket support
|
||||
- **SSO integration** ready (Authentik OpenID Connect)
|
||||
- **SMTP support** for email notifications (optional)
|
||||
- **Admin panel** for management
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Internet → Caddy (HTTPS) → Vaultwarden Container → PostgreSQL (Unix socket)
|
||||
↓
|
||||
/data volume
|
||||
```
|
||||
|
||||
### Components
|
||||
|
||||
- **Container Image**: `vaultwarden/server:latest` (Docker Hub)
|
||||
- **User**: System user `vaultwarden` (non-root)
|
||||
- **Port**: 8080 (localhost only)
|
||||
- **Domain**: `vault.jnss.me`
|
||||
- **Database**: PostgreSQL via Unix socket at `/var/run/postgresql`
|
||||
- **Data**: `/opt/vaultwarden/data`
|
||||
|
||||
## Dependencies
|
||||
|
||||
**Managed Hosts:**
|
||||
- `postgresql` role (provides database and Unix socket)
|
||||
- `caddy` role (provides reverse proxy)
|
||||
|
||||
**Control Node:**
|
||||
- `argon2` command-line tool (automatically installed if not present)
|
||||
- Used to hash the admin token securely on the control node
|
||||
- Available in most package managers: `pacman -S argon2`, `apt install argon2`, etc.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Required Variables
|
||||
|
||||
Must be defined in vault (e.g., `group_vars/homelab/vault.yml`):
|
||||
|
||||
```yaml
|
||||
# Database password
|
||||
vault_vaultwarden_db_password: "secure-database-password"
|
||||
|
||||
# Admin token (plain text - will be hashed automatically during deployment)
|
||||
vault_vaultwarden_admin_token: "your-secure-admin-token"
|
||||
|
||||
# SMTP password (if using email)
|
||||
vault_vaultwarden_smtp_password: "smtp-password" # optional
|
||||
|
||||
# SSO credentials (if using Authentik integration)
|
||||
vault_vaultwarden_sso_client_id: "vaultwarden" # optional
|
||||
vault_vaultwarden_sso_client_secret: "sso-secret" # optional
|
||||
```
|
||||
|
||||
### Optional Variables
|
||||
|
||||
Override in `group_vars` or `host_vars`:
|
||||
|
||||
```yaml
|
||||
# Domain
|
||||
vaultwarden_domain: "vault.jnss.me"
|
||||
|
||||
# Container version
|
||||
vaultwarden_version: "latest"
|
||||
|
||||
# Registration controls
|
||||
vaultwarden_signups_allowed: false # Disable open registration
|
||||
vaultwarden_invitations_allowed: true # Allow existing users to invite
|
||||
|
||||
# SMTP Configuration
|
||||
vaultwarden_smtp_enabled: true
|
||||
vaultwarden_smtp_host: "smtp.example.com"
|
||||
vaultwarden_smtp_port: 587
|
||||
vaultwarden_smtp_from: "vault@jnss.me"
|
||||
vaultwarden_smtp_username: "smtp-user"
|
||||
|
||||
# SSO Configuration (Authentik)
|
||||
vaultwarden_sso_enabled: true
|
||||
vaultwarden_sso_authority: "https://auth.jnss.me"
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Deploy Vaultwarden
|
||||
|
||||
```bash
|
||||
# Full deployment
|
||||
ansible-playbook rick-infra.yml --tags vaultwarden
|
||||
|
||||
# Or via site.yml
|
||||
ansible-playbook site.yml --tags vaultwarden -l homelab
|
||||
```
|
||||
|
||||
### Access Admin Panel
|
||||
|
||||
1. Set admin token in vault file (plain text):
|
||||
```yaml
|
||||
# Generate a secure token
|
||||
vault_vaultwarden_admin_token: "$(openssl rand -base64 32)"
|
||||
```
|
||||
|
||||
2. The role automatically hashes the token during deployment:
|
||||
- Hashing occurs on the **control node** using `argon2` CLI
|
||||
- Uses OWASP recommended settings (19MiB memory, 2 iterations, 1 thread)
|
||||
- Idempotent: same token always produces the same hash
|
||||
- The `argon2` package is automatically installed if not present
|
||||
|
||||
3. Access: `https://vault.jnss.me/admin` (use the plain text token from step 1)
|
||||
|
||||
### Configure SSO (Authentik Integration)
|
||||
|
||||
> ⚠️ **IMPORTANT: SSO Feature Status (as of December 2025)**
|
||||
>
|
||||
> SSO is currently **only available in `vaultwarden/server:testing` images**.
|
||||
> The stable release (v1.34.3) does **NOT** include SSO functionality.
|
||||
>
|
||||
> **Current Deployment Status:**
|
||||
> - This role is configured with SSO settings ready for when SSO reaches stable release
|
||||
> - Using `vaultwarden_version: "latest"` (stable) - SSO will not appear
|
||||
> - To test SSO now: Set `vaultwarden_version: "testing"` (not recommended for production)
|
||||
> - To wait for stable: Keep current configuration, SSO will activate automatically when available
|
||||
>
|
||||
> **References:**
|
||||
> - [Vaultwarden Wiki - SSO Documentation](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-SSO-support-using-OpenId-Connect)
|
||||
> - [Vaultwarden Testing Features](https://github.com/dani-garcia/vaultwarden/wiki#testing-features)
|
||||
>
|
||||
> **Decision:** This deployment keeps SSO configured but uses stable image until SSO feature is production-ready.
|
||||
|
||||
Following the [Authentik integration guide](https://integrations.goauthentik.io/security/vaultwarden/):
|
||||
|
||||
1. **In Authentik**: Create OAuth2/OpenID Provider
|
||||
- **Name**: `Vaultwarden`
|
||||
- **Client Type**: `Confidential`
|
||||
- **Redirect URIs**: `https://vault.jnss.me/identity/connect/oidc-signin` (must be strict/exact match)
|
||||
- **Scopes**: Under "Advanced protocol settings", ensure these scope mappings are selected:
|
||||
- `authentik default OAuth Mapping: OpenID 'openid'`
|
||||
- `authentik default OAuth Mapping: OpenID 'email'`
|
||||
- `authentik default OAuth Mapping: OpenID 'profile'`
|
||||
- `authentik default OAuth Mapping: OpenID 'offline_access'` ⚠️ **Required**
|
||||
- **Access token validity**: Set to more than 5 minutes
|
||||
- **Note the Client ID, Client Secret, and application slug** (from URL or provider settings)
|
||||
|
||||
2. **Update Vault Variables**:
|
||||
```yaml
|
||||
vault_vaultwarden_sso_client_id: "<client-id-from-authentik>"
|
||||
vault_vaultwarden_sso_client_secret: "<client-secret-from-authentik>"
|
||||
```
|
||||
|
||||
3. **Enable SSO and set authority** in `group_vars/homelab/main.yml`:
|
||||
```yaml
|
||||
vaultwarden_sso_enabled: true
|
||||
# Replace 'vaultwarden' with your actual application slug
|
||||
vaultwarden_sso_authority: "https://auth.jnss.me/application/o/vaultwarden/"
|
||||
```
|
||||
|
||||
4. **Optional: SSO-Only Mode** (disable password login):
|
||||
```yaml
|
||||
vaultwarden_sso_only: true # Requires SSO, disables email+password
|
||||
```
|
||||
|
||||
5. **Redeploy**:
|
||||
```bash
|
||||
ansible-playbook rick-infra.yml --tags vaultwarden
|
||||
```
|
||||
|
||||
6. **Test**: Log out, enter a verified email on login page, click "Use single sign-on"
|
||||
- **Note**: With `vaultwarden_version: "latest"`, SSO button will not appear (feature not in stable yet)
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Database Access
|
||||
|
||||
- Uses PostgreSQL Unix socket with **777 permissions**
|
||||
- Security maintained via password authentication (scram-sha-256)
|
||||
- See: `docs/socket-permissions-architecture.md`
|
||||
|
||||
### Admin Token
|
||||
|
||||
- **Never commit plain admin token to git**
|
||||
- Use Ansible Vault for `vault_vaultwarden_admin_token`
|
||||
- Rotate periodically via admin panel
|
||||
|
||||
### User Registration
|
||||
|
||||
- Default: **Disabled** (`vaultwarden_signups_allowed: false`)
|
||||
- Users must be invited by existing users or created via admin panel
|
||||
- Prevents unauthorized account creation
|
||||
|
||||
## Maintenance
|
||||
|
||||
### Backup
|
||||
|
||||
Backup the following:
|
||||
|
||||
```bash
|
||||
# Database backup (via PostgreSQL role)
|
||||
sudo -u postgres pg_dump vaultwarden > vaultwarden-backup.sql
|
||||
|
||||
# Data directory (attachments, icons, etc.)
|
||||
tar -czf vaultwarden-data-backup.tar.gz /opt/vaultwarden/data
|
||||
```
|
||||
|
||||
### Update Container
|
||||
|
||||
```bash
|
||||
# Pull new image and restart
|
||||
ansible-playbook rick-infra.yml --tags vaultwarden
|
||||
```
|
||||
|
||||
### View Logs
|
||||
|
||||
```bash
|
||||
# Service logs
|
||||
journalctl -u vaultwarden -f
|
||||
|
||||
# Container logs
|
||||
podman logs vaultwarden -f
|
||||
```
|
||||
|
||||
### Restart Service
|
||||
|
||||
```bash
|
||||
systemctl restart vaultwarden
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Container won't start
|
||||
|
||||
```bash
|
||||
# Check container status
|
||||
systemctl status vaultwarden
|
||||
|
||||
# Check container directly
|
||||
podman ps -a
|
||||
podman logs vaultwarden
|
||||
|
||||
# Verify database connectivity
|
||||
sudo -u vaultwarden psql -h /var/run/postgresql -U vaultwarden -d vaultwarden -c "SELECT 1;"
|
||||
```
|
||||
|
||||
### Database connection errors
|
||||
|
||||
1. Verify PostgreSQL is running: `systemctl status postgresql`
|
||||
2. Check socket exists: `ls -la /var/run/postgresql/.s.PGSQL.5432`
|
||||
3. Verify socket permissions: Should be `srwxrwxrwx` (777)
|
||||
4. Test connection as vaultwarden user (see above)
|
||||
|
||||
### Can't access admin panel
|
||||
|
||||
1. Verify admin token is set in vault file (plain text)
|
||||
2. Check that the token was hashed successfully during deployment
|
||||
3. Ensure you're using the plain text token to log in
|
||||
4. Redeploy to regenerate hash if needed
|
||||
|
||||
### SSO not appearing / not working
|
||||
|
||||
**Most Common Issue: Using Stable Image**
|
||||
|
||||
SSO is only available in testing images. Check your deployment:
|
||||
|
||||
```bash
|
||||
# Check current image version
|
||||
podman inspect vaultwarden --format '{{.ImageName}}'
|
||||
|
||||
# Check API config for SSO support
|
||||
curl -s http://127.0.0.1:8080/api/config | grep -o '"sso":"[^"]*"'
|
||||
# Empty string "" = SSO not available in this image
|
||||
# URL present = SSO is available
|
||||
```
|
||||
|
||||
**If using `vaultwarden_version: "latest"`**: SSO will not appear (feature not in stable yet)
|
||||
- **To test SSO**: Set `vaultwarden_version: "testing"` in role defaults or group/host vars
|
||||
- **For production**: Wait for SSO to reach stable release (recommended)
|
||||
|
||||
**If using `vaultwarden_version: "testing"` and SSO still not working**:
|
||||
|
||||
1. Verify Authentik provider configuration:
|
||||
- Check that `offline_access` scope mapping is added
|
||||
- Verify redirect URI matches exactly: `https://vault.jnss.me/identity/connect/oidc-signin`
|
||||
- Ensure access token validity is > 5 minutes
|
||||
2. Verify SSO authority URL includes full path with slug:
|
||||
- Should be: `https://auth.jnss.me/application/o/<your-slug>/`
|
||||
- Not just: `https://auth.jnss.me`
|
||||
3. Check client ID and secret in vault match Authentik
|
||||
4. Verify all required scopes: `openid email profile offline_access`
|
||||
5. Check Vaultwarden logs for SSO-related errors:
|
||||
```bash
|
||||
podman logs vaultwarden 2>&1 | grep -i sso
|
||||
```
|
||||
6. Test SSO flow: Log out, enter verified email, click "Use single sign-on"
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
roles/vaultwarden/
|
||||
├── defaults/
|
||||
│ └── main.yml # Default variables
|
||||
├── handlers/
|
||||
│ └── main.yml # Service restart handlers
|
||||
├── meta/
|
||||
│ └── main.yml # Role dependencies
|
||||
├── tasks/
|
||||
│ ├── main.yml # Main orchestration
|
||||
│ ├── user.yml # User and directory setup
|
||||
│ └── database.yml # PostgreSQL setup
|
||||
├── templates/
|
||||
│ ├── vaultwarden.container # Quadlet container definition
|
||||
│ ├── vaultwarden.env.j2 # Environment configuration
|
||||
│ └── vaultwarden.caddy.j2 # Caddy reverse proxy config
|
||||
└── README.md # This file
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
- [Vaultwarden Documentation](https://github.com/dani-garcia/vaultwarden/wiki)
|
||||
- [PostgreSQL Backend Guide](https://github.com/dani-garcia/vaultwarden/wiki/Using-the-PostgreSQL-Backend)
|
||||
- [SSO Configuration](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-SSO-support-using-OpenId-Connect)
|
||||
- [Socket Permissions Architecture](../../docs/socket-permissions-architecture.md)
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
Reference in New Issue
Block a user