Proof Portal

Project overview

Omarchy

ProbeLabs65 findings · 95 requirements

A proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.

Inbox
ReportR-37GitHub issuePublicDecided· Out of scope

omarchy setup security fingerprint cannot configure PAM once a print is already enrolled

Reported by sleepingcrows · filed Sep 27, 2026 · open at source

Decided: Out of scope — decided by agents · verified 3 days ago.

At a glance

1 · What is claimed?
Only the report text below — no validator has restated it as checkable claims yet.
2 · What does it affect?
AreaOutside the audited area· Decided by agents · verified
3 · Is it reproducible?
No validation has been run yet.
4 · What remains unclear?
  • Not validated yet: no claims, no reproducer.
5 · What happens next?
Decided by agents and verified by a second, independent agent — see the decision.

Original report

omarchy setup security fingerprint cannot configure PAM once a print is already enrolledrevision 1 · captured 2026-09-28 21:23 UTC via poll

Summary

omarchy setup security fingerprint cannot configure PAM once a fingerprint is already enrolled. Re-running it always fails at the enroll step and exits before writing any PAM configuration, leaving the enrolled fingerprint unusable for sudo, polkit, and the lock screen.

There is no way out of this state from the setup wizard alone.

What happens

omarchy-setup-security-fingerprint only calls setup_pam_config and setup_lock_fingerprint_pam from inside the success branch of the enroll step:

if sudo fprintd-enroll "$USER"; then
  echo -e "\e[32m\nFingerprint enrolled successfully!\e[0m"

  # Verify
  echo -e "\nNow let's verify that it's working correctly.\n"
  if fprintd-verify; then
    # PAM comes last, once a print is enrolled and verified. ...
    setup_pam_config
    setup_lock_fingerprint_pam
    echo -e "\e[32m\nPerfect! Fingerprint authentication is now configured.\e[0m"
    ...
  else
    echo -e "\e[31m\nVerification failed. You may want to try enrolling again.\e[0m"
  fi
else
  echo -e "\e[31m\nEnrollment failed. Please try again.\e[0m"
  exit 1
fi

Once a print exists, fprintd-enroll returns a non-success result for a finger that is already in the database:

$ fprintd-enroll right-index-finger
Using device /net/reactivated/Fprint/Device/0
Enrolling right-index-finger finger.
Enroll result: enroll-duplicate

fprintd-enroll exits non-zero on any non-success enroll result, so the else branch runs, the script prints "Enrollment failed" and exit 1 — and setup_pam_config is never reached.

The comment in the script shows the ordering (PAM last) is deliberate, but combined with enroll not being idempotent it produces a deadlock:

  • Print enrolled, PAM unconfigured -> fingerprint does nothing
  • Re-run wizard -> enroll-duplicate -> exit 1 -> PAM still unconfigured
  • Repeat forever

Steps to reproduce

  1. On a machine with a working fingerprint reader, run omarchy setup security fingerprint and complete enrollment.
  2. Confirm the print is enrolled: fprintd-list $USER lists it.
  3. Re-run omarchy setup security fingerprint — the enrollment step now fails and the wizard exits non-zero.
  4. Confirm no PAM configuration was written:
  • grep pam_fprintd /etc/pam.d/sudo -> no match
  • /etc/pam.d/polkit-1 -> does not exist
  • /etc/pam.d/omarchy-lock-fingerprint -> does not exist
  1. The enrolled fingerprint does not work for sudo/polkit/lock screen.

Observed on a machine that hit this state: a print was enrolled and fprintd-verify returned verify-match, but /etc/pam.d/sudo had no pam_fprintd.so, /etc/pam.d/polkit-1 did not exist, and /etc/pam.d/omarchy-lock-fingerprint did not exist.

What was expected

Re-running the setup wizard should be recoverable. Either it should configure PAM for the already-enrolled print, or it should tell the user what is already enrolled and offer to re-enroll.

Suggested fix directions

Any one of these breaks the deadlock:

  • Treat enroll-duplicate as non-fatal and fall through to the verify + PAM steps, since a print already exists.
  • Configure PAM before/independently of the enroll result, guarded by "is a print enrolled" rather than "did this run's enroll succeed".
  • Detect an existing print up front and skip straight to verify + PAM setup.

