Gate sudo fingerprint behind lid state (clamshell)#6003
Conversation
When fingerprint auth is set up, pam_fprintd is inserted first and `sufficient` in /etc/pam.d/sudo, so it blocks the password prompt with "Place your finger…". In clamshell mode (lid closed, docked to an external monitor) the reader is unreachable, forcing an awkward wait before every sudo. Gate pam_fprintd behind a small pam_exec helper that checks the laptop lid state, so fingerprint is only attempted when the lid is open and sudo falls straight through to the password stack when the lid is closed. - sudo only; polkit is left as-is (its GUI dialog shows a password field in parallel and never blocks the way terminal sudo does) - desktops / machines without an ACPI lid button are untouched - fail-safe: helper missing / errors / unknown lid state -> password, never lockout Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds a lid-state guard so that sudo fingerprint authentication is skipped when a laptop lid is closed (e.g., clamshell mode), preventing sudo from hanging on an unreachable reader. A small helper script (omarchy-lid-open) is installed and invoked via pam_exec before pam_fprintd. A migration applies the same guard to existing installs, and the remove script cleans it up.
Changes:
- New migration script that installs the lid helper and inserts a
pam_execguard abovepam_fprintd.soin/etc/pam.d/sudoon laptops. omarchy-setup-security-fingerprintnow detects an ACPI lid, installs the helper, and inserts the PAM guard during fresh setup.omarchy-remove-security-fingerprintstrips the PAM guard line from/etc/pam.d/sudoand removes the helper binary.
Reviewed changes
Copilot reviewed 1 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| migrations/1780152390.sh | Backfills lid-guard helper and PAM rule on existing systems with fingerprint sudo |
| bin/omarchy-setup-security-fingerprint | Adds has_lid/install_lid_helper and inserts the lid guard during setup |
| bin/omarchy-remove-security-fingerprint | Removes the lid guard PAM line and deletes the helper binary |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| sudo tee /usr/local/bin/omarchy-lid-open >/dev/null <<'EOF' | ||
| #!/bin/bash | ||
| # omarchy:summary=Exit 0 if the laptop lid is open (used by PAM to gate fingerprint auth) | ||
| for f in /proc/acpi/button/lid/*/state; do | ||
| [[ -r "$f" ]] || continue | ||
| grep -q open "$f" && exit 0 || exit 1 | ||
| done | ||
| exit 0 | ||
| EOF |
There was a problem hiding this comment.
Thanks for the catch. I went back and forth on this one.
These migrations are run-once, self-contained snapshots: omarchy-migrate executes each file with bash $file, records it in the state dir, and never touches it again. Keeping the helper body inline here is deliberate so the migration reproduces exactly what shipped at this point in time, independent of any later change to install_lid_helper. The single ongoing source of truth is install_lid_helper in omarchy-setup-security-fingerprint; the migration's copy is frozen at merge and won't need to be kept in sync.
I considered extracting the helper into a shared shipped file that both consumers install, but the natural home (bin/omarchy-lid-open) would surface it as an omarchy-lid-open entry in omarchy commands (it carries an # omarchy:summary= header) for what is really an internal PAM helper. Happy to go that route and drop the summary header if you'd prefer a single physical copy — let me know.
| for f in /proc/acpi/button/lid/*/state; do | ||
| [[ -r "$f" ]] || continue | ||
| grep -q open "$f" && exit 0 || exit 1 | ||
| done |
There was a problem hiding this comment.
This (the && exit 0 || exit 1 idiom) is now fixed in both places.
Address review feedback: the `cmd && exit 0 || exit 1` idiom is a known footgun and obscures intent. Spell it out as an if/else in both the setup helper and the migration's copy. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Problem
When fingerprint auth is set up,
omarchy-setup-security-fingerprintinsertsauth sufficient pam_fprintd.soat the top of/etc/pam.d/sudo. Because it is first andsufficient,pam_fprintdgrabs stdin with "Place your finger…" and blocks the password prompt until it times out.In clamshell mode (laptop lid closed, docked to an external display) the reader is physically unreachable, so every
sudoforces an awkward wait before you can type your password.Fix (sudo only)
Run
pam_fprintdonly when the lid is open. PAM can't read lid state, so a tinypam_exechelper (/usr/local/bin/omarchy-lid-open) gates it:success=ignore→ falls through topam_fprintd→ fingerprint as before.default=1→ jumps over the fprintd line → straight to the password stack.default=1→ password. Fail-safe: never a lockout.Scope & safety
/etc/pam.d/polkit-1is intentionally left as-is — the polkit agent shows a password field in parallel with fingerprint, so it never blocks the way terminalsudodoes.has_lid()is false when there is no/proc/acpi/button/lid/*/state, so setup inserts only the plainpam_fprintdline (today's behavior), no helper is installed, and the migration no-ops. A laptop with no ACPI lid button is treated like a desktop (fix simply doesn't engage).pam_execships with the basepampackage — no new dependency./usr/local/bin(not repobin/, which is only on the user's$PATH) so PAM as root has a stable absolute path. Installed viasudo tee, mirroring the existing polkit-1 heredoc.Changes
bin/omarchy-setup-security-fingerprint:has_lid(),install_lid_helper(); on laptops insert the lid guard above the sudopam_fprintdline. polkit untouched.bin/omarchy-remove-security-fingerprint: strip the guard from sudo and remove the helper.migrations/1780152390.sh: upgrade existing laptop installs idempotently; no-op on desktops.Testing
Verified locally on a ThinkPad X1 Carbon gen 14 (Omarchy 3.8.2):
bash -nclean on all three scripts./proc(lid open → exit 0), simulated closed lid (exit 1), and no-lid/desktop (exit 0)./etc/pam.d/sudo(with backup) and exercisedsudo -k; sudo truein both lid states: lid open prompts for fingerprint as before; lid closed (clamshell on external monitor) goes straight to the password prompt with no fingerprint wait. Toggled back and forth repeatedly with consistent results.🤖 Generated with Claude Code