(this was build with the assistance of google gemini but it is the steps i followed to get everything working)
This guide addresses TPM device access, container dependencies, pinentry conflicts, and systemd service environment issues for persistent, hardware-backed passkeys on Bazzite (or any Fedora OSTree/immutable system).
The Bazzite host must grant your user permanent access to the TPM device (/dev/tpmrm0).
-
Persist
tssGroup Definition: Copy the canonicaltssgroup entry to the/etc/groupoverlay, ensuring the change survives reboots.# Copy the group definition to the /etc overlay grep -E '^tss:' /usr/lib/group | sudo tee -a /etc/group
-
Add User and Finalize: Add your user (
$USER) to thetssgroup.# Add your current user to the tss group sudo usermod -aG tss $USER
-
Reboot: Reboot your system to finalize the persistent group membership change.
We use an Arch Linux Distrobox to provide the required tpm-fido package and its Qt dependencies.
-
Create/Enter the Box:
distrobox enter arch
-
Install Required Packages: Install the FIDO service, KDE/Qt dependencies, and the PIN entry program.
sudo pacman -S tpm-fido-git pinentry-qt kwindowingsystem kguiaddons
-
Clean Up Pinentry Conflicts (CRITICAL FIX): The
tpm-fidosource checks for pinentry binaries in a specific order (e.g.,gnome3beforeqt). Conflicting binaries must be removed to force selection of your workingpinentry-qt.# Remove conflicting packages (e.g., GNOME or Qt5 versions) sudo pacman -R pinentry-gnome3 pinentry-qt5 # Use -R to remove
-
Configure GnuPG Agent: Tell the GnuPG environment inside the container to prioritize your working Qt binary.
mkdir -p ~/.gnupg echo "pinentry-program /usr/bin/pinentry-qt" > ~/.gnupg/gpg-agent.conf
-
Export the Binary: This creates the host-side wrapper (
~/.local/bin/tpm-fido).distrobox-export --bin /usr/bin/tpm-fido
-
Exit the Box:
exit
This service unit must run after your KDE session starts and inherit the correct environment variables for graphical and GPG communication.
-
Create the Service File:
mkdir -p ~/.config/systemd/user/ nano ~/.config/systemd/user/tpm-fido.service
-
Paste the Final Configuration:
[Unit] Description=TPM FIDO implementation (via Distrobox) Wants=plasma-workspace.target After=plasma-workspace.target [Service] # CRITICAL: Pulls ALL dynamic variables (DISPLAY, GPG_AGENT_INFO, etc.) from the active session. ExecStartPre=/usr/bin/dbus-update-activation-environment --systemd DISPLAY XDG_RUNTIME_DIR GPG_AGENT_INFO # Executes a shell that explicitly sets the PINENTRY_PROGRAM path for the container # and runs the exported binary. ExecStart=/usr/bin/sh -c "export PINENTRY_PROGRAM=/usr/bin/pinentry-qt; exec %h/.local/bin/tpm-fido" Type=simple Restart=on-failure RestartSec=5s [Install] WantedBy=plasma-workspace.target
-
Enable and Start the Service:
systemctl --user daemon-reload systemctl --user enable --now tpm-fido
-
Check Service Status:
systemctl --user status tpm-fido
(Status should be
active (running)). -
Test Passkey Registration:
- Open your web browser on the host.
- Navigate to https://webauthn.io/
- Click Register.
- A native KDE/Qt PIN entry dialog should appear on your desktop.