There is also no in-product way to reset the state. omarchy-remove-security-fingerprint does not run fprintd-delete — it only strips the PAM lines, removes /etc/pam.d/omarchy-lock-fingerprint, and drops the fprintd/libfprint/libfprint-git packages. The enrolled print in /var/lib/fprint/ survives, because that is package-independent state. So remove-then-setup reinstalls the packages and lands straight back on enroll-duplicate, with PAM unconfigured again.

System details

Omarchy4.0.4-1
Kernel7.2.5-3-omarchy
MachineLenovo ThinkPad T450s (20BWS30000)
CPUIntel Core i7-5600U @ 2.60GHz
GPUIntel Broadwell-U GT2 (HD Graphics 5500)
ReaderValidity Sensors VFS 5011, 138a:0017 (swipe)
fprintd1.94.5-2
libfprintlibfprint-git 1:1.94.100.r10.g6f9479c-1

Note the reader is a swipe type, and libfprint drives it from userspace over libusb with no kernel driver bound (Driver=[none] in lsusb -t) — expected for this reader.

Additional observation: reader wedges on repeated enroll attempts

While reproducing this, repeated fprintd-enroll calls against this VFS 5011 left the reader unable to open at all:

$ fprintd-enroll left-middle-finger
Using device /net/reactivated/Fprint/Device/0
failed to claim device: GDBus.Error:net.reactivated.Fprint.Error.Internal: Open failed with error: transfer failed

The kernel log shows the reader disconnecting and re-enumerating repeatedly, and it only recovered after settling:

usb 1-6: USB disconnect, device number 7
usb 1-6: new full-speed USB device number 8 using xhci_hcd
usb 1-6: USB disconnect, device number 8
usb 1-6: new full-speed USB device number 9 using xhci_hcd

After that, fprintd-verify returned verify-match again with no intervention. fprintd also logged, throughout normal operation:

fpi_image_device_activate_complete: assertion 'priv->active == FALSE' failed

This may be specific to this swipe reader rather than Omarchy, but it compounds the main bug: because the wizard is not re-runnable, a user who hits the duplicate state is likely to retry enrollment repeatedly, which is what wedged the reader here. Flagging in case it is useful.

View raw text
## Summary

`omarchy setup security fingerprint` cannot configure PAM once a fingerprint is already enrolled. Re-running it always fails at the enroll step and exits before writing any PAM configuration, leaving the enrolled fingerprint unusable for sudo, polkit, and the lock screen.

There is no way out of this state from the setup wizard alone.

## What happens

`omarchy-setup-security-fingerprint` only calls `setup_pam_config` and `setup_lock_fingerprint_pam` from inside the success branch of the enroll step:

```bash
if sudo fprintd-enroll "$USER"; then
  echo -e "\e[32m\nFingerprint enrolled successfully!\e[0m"

  # Verify
  echo -e "\nNow let's verify that it's working correctly.\n"
  if fprintd-verify; then
    # PAM comes last, once a print is enrolled and verified. ...
    setup_pam_config
    setup_lock_fingerprint_pam
    echo -e "\e[32m\nPerfect! Fingerprint authentication is now configured.\e[0m"
    ...
  else
    echo -e "\e[31m\nVerification failed. You may want to try enrolling again.\e[0m"
  fi
else
  echo -e "\e[31m\nEnrollment failed. Please try again.\e[0m"
  exit 1
fi
```

Once a print exists, `fprintd-enroll` returns a non-success result for a finger that is already in the database:

```
$ fprintd-enroll right-index-finger
Using device /net/reactivated/Fprint/Device/0
Enrolling right-index-finger finger.
Enroll result: enroll-duplicate
```

`fprintd-enroll` exits non-zero on any non-success enroll result, so the `else` branch runs, the script prints "Enrollment failed" and `exit 1` — and `setup_pam_config` is never reached.

The comment in the script shows the ordering (PAM last) is deliberate, but combined with enroll not being idempotent it produces a deadlock:

