# Framework 13 Fingerprint Reader Design **Date:** 2026-05-25 **Status:** Approved ## Summary Enable the Framework 13 (AMD 7040) Goodix fingerprint reader for `sudo` and `gtklock` (lockscreen). Three-phase setup: package install via the existing `packages.txt` manifest, interactive enrollment (one-time, user-driven), and a small idempotent bootstrap script that adds `pam_fprintd.so` to the two PAM stacks if not already present. ## Current State - **Hardware:** Goodix `27c6:609c` USB fingerprint reader (well-supported by libfprint's `goodix.MOC` driver) - **Software:** `fprintd` and `libfprint` are NOT installed - **PAM:** No `pam_fprintd.so` line in any `/etc/pam.d/` file - **Enrollments:** none ## Target State After install + enrollment + bootstrap script: | Service | Behaviour | |---|---| | `sudo` | Prompt offers fingerprint first; falls back to password if it fails / times out | | `gtklock` (lockscreen) | Same — touch the reader to unlock; type password if it fails | | `login`, `system-local-login`, `polkit-1` | Untouched — password only (boot-time fingerprint is finicky; polkit-1 has no existing PAM file) | ## Implementation ### Phase 1: Package install Add to `packages.txt`: ``` fprintd ``` `libfprint` is pulled in as a dependency. `fprintd.service` auto-starts via dbus activation — no `systemctl enable` needed. ### Phase 2: Enrollment (interactive, user-driven) After install, the user runs: ``` fprintd-enroll ``` Default enrolls right-index. Additional fingers via `fprintd-enroll -f left-thumb` (or `right-thumb`, `left-index`, etc.). Verify with `fprintd-list $USER`. This step is interactive and not scriptable — documented in the README. ### Phase 3: PAM wiring via bootstrap script **`scripts/enable-fingerprint.sh`** — new, idempotent, requires sudo, run once. For each of `/etc/pam.d/sudo` and `/etc/pam.d/gtklock`, inserts this exact line at the top of the auth stack (before the first existing `auth` directive), if not already present: ``` auth sufficient pam_fprintd.so ``` `sufficient` means: fingerprint success → skip password; fingerprint missing/failure → fall through to the existing password auth. Never blocks login on fingerprint failure. The script: 1. Checks each target file for `pam_fprintd` (already present → skip with message) 2. Backs up the file to `.bak.` before editing 3. Inserts the new line on a fresh line directly before the first `auth ` line 4. Prints what changed Why a script vs tracking the PAM files in the repo: `/etc/pam.d/sudo` is owned by the `sudo` pacman package and `/etc/pam.d/gtklock` by `gtklock`. Tracking modified copies and `sudo install`-ing them via `install.sh` would clobber pacman updates of those packages. An idempotent one-time edit is the cleanest path. ### Phase 4: README documentation Append a `### One-time fingerprint setup` subsection under `## Setup`, alongside the existing hibernation + NetworkManager subsections. Three steps documented: 1. Run `install.sh` (gets `fprintd` installed via packages.txt) 2. Enroll a finger: `fprintd-enroll` 3. Wire up PAM: `sudo bash scripts/enable-fingerprint.sh` ## Files Touched | File | Action | |---|---| | `packages.txt` | add `fprintd` | | `scripts/enable-fingerprint.sh` | created | | `README.md` | append `### One-time fingerprint setup` subsection | ## Verification After all three phases: ``` fprintd-list $USER # lists enrolled fingers fprintd-verify # touch reader → "verify-match" grep pam_fprintd /etc/pam.d/sudo /etc/pam.d/gtklock # both have the line ``` Behavioural checks: 1. Run `sudo true` — prompts for fingerprint first; if you touch the reader → no password requested. 2. Lock screen (`Mod+Shift+E`) → touch reader → unlocks without typing password. 3. Disconnect the fingerprint reader (theoretically; you can't physically with a built-in one — instead `pkill fprintd; sudo systemctl mask fprintd` temporarily): both services should still accept the password, proving the fallback works. Restore with `sudo systemctl unmask fprintd`. ## Out of Scope - **Tracking PAM files in the repo** — would clobber pacman-owned files. Bootstrap script edits in place instead. - **Adding fingerprint to login/system-local-login/polkit-1** — boot-time fingerprint is finicky (USB device may not be ready); polkit-1 has no existing PAM file. Easy follow-up if desired. - **Automatic enrollment** — `fprintd-enroll` is inherently interactive. - **Custom enrollment of multiple fingers** — user runs `fprintd-enroll -f ` as needed. - **Removing fingerprint from PAM** — manual `sudo sed -i '/pam_fprintd/d' /etc/pam.d/sudo /etc/pam.d/gtklock` reverses it; not scripted. - **Backwards-compatible PAM stack** that survives package updates of `sudo`/`gtklock`. Acceptable risk: pacman package updates of these are rare; if it happens, the script is idempotent — run it again to re-add the line.