A virtual CTAP2 authenticator for Linux with TPM 2.0-bound keys, biometric user verification, and enterprise attestation.
vauth creates a virtual FIDO2 security key via Linux uhid. Browsers see it as a hardware authenticator — register and sign in with passkeys using your face or a password, backed by keys that never leave your TPM.
- TPM 2.0-bound keys — private keys generated inside and never exported from the TPM
- Face recognition — howdy-based face auth via PAM, with password fallback (zenity dialog)
- Packed attestation — self-signed CA with x5c certificate chain for enterprise enforcement
- Privilege separation — drops from root to real user after init, retains only
CAP_DAC_READ_SEARCH - Audit logging — single JSONL file, every operation logged with RP, user, result, counter
- UV caching — (CID, RP ID)-bound, use-once, 10s TTL — no double-prompts, no attack window
- Lockout — configurable failure threshold and cooldown
- Credential management —
list,info,revoke,wipesubcommands - Monotonic counter — TPM NV counter for clone detection
- Linux with kernel uhid support
- TPM 2.0 (
/dev/tpmrm0) - Rust 1.91+
libpam(PAM development headers)tpm2-tss(TPM2 Software Stack)
- howdy — face recognition via PAM
zenity— GUI password dialog fallback
cargo build --releaseThe binary is at target/release/vauth.
sudo cp dist/udev/99-vauth.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
sudo udevadm trigger /dev/uhidEnsure your user is in the input group:
sudo usermod -aG input $USERsudo cp dist/pam.d/vauth /etc/pam.d/Edit /etc/pam.d/vauth to match your system. The default config tries howdy (face), then falls back to password:
auth sufficient pam_python.so /lib/security/howdy/pam.py
auth required pam_unix.so nullok
Generate a self-signed attestation CA and device certificate:
sudo vauth setup-attestationThe CA cert can be imported into your identity provider (e.g., Authentik) to enforce "only vauth" credentials. The cert is at:
~/.local/share/fidorium/attestation_ca.pem
sudo cp dist/systemd/vauth.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now vauthsudo vauth run -vv --audit-log /var/log/vauth/audit.jsonlThe daemon starts as root (for TPM + uhid), then drops to your user. Open a browser, navigate to a WebAuthn-enabled site, and register a passkey.
sudo vauth list # List all stored credentials
sudo vauth info <id-prefix> # Show credential details
sudo vauth revoke <id-prefix> # Delete a credential
sudo vauth wipe # Delete everything + reset TPM counterCredential IDs support prefix matching — vauth info 8d94 matches 8d945861f3a4....
vauth [OPTIONS] [COMMAND]
Commands:
run Start the authenticator daemon (default)
list List all stored credentials
info <ID> Show details of a specific credential
revoke <ID> Revoke (delete) a credential
wipe Delete all credentials and reset TPM NV counter
setup-attestation Generate attestation CA and device certificate
Options:
-v, --verbose Increase log verbosity (use -vv for debug)
--tpm-device <PATH> TPM device [default: /dev/tpmrm0]
--nv-index <HEX> TPM NV counter index [default: 0x01800100]
vauth run [OPTIONS]
Options:
--pam-service <NAME> PAM service name [default: vauth]
--audit-log <PATH> Audit log path [default: /var/log/vauth/audit.jsonl]
--max-uv-failures <N> Failures before lockout [default: 5]
--lockout-secs <N> Lockout duration [default: 300]
See THREAT_MODEL.md for a detailed analysis of what vauth does and does not defend against.
Key points:
- Private keys never leave the TPM
- Every signing operation requires fresh user verification
- The daemon runs as an unprivileged user after initialization
- A compromised local OS can bypass all protections — no software authenticator can prevent this
Browser (WebAuthn JS API)
│ HID reports via /dev/uhid
▼
vauth daemon (unprivileged after init)
├── CTAPHID framing + dispatch
├── CTAP2 protocol (makeCredential, getAssertion, getInfo)
├── PAM user verification (howdy face → password fallback)
├── UV cache (CID+RP bound, use-once, TTL)
├── Attestation signing (device cert + CA chain)
├── Audit logger (JSONL)
└── TPM 2.0 (key generation, signing, NV counter, sealing)
vauth is a fork of fidorium by Edgar Luque, which provided the foundational CTAP2/CTAPHID/TPM implementation. Licensed under MIT/Apache-2.0.
MIT OR Apache-2.0
- AUR PKGBUILD
- Install script
- Cross-browser testing (Chromium)
- FIDO Alliance conformance test vectors
- Hybrid transport / caBLE (QR code auth from other devices)
- Encrypted credential sync (portable passkey support)
- Platform authenticator integration (emerging Linux credential-provider APIs)
- seccomp filter (restrict syscalls post-init)
- TPM policy sessions (bind UV cryptographically to signing, not just type-level gate)