- Print enrolled, PAM unconfigured -> fingerprint does nothing
- Re-run wizard -> `enroll-duplicate` -> `exit 1` -> PAM still unconfigured
- Repeat forever

## Steps to reproduce

1. On a machine with a working fingerprint reader, run `omarchy setup security fingerprint` and complete enrollment.
2. Confirm the print is enrolled: `fprintd-list $USER` lists it.
3. Re-run `omarchy setup security fingerprint` — the enrollment step now fails and the wizard exits non-zero.
4. Confirm no PAM configuration was written:
   - `grep pam_fprintd /etc/pam.d/sudo` -> no match
   - `/etc/pam.d/polkit-1` -> does not exist
   - `/etc/pam.d/omarchy-lock-fingerprint` -> does not exist
5. The enrolled fingerprint does not work for sudo/polkit/lock screen.

Observed on a machine that hit this state: a print was enrolled and `fprintd-verify` returned `verify-match`, but `/etc/pam.d/sudo` had no `pam_fprintd.so`, `/etc/pam.d/polkit-1` did not exist, and `/etc/pam.d/omarchy-lock-fingerprint` did not exist.

## What was expected

Re-running the setup wizard should be recoverable. Either it should configure PAM for the already-enrolled print, or it should tell the user what is already enrolled and offer to re-enroll.

## Suggested fix directions

Any one of these breaks the deadlock:

- Treat `enroll-duplicate` as non-fatal and fall through to the verify + PAM steps, since a print already exists.
- Configure PAM before/independently of the enroll result, guarded by "is a print enrolled" rather than "did this run's enroll succeed".
- Detect an existing print up front and skip straight to verify + PAM setup.

There is also no in-product way to reset the state. `omarchy-remove-security-fingerprint` does not run `fprintd-delete` — it only strips the PAM lines, removes `/etc/pam.d/omarchy-lock-fingerprint`, and drops the `fprintd`/`libfprint`/`libfprint-git` packages. The enrolled print in `/var/lib/fprint/` survives, because that is package-independent state. So remove-then-setup reinstalls the packages and lands straight back on `enroll-duplicate`, with PAM unconfigured again.

## System details

| | |
|---|---|
| Omarchy | 4.0.4-1 |
| Kernel | 7.2.5-3-omarchy |
| Machine | Lenovo ThinkPad T450s (20BWS30000) |
| CPU | Intel Core i7-5600U @ 2.60GHz |
| GPU | Intel Broadwell-U GT2 (HD Graphics 5500) |
| Reader | Validity Sensors VFS 5011, `138a:0017` (swipe) |
| fprintd | 1.94.5-2 |
| libfprint | libfprint-git 1:1.94.100.r10.g6f9479c-1 |

Note the reader is a swipe type, and libfprint drives it from userspace over libusb with no kernel driver bound (`Driver=[none]` in `lsusb -t`) — expected for this reader.

## Additional observation: reader wedges on repeated enroll attempts

While reproducing this, repeated `fprintd-enroll` calls against this VFS 5011 left the reader unable to open at all:

```
$ fprintd-enroll left-middle-finger
Using device /net/reactivated/Fprint/Device/0
failed to claim device: GDBus.Error:net.reactivated.Fprint.Error.Internal: Open failed with error: transfer failed
```

The kernel log shows the reader disconnecting and re-enumerating repeatedly, and it only recovered after settling:

```
usb 1-6: USB disconnect, device number 7
usb 1-6: new full-speed USB device number 8 using xhci_hcd
usb 1-6: USB disconnect, device number 8
usb 1-6: new full-speed USB device number 9 using xhci_hcd
```

After that, `fprintd-verify` returned `verify-match` again with no intervention. fprintd also logged, throughout normal operation:

```
fpi_image_device_activate_complete: assertion 'priv->active == FALSE' failed
```

This may be specific to this swipe reader rather than Omarchy, but it compounds the main bug: because the wizard is not re-runnable, a user who hits the duplicate state is likely to retry enrollment repeatedly, which is what wedged the reader here. Flagging in case it is useful.

Validation

Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.

Linked

  • Related PRpr/10689· confirmed

Decision

Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.

  • Out of scopeDecided by agents · verified · 2026-10-09 19:37 UTC