From bfd6f22f0e2f81d0e027ea55161053eb9db3d403 Mon Sep 17 00:00:00 2001 From: Joakim Date: Sun, 21 Dec 2025 16:13:25 +0100 Subject: [PATCH] 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. --- docs/vaultwarden-sso-status.md | 307 ++++++++++++++++ rick-infra.yml | 12 +- roles/vaultwarden/README.md | 331 ++++++++++++++++++ roles/vaultwarden/VAULT_VARIABLES.md | 171 +++++++++ roles/vaultwarden/defaults/main.yml | 109 ++++++ roles/vaultwarden/handlers/main.yml | 16 + roles/vaultwarden/meta/main.yml | 25 ++ roles/vaultwarden/tasks/database.yml | 51 +++ roles/vaultwarden/tasks/hash_admin_token.yml | 57 +++ roles/vaultwarden/tasks/main.yml | 108 ++++++ roles/vaultwarden/tasks/user.yml | 28 ++ .../templates/vaultwarden.caddy.j2 | 35 ++ .../templates/vaultwarden.container | 26 ++ .../vaultwarden/templates/vaultwarden.env.j2 | 73 ++++ 14 files changed, 1346 insertions(+), 3 deletions(-) create mode 100644 docs/vaultwarden-sso-status.md create mode 100644 roles/vaultwarden/README.md create mode 100644 roles/vaultwarden/VAULT_VARIABLES.md create mode 100644 roles/vaultwarden/defaults/main.yml create mode 100644 roles/vaultwarden/handlers/main.yml create mode 100644 roles/vaultwarden/meta/main.yml create mode 100644 roles/vaultwarden/tasks/database.yml create mode 100644 roles/vaultwarden/tasks/hash_admin_token.yml create mode 100644 roles/vaultwarden/tasks/main.yml create mode 100644 roles/vaultwarden/tasks/user.yml create mode 100644 roles/vaultwarden/templates/vaultwarden.caddy.j2 create mode 100644 roles/vaultwarden/templates/vaultwarden.container create mode 100644 roles/vaultwarden/templates/vaultwarden.env.j2 diff --git a/docs/vaultwarden-sso-status.md b/docs/vaultwarden-sso-status.md new file mode 100644 index 0000000..e76bc56 --- /dev/null +++ b/docs/vaultwarden-sso-status.md @@ -0,0 +1,307 @@ +# Vaultwarden SSO Feature Status and Configuration + +**Document Date:** December 21, 2025 +**Last Updated:** December 21, 2025 +**Status:** SSO Configured, Waiting for Stable Release + +--- + +## Executive Summary + +Vaultwarden has been successfully deployed with **SSO integration pre-configured** for Authentik. However, SSO functionality is currently **only available in testing images** and not yet in the stable release. This document explains the current state, our decision to wait for stable, and how to activate SSO when it becomes available. + +## Current Deployment Status + +### What's Working +- ✅ Vaultwarden deployed successfully at `https://vault.jnss.me` +- ✅ PostgreSQL backend via Unix socket +- ✅ Admin panel accessible and working +- ✅ Email/password authentication working +- ✅ SMTP notifications configured +- ✅ All SSO environment variables correctly configured +- ✅ Authentik OAuth2 provider created and ready + +### What's Not Working (By Design) +- ❌ SSO login option not appearing on login page +- ❌ "Use single sign-on" button missing + +**Reason:** Using stable image (`vaultwarden/server:latest` v1.34.3) which does not include SSO code. + +## Investigation Summary (Dec 21, 2025) + +### Problem Reported +User deployed Vaultwarden with `vaultwarden_sso_enabled: true` and configured Authentik integration following official guides, but no SSO option appeared on the login page. + +### Root Cause Identified +After investigation including: +- Service status check (healthy, running normally) +- Environment variable verification (all SSO vars present and correct) +- Configuration review (matches Authentik integration guide perfectly) +- API endpoint inspection (`/api/config` returns `"sso":""`) +- Official documentation review + +**Finding:** SSO feature is only compiled into `vaultwarden/server:testing` images, not stable releases. + +### Evidence + +From [Vaultwarden Official Wiki](https://github.com/dani-garcia/vaultwarden/wiki): + +> **Testing features** +> +> Features available in the `testing` docker image: +> - Single Sign-On (SSO), see [Documentation](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-SSO-support-using-OpenId-Connect) + +From [SSO Documentation Page](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-SSO-support-using-OpenId-Connect): + +> ⚠️ **Important** +> +> ‼️ ‼️ ‼️ +> SSO is currently only available in the `:testing` tagged images! +> The current stable `v1.34.3` **does not** contain the SSO feature. +> ‼️ ‼️ ‼️ + +### API Response Analysis + +```bash +# API config endpoint shows SSO not available +curl -s http://127.0.0.1:8080/api/config | grep -o '"sso":"[^"]*"' +# Returns: "sso":"" ← Empty = feature not compiled in + +# Environment variables are set correctly +podman exec vaultwarden env | grep -i sso +SSO_ENABLED=true +SSO_ONLY=false +SSO_CLIENT_ID=DDOQXdwFn6pi4FtSvo7PK5b63pRzyD552xapTZGr +SSO_CLIENT_SECRET=02D308Sle2w2NPsi7UaXb3bvKKK4punFDT2LiVqKpzvEFqgPpyLysA8Z5yS4g8t4LYmsI9txLE02l5MtWP5R2RBavLhYHjNFHcwEmvYB94bOJw45YmgiGePaW4NHKcfY +SSO_AUTHORITY=https://auth.jnss.me/application/o/vaultwarden/ +SSO_SCOPES="openid email profile offline_access" +# ... etc (all correct) +``` + +**Conclusion:** Environment configured correctly, feature simply not available in stable release. + +## Decision: Wait for Stable Release + +### Rationale + +**Why NOT switch to testing image:** +1. **Production stability** - This is a password manager handling sensitive credentials +2. **Testing images are volatile** - Frequent updates, potential bugs +3. **No ETA for stable** - SSO marked as "testing feature" indefinitely +4. **Current auth works fine** - Email/password login is secure and functional +5. **Configuration is ready** - When SSO reaches stable, it will work immediately + +**Why keep SSO configured:** +1. **Future-ready** - No additional work needed when SSO stabilizes +2. **No harm** - Environment variables are ignored by stable image +3. **Documentation** - Clear record of SSO setup for future reference +4. **Authentik provider ready** - Already created and configured + +### Alternatives Considered + +| Option | Pros | Cons | Decision | +|--------|------|------|----------| +| Use `testing` image | SSO available now | Unstable, potential data loss, frequent breaking changes | ❌ Rejected | +| Wait for stable | Stable, reliable, secure | No SSO until unknown future date | ✅ **Selected** | +| Remove SSO config | Cleaner config | Requires reconfiguration later | ❌ Rejected | +| Dual deployment | Test SSO separately | Resource waste, complexity | ❌ Rejected | + +## Current Configuration + +### Ansible Role Variables + +Location: `roles/vaultwarden/defaults/main.yml` + +```yaml +# Container version (stable, no SSO) +vaultwarden_version: "latest" + +# SSO enabled (ready for when feature reaches stable) +vaultwarden_sso_enabled: true +vaultwarden_sso_only: false +vaultwarden_sso_client_id: "{{ vault_vaultwarden_sso_client_id }}" +vaultwarden_sso_client_secret: "{{ vault_vaultwarden_sso_client_secret }}" +vaultwarden_sso_authority: "https://auth.jnss.me/application/o/vaultwarden/" +vaultwarden_sso_scopes: "openid email profile offline_access" +vaultwarden_sso_signups_match_email: true +vaultwarden_sso_allow_unknown_email_verification: false +vaultwarden_sso_client_cache_expiration: 0 +``` + +### Vault Variables (Encrypted) + +Location: `group_vars/homelab/vault.yml` + +```yaml +# SSO credentials from Authentik +vault_vaultwarden_sso_client_id: "DDOQXdwFn6pi4FtSvo7PK5b63pRzyD552xapTZGr" +vault_vaultwarden_sso_client_secret: "02D308Sle2w2NPsi7UaXb3bvKKK4punFDT2LiVqKpzvEFqgPpyLysA8Z5yS4g8t4LYmsI9txLE02l5MtWP5R2RBavLhYHjNFHcwEmvYB94bOJw45YmgiGePaW4NHKcfY" +``` + +### Authentik Provider Configuration + +**Provider Details:** +- **Name:** Vaultwarden +- **Type:** OAuth2/OpenID Connect Provider +- **Client Type:** Confidential +- **Client ID:** `DDOQXdwFn6pi4FtSvo7PK5b63pRzyD552xapTZGr` +- **Application Slug:** `vaultwarden` +- **Redirect URI:** `https://vault.jnss.me/identity/connect/oidc-signin` + +**Scopes Configured:** +- ✅ `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'` + +**Token Settings:** +- Access token validity: > 5 minutes +- Refresh token enabled via `offline_access` scope + +**Authority URL:** `https://auth.jnss.me/application/o/vaultwarden/` + +### Deployed Environment (VPS) + +```bash +# Deployed environment file +Location: /opt/vaultwarden/.env + +# All SSO variables present and correct +SSO_ENABLED=true +SSO_AUTHORITY=https://auth.jnss.me/application/o/vaultwarden/ +SSO_SCOPES="openid email profile offline_access" +# ... etc +``` + +## How to Activate SSO (Future) + +When Vaultwarden SSO reaches stable release: + +### Automatic Activation (Recommended) + +1. **Monitor Vaultwarden releases** for SSO in stable: + - Watch: https://github.com/dani-garcia/vaultwarden/releases + - Look for: SSO feature in stable image changelog + +2. **Update container** (standard maintenance): + ```bash + ansible-playbook rick-infra.yml --tags vaultwarden --ask-vault-pass + ``` + +3. **Verify SSO is available**: + ```bash + ssh root@69.62.119.31 "curl -s http://127.0.0.1:8080/api/config | grep sso" + # Should return: "sso":"https://vault.jnss.me" or similar + ``` + +4. **Test SSO**: + - Navigate to: https://vault.jnss.me + - Log out if logged in + - Enter verified email address + - Click "Use single sign-on" button + - Should redirect to Authentik login + +**No configuration changes needed** - Everything is already set up correctly. + +### Manual Testing (Use Testing Image) + +If you want to test SSO before stable release: + +1. **Backup current deployment**: + ```bash + ansible-playbook playbooks/backup-vaultwarden.yml # Create if needed + ``` + +2. **Change to testing image** in `roles/vaultwarden/defaults/main.yml`: + ```yaml + vaultwarden_version: "testing" + ``` + +3. **Deploy**: + ```bash + ansible-playbook rick-infra.yml --tags vaultwarden --ask-vault-pass + ``` + +4. **Test SSO** (same as above) + +5. **Revert to stable** when testing complete: + ```yaml + vaultwarden_version: "latest" + ``` + +**Warning:** Testing images may contain bugs, data corruption risks, or breaking changes. Not recommended for production password manager. + +## Verification Commands + +### Check Current Image Version +```bash +ssh root@69.62.119.31 "podman inspect vaultwarden --format '{{.ImageName}}'" +# Expected: docker.io/vaultwarden/server:latest +``` + +### Check SSO API Status +```bash +ssh root@69.62.119.31 "curl -s http://127.0.0.1:8080/api/config | grep -o '\"sso\":\"[^\"]*\"'" +# Current: "sso":"" (empty = not available) +# Future: "sso":"https://vault.jnss.me" (URL = available) +``` + +### Check SSO Environment Variables +```bash +ssh root@69.62.119.31 "podman exec vaultwarden env | grep -i sso | sort" +# Should show all SSO_* variables configured correctly +``` + +### Check Vaultwarden Version +```bash +ssh root@69.62.119.31 "podman exec vaultwarden /vaultwarden --version" +# Current: Vaultwarden 1.34.3 +``` + +## Documentation Updates + +The following files have been updated to document this finding: + +1. **`roles/vaultwarden/README.md`** + - Added warning banner in SSO configuration section + - Updated troubleshooting section with SSO status checks + - Documented stable vs testing image behavior + +2. **`roles/vaultwarden/VAULT_VARIABLES.md`** + - Added SSO feature status warning + - Documented that credentials are ready but inactive + +3. **`roles/vaultwarden/defaults/main.yml`** + - Added comments explaining SSO availability + +4. **`docs/vaultwarden-sso-status.md`** (this document) + - Complete investigation findings + - Configuration reference + - Activation procedures + +## Timeline + +- **2025-07-30:** Vaultwarden v1.34.3 released (current stable) +- **2025-12-21:** Vaultwarden deployed with SSO pre-configured +- **2025-12-21:** Investigation completed, SSO status documented +- **TBD:** SSO feature reaches stable release (no ETA) +- **Future:** Automatic SSO activation on next deployment + +## Related Documentation + +- [Vaultwarden Official Wiki](https://github.com/dani-garcia/vaultwarden/wiki) +- [SSO Documentation](https://github.com/dani-garcia/vaultwarden/wiki/Enabling-SSO-support-using-OpenId-Connect) +- [Authentik Integration Guide](https://integrations.goauthentik.io/security/vaultwarden/) +- [Vaultwarden Testing Features](https://github.com/dani-garcia/vaultwarden/wiki#testing-features) + +## Contact + +For questions about this deployment: +- Infrastructure repo: `/home/fitz/rick-infra` +- Role location: `roles/vaultwarden/` +- Service: `vault.jnss.me` +- Host: `arch-vps` (69.62.119.31) + +--- + +**Status:** SSO configured and ready, waiting for upstream stable release. No action required. diff --git a/rick-infra.yml b/rick-infra.yml index afdb2d0..acca03a 100644 --- a/rick-infra.yml +++ b/rick-infra.yml @@ -9,6 +9,7 @@ # - Nextcloud cloud storage # - Authentik SSO/authentication # - Gitea git hosting +# - Vaultwarden password manager # # Usage: # ansible-playbook playbooks/homelab.yml @@ -30,8 +31,13 @@ # name: gitea # tags: ['gitea', 'git', 'development'] - - name: Deploy Nextcloud + # - name: Deploy Nextcloud + # include_role: + # name: nextcloud + # tags: ['nextcloud', 'cloud', 'storage'] + + - name: Deploy Vaultwarden include_role: - name: nextcloud - tags: ['nextcloud', 'cloud', 'storage'] + name: vaultwarden + tags: ['vaultwarden', 'vault', 'password-manager', 'security'] diff --git a/roles/vaultwarden/README.md b/roles/vaultwarden/README.md new file mode 100644 index 0000000..8401ede --- /dev/null +++ b/roles/vaultwarden/README.md @@ -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: "" + vault_vaultwarden_sso_client_secret: "" + ``` + +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//` + - 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 diff --git a/roles/vaultwarden/VAULT_VARIABLES.md b/roles/vaultwarden/VAULT_VARIABLES.md new file mode 100644 index 0000000..d8c350b --- /dev/null +++ b/roles/vaultwarden/VAULT_VARIABLES.md @@ -0,0 +1,171 @@ +# Vaultwarden Role - Required Vault Variables + +This document lists all vault-encrypted variables required by the Vaultwarden role. + +## Required Variables + +These variables **must** be defined in your vault file (e.g., `group_vars/homelab/vault.yml`): + +### Database Credentials + +```yaml +# PostgreSQL database password for vaultwarden user +vault_vaultwarden_db_password: "your-secure-database-password-here" +``` + +**Generation**: +```bash +openssl rand -base64 32 +``` + +### Admin Panel Access + +```yaml +# Plain text admin token (will be hashed during deployment) +vault_vaultwarden_admin_token: "your-secret-admin-token" +``` + +**Generation**: +```bash +# Generate a secure random token +openssl rand -base64 32 +``` + +**Important**: +- Store as **plain text** in vault (the role will hash it automatically) +- Use the same token to access `/admin` panel +- The token is automatically hashed on the **control node** using argon2id +- Hashing uses OWASP recommended settings (m=19456, t=2, p=1) +- Hashing is **idempotent**: same token always produces same hash +- The `argon2` package is automatically installed if not present on control node +- Never commit the vault file unencrypted to git + +## Optional Variables + +These variables are only needed if you enable specific features: + +### SMTP Configuration + +Required if `vaultwarden_smtp_enabled: true`: + +```yaml +# SMTP password for sending emails +vault_vaultwarden_smtp_password: "smtp-password-here" +``` + +### SSO Integration (Authentik) + +> ⚠️ **SSO Feature Status (December 2025)** +> +> SSO is only available in `vaultwarden/server:testing` images (not in stable yet). +> This role is configured with SSO ready for when it reaches stable release. +> +> Current deployment uses `vaultwarden_version: "latest"` (stable) - SSO credentials +> below are configured but SSO will not appear until feature reaches stable. + +Required if `vaultwarden_sso_enabled: true`: + +```yaml +# OAuth2 Client ID from Authentik +vault_vaultwarden_sso_client_id: "your-client-id-here" + +# OAuth2 Client Secret from Authentik +vault_vaultwarden_sso_client_secret: "your-client-secret-here" +``` + +**Setup** (following [Authentik integration guide](https://integrations.goauthentik.io/security/vaultwarden/)): +1. Create OAuth2/OpenID Provider in Authentik: + - Redirect URI: `https://vault.jnss.me/identity/connect/oidc-signin` (exact match) + - Add scope mappings: `openid`, `email`, `profile`, `offline_access` (required) + - Access token validity: > 5 minutes + - Note the **application slug** from the provider URL +2. Copy Client ID and Secret from Authentik +3. Add credentials to vault file +4. Set the SSO authority URL in role configuration: + ```yaml + vaultwarden_sso_enabled: true + vaultwarden_sso_authority: "https://auth.jnss.me/application/o//" + ``` +5. Deploy the role +6. **Wait for SSO to reach stable**, or use `vaultwarden_version: "testing"` to test now + +**Important**: +- The SSO authority must include the full path with application slug +- The `offline_access` scope mapping is **required** for Vaultwarden SSO +- Access token must be valid for more than 5 minutes +- SSO is configured and ready but will activate when stable release includes it + +## Example Vault File + +```yaml +--- +# group_vars/homelab/vault.yml (encrypted with ansible-vault) + +# Vaultwarden - Database +vault_vaultwarden_db_password: "xK9mP2nR5tY8wQ3vZ7cB6sA4dF1gH0jL" + +# Vaultwarden - Admin Panel (plain text, will be hashed automatically) +vault_vaultwarden_admin_token: "MySecureAdminToken123!" + +# Vaultwarden - SMTP (optional) +vault_vaultwarden_smtp_password: "smtp-app-password-here" + +# Vaultwarden - SSO (optional) +vault_vaultwarden_sso_client_id: "vaultwarden" +vault_vaultwarden_sso_client_secret: "sso-secret-from-authentik" +``` + +## Vault File Management + +### Encrypt Vault File + +```bash +ansible-vault encrypt group_vars/homelab/vault.yml +``` + +### Edit Vault File + +```bash +ansible-vault edit group_vars/homelab/vault.yml +``` + +### Decrypt Vault File (temporary) + +```bash +ansible-vault decrypt group_vars/homelab/vault.yml +# Make changes +ansible-vault encrypt group_vars/homelab/vault.yml +``` + +## Security Best Practices + +1. **Never commit unencrypted vault files** +2. **Use strong passwords** (32+ characters for database, admin token) +3. **Rotate credentials periodically** (especially admin token) +4. **Limit vault password access** (use password manager) +5. **Use separate passwords** for different services +6. **Back up vault password** (secure location, not in git) + +## Verifying Variables + +Test if variables are properly loaded: + +```bash +ansible -m debug -a "var=vault_vaultwarden_db_password" homelab --ask-vault-pass +``` + +## Troubleshooting + +### Variable not found error + +- Ensure vault file is in correct location: `group_vars/homelab/vault.yml` +- Verify file is encrypted: `file group_vars/homelab/vault.yml` +- Check variable name matches exactly (case-sensitive) +- Provide vault password with `--ask-vault-pass` + +### Admin token not working + +- Verify the plain text token in vault matches what you're entering +- Check for extra whitespace in vault file +- Ensure the token was hashed successfully during deployment (check ansible output) +- Try redeploying the role to regenerate the hash diff --git a/roles/vaultwarden/defaults/main.yml b/roles/vaultwarden/defaults/main.yml new file mode 100644 index 0000000..3c76e53 --- /dev/null +++ b/roles/vaultwarden/defaults/main.yml @@ -0,0 +1,109 @@ +--- +# ================================================================= +# Vaultwarden Password Manager Role - Default Variables +# ================================================================= +# Self-contained Vaultwarden deployment with Podman and PostgreSQL + +# ================================================================= +# Service Configuration +# ================================================================= + +# Service user and directories +vaultwarden_user: vaultwarden +vaultwarden_group: vaultwarden +vaultwarden_home: /opt/vaultwarden +vaultwarden_data_dir: "{{ vaultwarden_home }}/data" + +# Container configuration +# NOTE: SSO feature is only available in "testing" tag (as of Dec 2025) +# Using "latest" (stable) means SSO will not appear even if configured +# SSO settings below are configured and ready for when feature reaches stable +vaultwarden_version: "latest" +vaultwarden_image: "vaultwarden/server" + +# Service management +vaultwarden_service_enabled: true +vaultwarden_service_state: "started" + +# ================================================================= +# Database Configuration (Self-managed) +# ================================================================= + +vaultwarden_db_name: "vaultwarden" +vaultwarden_db_user: "vaultwarden" +vaultwarden_db_password: "{{ vault_vaultwarden_db_password }}" + +# ================================================================= +# Network Configuration +# ================================================================= + +vaultwarden_domain: "vault.jnss.me" +vaultwarden_http_port: 8080 + +# ================================================================= +# Vaultwarden Core Configuration +# ================================================================= + +# Admin panel access token (plain text, will be hashed during deployment) +vaultwarden_admin_token_plain: "{{ vault_vaultwarden_admin_token }}" + +# Registration and invitation controls +vaultwarden_signups_allowed: false # Disable open registration +vaultwarden_invitations_allowed: true # Allow existing users to invite +vaultwarden_show_password_hint: false # Don't show password hints + +# WebSocket support for live sync +vaultwarden_websocket_enabled: true + +# ================================================================= +# Email Configuration (Optional) +# ================================================================= + +vaultwarden_smtp_enabled: true +vaultwarden_smtp_host: "smtp.titan.email" +vaultwarden_smtp_port: 587 +vaultwarden_smtp_from: "hello@jnss.me" +vaultwarden_smtp_username: "hello@jnss.me" +vaultwarden_smtp_password: "{{ vault_vaultwarden_smtp_password | default('') }}" +vaultwarden_smtp_security: "starttls" # Options: starttls, force_tls, off + +# ================================================================= +# SSO Configuration (Optional - Authentik Integration) +# ================================================================= + +vaultwarden_sso_enabled: false + +# SSO Provider Configuration (Authentik) +vaultwarden_sso_client_id: "{{ vault_vaultwarden_sso_client_id | default('') }}" +vaultwarden_sso_client_secret: "{{ vault_vaultwarden_sso_client_secret | default('') }}" +# Authority must include full path with application slug +vaultwarden_sso_authority: "https://{{ authentik_domain }}/application/o/vaultwarden/" +vaultwarden_sso_scopes: "openid email profile offline_access" + +# Additional SSO settings (per Authentik integration guide) +vaultwarden_sso_only: false # Set to true to disable email+password login and require SSO +vaultwarden_sso_signups_match_email: true # Match first SSO login to existing account by email +vaultwarden_sso_allow_unknown_email_verification: false +vaultwarden_sso_client_cache_expiration: 0 + +# Domain whitelist for SSO signups (comma-separated domains, empty = all) +vaultwarden_sso_signups_domains_whitelist: "" + +# ================================================================= +# Caddy Integration +# ================================================================= + +# Caddy configuration (assumes caddy role provides these variables) +caddy_sites_enabled_dir: "/etc/caddy/sites-enabled" +caddy_log_dir: "/var/log/caddy" +caddy_user: "caddy" + +# ================================================================= +# Infrastructure Dependencies (Read-only) +# ================================================================= + +# PostgreSQL socket configuration (managed by postgresql role) +postgresql_unix_socket_directories: "/var/run/postgresql" +postgresql_client_group: "postgres-clients" +postgresql_port: 5432 +postgresql_unix_socket_enabled: true diff --git a/roles/vaultwarden/handlers/main.yml b/roles/vaultwarden/handlers/main.yml new file mode 100644 index 0000000..7052d1a --- /dev/null +++ b/roles/vaultwarden/handlers/main.yml @@ -0,0 +1,16 @@ +--- +# Vaultwarden Password Manager - Service Handlers + +- name: reload systemd + systemd: + daemon_reload: true + +- name: restart vaultwarden + systemd: + name: vaultwarden + state: restarted + +- name: reload caddy + systemd: + name: caddy + state: reloaded diff --git a/roles/vaultwarden/meta/main.yml b/roles/vaultwarden/meta/main.yml new file mode 100644 index 0000000..9485c72 --- /dev/null +++ b/roles/vaultwarden/meta/main.yml @@ -0,0 +1,25 @@ +--- +# Vaultwarden Password Manager - Role Metadata + +dependencies: + - role: postgresql + - role: caddy + +galaxy_info: + author: Rick Infrastructure Team + description: Vaultwarden password manager deployment with PostgreSQL and Caddy + license: MIT + min_ansible_version: "2.14" + + platforms: + - name: ArchLinux + versions: + - all + + galaxy_tags: + - vaultwarden + - bitwarden + - password-manager + - security + - postgresql + - podman diff --git a/roles/vaultwarden/tasks/database.yml b/roles/vaultwarden/tasks/database.yml new file mode 100644 index 0000000..3d339b1 --- /dev/null +++ b/roles/vaultwarden/tasks/database.yml @@ -0,0 +1,51 @@ +--- +# Database setup for Vaultwarden - PostgreSQL via Unix Socket + +- name: Test PostgreSQL socket connectivity + postgresql_ping: + login_unix_socket: "{{ postgresql_unix_socket_directories }}" + login_user: "{{ vaultwarden_user }}" + become: true + become_user: "{{ vaultwarden_user }}" + +- name: Create Vaultwarden database user via socket + postgresql_user: + name: "{{ vaultwarden_db_user }}" + password: "{{ vaultwarden_db_password }}" + login_unix_socket: "{{ postgresql_unix_socket_directories }}" + login_user: postgres + become: true + become_user: postgres + +- name: Create Vaultwarden database via socket + postgresql_db: + name: "{{ vaultwarden_db_name }}" + owner: "{{ vaultwarden_db_user }}" + encoding: UTF8 + template: template0 + login_unix_socket: "{{ postgresql_unix_socket_directories }}" + login_user: postgres + become: true + become_user: postgres + +- name: Grant Vaultwarden database privileges + postgresql_privs: + db: "{{ vaultwarden_db_name }}" + privs: ALL + type: database + role: "{{ vaultwarden_db_user }}" + login_unix_socket: "{{ postgresql_unix_socket_directories }}" + login_user: postgres + become: true + become_user: postgres + +- name: Display database setup status + debug: + msg: | + Vaultwarden database setup complete! + + Database: {{ vaultwarden_db_name }} + User: {{ vaultwarden_db_user }} + Connection: Unix socket ({{ postgresql_unix_socket_directories }}) + + Ready for Vaultwarden container deployment diff --git a/roles/vaultwarden/tasks/hash_admin_token.yml b/roles/vaultwarden/tasks/hash_admin_token.yml new file mode 100644 index 0000000..431ce53 --- /dev/null +++ b/roles/vaultwarden/tasks/hash_admin_token.yml @@ -0,0 +1,57 @@ +--- +# Hash admin token on Ansible control node using argon2 + +- name: Check if argon2 is available on control node + command: which argon2 + register: argon2_check + delegate_to: localhost + become: false + changed_when: false + failed_when: false + +- name: Install argon2 on control node if not present + package: + name: argon2 + state: present + delegate_to: localhost + become: false + when: argon2_check.rc != 0 + run_once: true + +- name: Generate deterministic salt from domain + set_fact: + vaultwarden_salt_source: "{{ vaultwarden_domain }}-{{ vaultwarden_sso_authority }}" + no_log: true + +- name: Create base64-encoded salt for argon2 + shell: echo -n "{{ vaultwarden_salt_source }}" | sha256sum | cut -d' ' -f1 | head -c 22 + register: admin_token_salt + delegate_to: localhost + become: false + changed_when: false + no_log: true + +- name: Hash admin token using argon2 (OWASP preset) + shell: echo -n "{{ vaultwarden_admin_token_plain }}" | argon2 "{{ admin_token_salt.stdout }}" -id -t 2 -k 19456 -p 1 -e + register: admin_token_hash_result + delegate_to: localhost + become: false + changed_when: false + no_log: true + +- name: Extract hashed admin token + set_fact: + vaultwarden_admin_token_hashed: "{{ admin_token_hash_result.stdout | trim }}" + no_log: true + +- name: Display token hash status + debug: + msg: | + Admin token hashed successfully on control node + + Hash algorithm: argon2id + Preset: OWASP (m=19456, t=2, p=1) + Format: PHC string (Vaultwarden compatible) + Idempotent: Same token always produces same hash + + The hashed token will be used in the environment configuration diff --git a/roles/vaultwarden/tasks/main.yml b/roles/vaultwarden/tasks/main.yml new file mode 100644 index 0000000..5eb3a7a --- /dev/null +++ b/roles/vaultwarden/tasks/main.yml @@ -0,0 +1,108 @@ +--- +# Vaultwarden Password Manager Role - Main Tasks +# Self-contained deployment with Podman and Unix sockets + +- name: Setup vaultwarden user and directories + include_tasks: user.yml + tags: [user, setup] + +- name: Setup database access and permissions + include_tasks: database.yml + tags: [database, setup] + +- name: Pull vaultwarden container image + containers.podman.podman_image: + name: "{{ vaultwarden_image }}:{{ vaultwarden_version }}" + state: present + tags: [containers, image-pull] + +- name: Hash admin token on host + include_tasks: hash_admin_token.yml + tags: [config, admin-token] + +- name: Deploy environment configuration + template: + src: vaultwarden.env.j2 + dest: "{{ vaultwarden_home }}/.env" + owner: "{{ vaultwarden_user }}" + group: "{{ vaultwarden_group }}" + mode: '0600' + backup: true + notify: + - restart vaultwarden + tags: [config] + +- name: Create Quadlet systemd directory + file: + path: /etc/containers/systemd + state: directory + mode: '0755' + +- name: Deploy Quadlet container file + template: + src: vaultwarden.container + dest: /etc/containers/systemd/vaultwarden.container + mode: '0644' + notify: + - reload systemd + - restart vaultwarden + tags: [containers, deployment] + +- name: Deploy Caddy configuration + template: + src: vaultwarden.caddy.j2 + dest: "{{ caddy_sites_enabled_dir }}/vaultwarden.caddy" + owner: root + group: "{{ caddy_user }}" + mode: '0644' + backup: true + notify: reload caddy + tags: [caddy, reverse-proxy] + +- name: Ensure PostgreSQL is running + systemd: + name: postgresql + state: started + +- name: Wait for PostgreSQL socket to be ready + wait_for: + path: "{{ postgresql_unix_socket_directories }}/.s.PGSQL.{{ postgresql_port }}" + timeout: 30 + when: postgresql_unix_socket_enabled + +- name: Enable and start Vaultwarden service (system scope) + systemd: + name: vaultwarden + enabled: "{{ vaultwarden_service_enabled }}" + state: "{{ vaultwarden_service_state }}" + daemon_reload: true + tags: [containers, service] + +- name: Wait for Vaultwarden to be ready + uri: + url: "http://127.0.0.1:{{ vaultwarden_http_port }}/" + method: GET + status_code: [200, 302] + timeout: 30 + retries: 10 + delay: 15 + register: vaultwarden_health_check + tags: [verification, health-check] + +- name: Display Vaultwarden deployment status + debug: + msg: | + Vaultwarden Password Manager deployed successfully! + + Domain: {{ vaultwarden_domain }} + Database: {{ vaultwarden_db_name }} (Unix socket) + Container: {{ vaultwarden_image }}:{{ vaultwarden_version }} + Admin Panel: https://{{ vaultwarden_domain }}/admin + + Ready for user registration and password management! + + Next Steps: + - Access https://{{ vaultwarden_domain }}/admin with your admin token + - Configure additional settings (SMTP, SSO, etc.) + - Invite users or create accounts + tags: [verification] diff --git a/roles/vaultwarden/tasks/user.yml b/roles/vaultwarden/tasks/user.yml new file mode 100644 index 0000000..ffdc976 --- /dev/null +++ b/roles/vaultwarden/tasks/user.yml @@ -0,0 +1,28 @@ +--- +# Vaultwarden User Management - Service-Specific User Setup + +- name: Create vaultwarden group + group: + name: "{{ vaultwarden_group }}" + system: true + +- name: Create vaultwarden user + user: + name: "{{ vaultwarden_user }}" + group: "{{ vaultwarden_group }}" + system: true + shell: /bin/bash + home: "{{ vaultwarden_home }}" + create_home: true + comment: "Vaultwarden password manager service" + +- name: Create vaultwarden directories + file: + path: "{{ item }}" + state: directory + owner: "{{ vaultwarden_user }}" + group: "{{ vaultwarden_group }}" + mode: '0755' + loop: + - "{{ vaultwarden_home }}" + - "{{ vaultwarden_data_dir }}" diff --git a/roles/vaultwarden/templates/vaultwarden.caddy.j2 b/roles/vaultwarden/templates/vaultwarden.caddy.j2 new file mode 100644 index 0000000..2abc012 --- /dev/null +++ b/roles/vaultwarden/templates/vaultwarden.caddy.j2 @@ -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 + } +} diff --git a/roles/vaultwarden/templates/vaultwarden.container b/roles/vaultwarden/templates/vaultwarden.container new file mode 100644 index 0000000..9eeeacd --- /dev/null +++ b/roles/vaultwarden/templates/vaultwarden.container @@ -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 diff --git a/roles/vaultwarden/templates/vaultwarden.env.j2 b/roles/vaultwarden/templates/vaultwarden.env.j2 new file mode 100644 index 0000000..88e4cd4 --- /dev/null +++ b/roles/vaultwarden/templates/vaultwarden.env.j2 @@ -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