Gate sudo fingerprint behind lid state too

Extend the clamshell gate to /etc/pam.d/sudo, not just polkit-1. When the
lid is shut the reader is unreachable, so a terminal sudo would block on
"Place your finger" until pam_fprintd timed out before letting you type the
password. The same pam_exec gate (success=1 skips fingerprint when the lid
is closed) now runs ahead of pam_fprintd in the sudo stack as well.

setup and removal share one gate definition across sudo and polkit; the
migration now gates both stacks on existing installs.

Resolves the clamshell case in #856 and supersedes #6003.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
David Heinemeier Hansson
2026-07-23 15:29:22 -07:00
co-authored by Claude Opus 4.8
parent 8e549c27d0
commit cb9485f216
3 changed files with 36 additions and 29 deletions
+3 -3
View File
@@ -7,10 +7,10 @@ set -e
remove_pam_config() { remove_pam_config() {
# Remove from sudo # Remove from sudo (both the fingerprint module and its clamshell gate)
if grep -q pam_fprintd.so /etc/pam.d/sudo; then if grep -Eq 'pam_fprintd\.so|omarchy-hw-laptop-closed' /etc/pam.d/sudo; then
echo "Removing fingerprint authentication from sudo..." echo "Removing fingerprint authentication from sudo..."
sudo sed -i '/pam_fprintd\.so/d' /etc/pam.d/sudo sudo sed -i -e '/pam_fprintd\.so/d' -e '/omarchy-hw-laptop-closed/d' /etc/pam.d/sudo
fi fi
# Remove from polkit (both the fingerprint module and its clamshell gate) # Remove from polkit (both the fingerprint module and its clamshell gate)
+19 -14
View File
@@ -7,23 +7,29 @@ set -e
setup_pam_config() { setup_pam_config() {
# Configure sudo # A clamshell gate runs before pam_fprintd in every stack: when the lid is
if ! grep -q pam_fprintd.so /etc/pam.d/sudo; then # shut the reader is unreachable, so it skips fingerprint (success=1) and PAM
echo "Configuring sudo for fingerprint authentication..." # drops straight to the password prompt instead of blocking on the reader
sudo sed -i '1i auth sufficient pam_fprintd.so' /etc/pam.d/sudo # until it times out. Lid open → fingerprint, then password as the fallback.
fi
# Configure polkit. A clamshell gate runs before pam_fprintd: when the lid
# is shut the reader is unreachable, so it skips fingerprint (success=1) and
# PAM drops straight to the password prompt. Lid open → fingerprint, then
# password as the fallback.
# #
# pam_exec needs a literal absolute path (no env expansion). Point at the # pam_exec needs a literal absolute path (no env expansion). Point at the
# fixed /usr/bin path the omarchy package always provides, so the gate keeps # fixed /usr/bin path the omarchy package always provides, so the gate keeps
# working across package installs and dev-link — the latter overlays # working across package installs and dev-link — the latter overlays
# $OMARCHY_PATH trees but leaves /usr/bin untouched. # $OMARCHY_PATH trees but leaves /usr/bin untouched.
local polkit_gate="auth [success=1 default=ignore] pam_exec.so quiet /usr/bin/omarchy-hw-laptop-closed" local fprintd_gate="auth [success=1 default=ignore] pam_exec.so quiet /usr/bin/omarchy-hw-laptop-closed"
# Configure sudo
if ! grep -q pam_fprintd.so /etc/pam.d/sudo; then
echo "Configuring sudo for fingerprint authentication..."
sudo sed -i '1i auth sufficient pam_fprintd.so' /etc/pam.d/sudo
fi
if ! grep -q 'omarchy-hw-laptop-closed' /etc/pam.d/sudo; then
echo "Adding clamshell gate to sudo..."
# Insert immediately before pam_fprintd so success=1 skips exactly it.
sudo sed -i "/pam_fprintd\.so/i $fprintd_gate" /etc/pam.d/sudo
fi
# Configure polkit
if [[ -f /etc/pam.d/polkit-1 ]]; then if [[ -f /etc/pam.d/polkit-1 ]]; then
if ! grep -q 'pam_fprintd.so' /etc/pam.d/polkit-1; then if ! grep -q 'pam_fprintd.so' /etc/pam.d/polkit-1; then
echo "Configuring polkit for fingerprint authentication..." echo "Configuring polkit for fingerprint authentication..."
@@ -31,13 +37,12 @@ setup_pam_config() {
fi fi
if ! grep -q 'omarchy-hw-laptop-closed' /etc/pam.d/polkit-1; then if ! grep -q 'omarchy-hw-laptop-closed' /etc/pam.d/polkit-1; then
echo "Adding clamshell gate to polkit..." echo "Adding clamshell gate to polkit..."
# Insert immediately before pam_fprintd so success=1 skips exactly it. sudo sed -i "/pam_fprintd\.so/i $fprintd_gate" /etc/pam.d/polkit-1
sudo sed -i "/pam_fprintd\.so/i $polkit_gate" /etc/pam.d/polkit-1
fi fi
else else
echo "Creating polkit configuration with fingerprint authentication..." echo "Creating polkit configuration with fingerprint authentication..."
sudo tee /etc/pam.d/polkit-1 >/dev/null <<EOF sudo tee /etc/pam.d/polkit-1 >/dev/null <<EOF
$polkit_gate $fprintd_gate
auth sufficient pam_fprintd.so auth sufficient pam_fprintd.so
auth required pam_unix.so auth required pam_unix.so
+14 -12
View File
@@ -1,21 +1,23 @@
echo "Gate polkit fingerprint auth behind the lid state (password when the lid is shut)" echo "Gate sudo and polkit fingerprint auth behind the lid state (password when the lid is shut)"
# Existing fingerprint setups have pam_fprintd first in /etc/pam.d/polkit-1 but # Existing fingerprint setups have pam_fprintd first in /etc/pam.d/sudo and
# no lid gate, so a closed-lid pkexec would block on the unreachable reader for # /etc/pam.d/polkit-1 but no lid gate, so a closed-lid sudo or pkexec would
# the full pam_fprintd timeout before offering the password. Insert a pam_exec # block on the unreachable reader for the full pam_fprintd timeout before
# gate before pam_fprintd that skips fingerprint while the lid is closed. New # offering the password. Insert a pam_exec gate before pam_fprintd that skips
# setups already get this from omarchy-setup-security-fingerprint. # fingerprint while the lid is closed. New setups already get this from
# omarchy-setup-security-fingerprint.
# #
# The gate points at the fixed /usr/bin path the omarchy package always # The gate points at the fixed /usr/bin path the omarchy package always
# provides, so it keeps working across package installs and dev-link (which # provides, so it keeps working across package installs and dev-link (which
# overlays $OMARCHY_PATH but leaves /usr/bin untouched). pam_exec needs a # overlays $OMARCHY_PATH but leaves /usr/bin untouched). pam_exec needs a
# literal absolute path — it does not expand env vars. # literal absolute path — it does not expand env vars.
polkit_pam="/etc/pam.d/polkit-1"
gate="auth [success=1 default=ignore] pam_exec.so quiet /usr/bin/omarchy-hw-laptop-closed" gate="auth [success=1 default=ignore] pam_exec.so quiet /usr/bin/omarchy-hw-laptop-closed"
if [[ -f $polkit_pam ]] && for pam in /etc/pam.d/sudo /etc/pam.d/polkit-1; do
grep -q 'pam_fprintd\.so' "$polkit_pam" && if [[ -f $pam ]] &&
! grep -q 'omarchy-hw-laptop-closed' "$polkit_pam"; then grep -q 'pam_fprintd\.so' "$pam" &&
sudo sed -i "/pam_fprintd\.so/i $gate" "$polkit_pam" ! grep -q 'omarchy-hw-laptop-closed' "$pam"; then
fi sudo sed -i "/pam_fprintd\.so/i $gate" "$pam"
fi
done