- 0029: User registration workflow with approval and group-based access - 0030: MFA and Yubikey strategy for Authentik and Vaultwarden
13 KiB
MFA and Yubikey Strategy
- Status: proposed
- Date: 2026-02-04
- Deciders: Billy
- Technical Story: Enable hardware security key (Yubikey) authentication across homelab applications
Context and Problem Statement
Password-only authentication is vulnerable to phishing and credential theft. Hardware security keys (Yubikeys) provide phishing-resistant authentication through WebAuthn/FIDO2. The homelab uses multiple authentication points:
- Authentik - Central SSO for most applications
- Vaultwarden - Password manager (independent auth)
How do we enable Yubikey support across these authentication points while maintaining usability?
Decision Drivers
- Phishing-resistant authentication for sensitive applications
- Flexibility - support both hardware keys and TOTP
- User experience - single Yubikey works everywhere
- Fallback options - don't lock users out if key is lost
- Future-proof - support passkeys and newer standards
Considered Options
- WebAuthn/FIDO2 for both Authentik and Vaultwarden
- Yubikey OTP only
- TOTP only (no hardware key support)
Decision Outcome
Chosen option: Option 1 - WebAuthn/FIDO2 for both Authentik and Vaultwarden
WebAuthn provides the best security (phishing-resistant) and user experience (touch to authenticate). Both Authentik and Vaultwarden support WebAuthn natively.
Positive Consequences
- Phishing-resistant authentication
- Single Yubikey works for all applications
- No external dependencies (unlike Yubikey OTP)
- Supports passkeys for future passwordless auth
- Hardware-bound credentials can't be copied
Negative Consequences
- Requires modern browser with WebAuthn support
- Users must have physical access to key
- Key loss requires recovery process
Implementation Status
| Application | WebAuthn Support | Current Status | Action Required |
|---|---|---|---|
| Authentik | ✅ Native | ✅ Working | Configure enforcement policies |
| Vaultwarden | ✅ Native | ⚠️ Partial | Enable in admin settings |
Authentik Configuration
Current State
Authentik has WebAuthn support built-in. Users can already enroll devices via:
- Settings → MFA Devices → Enroll WebAuthn Device
Required Configuration
1. Create WebAuthn Authenticator Stage
In Admin → Flows & Stages → Stages:
Stage: authenticator-webauthn-setup
Type: Authenticator WebAuthn Setup Stage
Name: authenticator-webauthn-setup
User verification: preferred
Resident key requirement: preferred
Authenticator attachment: cross-platform
Stage: authenticator-webauthn-validation
Type: Authenticator Validation Stage
Name: authenticator-webauthn-validation
Device classes: WebAuthn, TOTP (allow both)
Not configured action: skip
2. Bind to Authentication Flow
Edit the default authentication flow to include MFA:
Flow: default-authentication-flow
Stages (in order):
1. identification (username/email)
2. password
3. authenticator-webauthn-validation ← Add this
4. user-login
3. Create MFA Enforcement Policies
Policy: enforce-mfa-admins
# Expression Policy
# Requires WebAuthn for admins
if ak_is_group_member(request.user, name="homelab-admins"):
from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
if not WebAuthnDevice.objects.filter(user=request.user).exists():
ak_message("Administrators must enroll a hardware security key (Yubikey)")
return False
return True
Policy: enforce-mfa-users
# Expression Policy
# Requires any MFA for users
if ak_is_group_member(request.user, name="homelab-users"):
from authentik.stages.authenticator_totp.models import TOTPDevice
from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
has_totp = TOTPDevice.objects.filter(user=request.user, confirmed=True).exists()
has_webauthn = WebAuthnDevice.objects.filter(user=request.user).exists()
if not (has_totp or has_webauthn):
ak_message("Please enroll an MFA device (authenticator app or security key)")
return False
return True
4. User Enrollment Flow
- User logs into Authentik
- Navigates to Settings → MFA Devices
- Clicks "Enroll WebAuthn Device"
- Inserts Yubikey and touches when prompted
- Names the device (e.g., "Yubikey 5 NFC - Primary")
- Optionally enrolls backup device or TOTP
Vaultwarden Configuration
Current State
Vaultwarden deployment has WebAuthn enabled by default, but admin panel configuration may be needed.
Required Configuration
1. Enable WebAuthn in Admin Panel
Access admin panel at https://vaultwarden.daviestechlabs.io/admin:
Settings → Advanced:
Enable Web Vault: true (already set)
Two-Factor Authentication:
Enable WebAuthn: true (verify this is set)
2. Optional: Enable Yubikey OTP
If users want Yubikey OTP as an additional option (the 44-character string feature):
Step 1: Get Yubico API Credentials
Visit: https://upgrade.yubico.com/getapikey/
Step 2: Store credentials in Vault
vault kv put kv/vaultwarden-yubico \
client_id="YOUR_CLIENT_ID" \
secret_key="YOUR_SECRET_KEY"
Step 3: Create ExternalSecret
Add to /home/billy/homelab-k8s2/kubernetes/apps/security/vaultwarden/app/externalsecret.yaml:
---
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: vaultwarden-yubico
spec:
refreshInterval: 1h
secretStoreRef:
kind: ClusterSecretStore
name: vault
target:
name: vaultwarden-yubico
creationPolicy: Owner
data:
- secretKey: YUBICO_CLIENT_ID
remoteRef:
key: kv/data/vaultwarden-yubico
property: client_id
- secretKey: YUBICO_SECRET_KEY
remoteRef:
key: kv/data/vaultwarden-yubico
property: secret_key
Step 4: Update Deployment
Add to /home/billy/homelab-k8s2/kubernetes/apps/security/vaultwarden/app/deployment.yaml:
envFrom:
- secretRef:
name: vaultwarden-db-credentials
- secretRef:
name: vaultwarden-yubico # Add this
Status: ⏳ NOT IMPLEMENTED - Requires Yubico API credentials
3. User Setup (WebAuthn - Already Available)
- Log into Vaultwarden web vault
- Go to Settings → Security → Two-step Login
- Click Manage next to "FIDO2 WebAuthn"
- Click "Register new key"
- Insert Yubikey and touch when prompted
- Name the key (e.g., "Yubikey 5 NFC")
MFA Requirements by User Group
| Group | MFA Requirement | Allowed Methods |
|---|---|---|
| homelab-admins | Required | WebAuthn only |
| homelab-users | Required | WebAuthn or TOTP |
| homelab-guests | Optional | WebAuthn or TOTP |
| pending-approval | Not required | N/A |
Recovery Procedures
Lost Yubikey - Authentik
- Admin accesses Authentik Admin → Directory → Users
- Find affected user
- Go to user's MFA Devices tab
- Delete lost device
- User can enroll new device on next login
Lost Yubikey - Vaultwarden
- User uses backup recovery code (generated at 2FA setup)
- Or admin accesses Vaultwarden admin panel
- Users → Find user → Disable 2FA
- User can re-enable with new device
Best Practice: Backup Keys
Recommend users enroll:
- Primary Yubikey (carried daily)
- Backup Yubikey (stored securely at home)
- TOTP as fallback (if allowed by policy)
Supported Yubikey Models
| Model | WebAuthn | NFC | USB-C | Recommended For |
|---|---|---|---|---|
| Yubikey 5 NFC | ✅ | ✅ | ❌ | Mobile + Desktop (USB-A) |
| Yubikey 5C NFC | ✅ | ✅ | ✅ | Modern laptops |
| Yubikey 5 Nano | ✅ | ❌ | ❌ | Always-in desktop |
| Security Key NFC | ✅ | ✅ | ❌ | Budget option |
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ User Login │
└──────────────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Authentik SSO │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Password │───▶│ WebAuthn │───▶│ Session │ │
│ │ Stage │ │ Validation │ │ Created │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ Yubikey │ │
│ │ Touch │ │
│ └─────────────┘ │
└──────────────────────────────┬──────────────────────────────────┘
│ SSO (no MFA needed again)
┌────────────────────┼────────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Affine │ │ Nextcloud│ │ Immich │
└──────────┘ └──────────┘ └──────────┘
┌─────────────────────────────────────────────────────────────────┐
│ Vaultwarden (Separate) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Master │───▶│ WebAuthn │───▶│ Vault │ │
│ │ Password │ │ (2FA) │ │ Unlocked │ │
│ └─────────────┘ └──────┬──────┘ └─────────────┘ │
│ │ │
│ ┌──────┴──────┐ │
│ │ Yubikey │ │
│ │ Touch │ │
│ └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
Testing Checklist
Authentik WebAuthn
- Enroll Yubikey as admin user
- Verify login requires Yubikey touch
- Test SSO to Affine with Yubikey
- Test recovery with backup device
- Verify non-admin can use TOTP instead
Vaultwarden WebAuthn
- Enable WebAuthn in admin panel
- Enroll Yubikey for test user
- Verify vault unlock requires Yubikey
- Test with browser extension
- Test recovery code flow
Future Enhancements
- Passkeys - Enable passwordless login with resident keys
- Conditional access - Require hardware key for sensitive operations only
- Device attestation - Verify Yubikey authenticity
- Session binding - Bind sessions to hardware key