Using the Built-in Fingerprint Reader as a FIDO2 Security Key in Linux Firefox
Introduction
Starting this academic year, my university (Chiba Institute of Technology) introduced two-factor authentication on its portal site. Currently, I have to open an authenticator app on my phone to get a one-time password and manually type it into my PC. On my phone, a single fingerprint touch is enough to log in — but on the PC I have to open the app and enter the code every single time, which is honestly a pain.
The university’s guide PDF recommends a Chrome extension, but my environment is Linux + Firefox. I wanted to do the same thing in Firefox on Linux, so I started looking into it.
Why the Fingerprint Reader Doesn’t Respond
When I navigate to the two-factor authentication enrollment page in Firefox, it shows “touch your security key,” but the PC’s built-in fingerprint reader does absolutely nothing.
This is because the PC’s fingerprint reader (fprintd) and the browser’s WebAuthn/FIDO2 are completely separate systems.
| fprintd | WebAuthn/FIDO2 | |
|---|---|---|
| Purpose | OS login, sudo | Website two-factor authentication |
| Supported devices | PC built-in fingerprint reader | USB security keys like YubiKey |
| Protocol | PAM | FIDO2/CTAP2 |
Windows Hello and macOS Touch ID have OS-level bridges between these two systems, but Linux has no such mechanism. In other words, as far as the browser is concerned, there is no security key present.
Solution: tpm-fido2
After some research, I found a project called tpm-fido2-thinkpad-linux. It combines TPM 2.0 with fprintd to create a virtual FIDO2 security key, making it appear to the browser as if a physical YubiKey is connected.
Firefox (WebAuthn API)
↓
/dev/uhid (virtual HID device)
↓
tpm-fido2 daemon
├── TPM 2.0 (private key protection)
└── fprintd (fingerprint identity verification)
When an authentication request comes from the browser, a desktop notification prompts for a fingerprint, and touching the sensor completes the authentication.
Environment
| Item | Details |
|---|---|
| OS | Pop!_OS (COSMIC, Wayland) |
| Browser | Firefox |
| Fingerprint reader | Goodix MOC Fingerprint Sensor |
| TPM | TPM 2.0 |
Setup
Verifying Prerequisites
First, confirm that TPM 2.0 is available and that a fingerprint has already been enrolled.
# Check TPM version (OK if it shows 2)
cat /sys/class/tpm/tpm0/tpm_version_major
# Check fingerprint enrollment status
fprintd-list $(whoami)
Installation
sudo apt install golang libfido2-dev libtss2-dev fprintd
git clone https://github.com/mc256/tpm-fido2-thinkpad-linux.git
cd tpm-fido2-thinkpad-linux
go build -o tpm-fido2
sudo cp tpm-fido2 /usr/local/bin/
uhid Permission Setup
Permission to /dev/uhid is required to create the virtual HID device.
sudo chmod 666 /dev/uhid
Starting the Daemon
sudo tpm-fido2 --mode daemon
The --mode daemon flag is important. The default native mode uses Native Messaging for Chrome extensions and does not work with Firefox. The daemon mode creates a virtual HID device via /dev/uhid, so it works with both Firefox and Chrome.
Pitfall: Specifying the User for fprintd-verify
The daemon started successfully and the authentication prompt appeared in the browser, but the fingerprint reader never responded.
The cause was in the source code — line 103 of userpresence/userpresence.go:
// Default: call fprintd-verify without specifying a username
fprintCmd := exec.CommandContext(ctx, "fprintd-verify")
Because the daemon is run with sudo, fprintd-verify looks for the root user’s fingerprint. However, fingerprints are enrolled under the regular user account, so it never matches.
Fix
Add your username as an argument.
fprintCmd := exec.CommandContext(ctx, "fprintd-verify", "your-username")
Rebuild after making the fix.
go build -o tpm-fido2
sudo cp tpm-fido2 /usr/local/bin/
sudo tpm-fido2 --mode daemon
After this, the fingerprint reader responded correctly.
Verification
- Start
sudo tpm-fido2 --mode daemon - Navigate to the university portal’s two-factor authentication settings page in Firefox
- “touch your security key” is displayed
- A desktop notification “Touch fingerprint sensor to confirm” appears
- Touch the fingerprint reader → authentication succeeds
I no longer need to open the authenticator app on my phone; two-factor authentication now completes entirely from the PC.
Summary
Because Linux lacks an OS-level WebAuthn bridge like Windows Hello, the PC’s built-in fingerprint reader cannot be used directly for browser-based two-factor authentication. With tpm-fido2, you can create a virtual security key backed by TPM + fprintd, enabling fingerprint authentication even in Firefox.
Just be careful to specify the username for fprintd-verify when running under sudo.