PAM integration
deploy.sh adds auth sufficient pam_exec.so quiet stdout /usr/local/bin/vinoauthface-auth to:
| Service | File | Covers |
|---|---|---|
sudo |
/etc/pam.d/sudo |
sudo |
gdm-password |
/etc/pam.d/gdm-password |
GNOME lock screen |
swaylock |
/etc/pam.d/swaylock |
swaylock |
polkit-1 |
/etc/pam.d/polkit-1 |
polkit prompts |
kde-fingerprint or kde-smartcard |
/etc/pam.d/kde-fingerprint or kde-smartcard |
KDE lock screen (one of the two, see KDE) |
cosmic-greeter |
/etc/pam.d/cosmic-greeter |
COSMIC lock screen and greeter |
The Plasma login screen is opt-in and set separately: see Login screen.
The line goes just above the first auth line that actually authenticates: pam_unix,
pam_sss, pam_fprintd, pam_u2f, or an include/substack/@include of another stack.
Gates above that point, like pam_nologin, pam_faillock preauth and Fedora’s
pam_selinux_permit, still run before a face match can end the stack. Gates inside an included
stack (Fedora’s system-auth, say) don’t.
If a stack the service includes already runs vinoAuthFace (added by hand, an authselect profile,
an older install), deploy.sh skips the service rather than scan the camera twice per attempt.
sufficient means a face match (exit 0) authenticates immediately. Anything else (no match, no
camera, timeout, lockout) falls through to the password prompt. quiet keeps pam_exec chatter
out of the unlock UI.
While scanning, vinoauthface-auth shows Looking for your face...:
- With a terminal (
sudoin a terminal or on a VT), it’s written to the controlling terminal and erased when the scan ends. - Without one (lock screens, login screens, polkit agents), it’s written once to stdout, which
stdouthaspam_execrelay to the application as a PAM info message, as it arrives. The application decides how to show it and replaces it with its own prompt if the scan falls through.pam_execrelays stderr the same way, so in this modevinoauthface-authsends its stderr to/dev/null: errors are injournalctl -t vinoauthface-autheither way.
Only sudo (and sudo -i, sudo su -, which authenticate through it) is covered on a text
console. su isn’t: it authenticates the target account, so a face can only ever match the
caller’s own account. Console login isn’t wired up either.
Installs from before this change have the line without stdout and stay silent on lock screens
until deploy.sh is re-run (update.sh doesn’t touch PAM).
KDE
KScreenLocker runs two background PAM services next to the password field, kde-fingerprint and
kde-smartcard. deploy.sh puts face in one of them, so the KDE lock screen unlocks hands-free:
look at the camera and it opens, or type your password as usual.
kde-fingerprint |
kde-smartcard |
Face goes in | Line |
|---|---|---|---|
No pam_fprintd |
any | kde-fingerprint |
[success=done new_authtok_reqd=done default=die] |
Runs pam_fprintd |
No smartcard module | kde-smartcard |
[success=done new_authtok_reqd=done default=die] |
Runs pam_fprintd |
Runs pam_pkcs11, pam_p11 or pam_sss, or is missing |
kde-fingerprint |
sufficient |
pam_fprintd and the smartcard modules count in the service’s own file or in a stack it includes
(Fedora’s fingerprint-auth and smartcard-auth). In the smartcard slot, face and finger run at
the same time and Plasma’s hint reads “(or scan your smartcard)”. Sharing the fingerprint slot
with fprintd, face runs first and the reader waits until the scan ends. Re-running deploy.sh
after enabling or disabling fingerprint login moves face to match.
In a slot of its own, a miss ends the stack with an error instead of falling through. On Fedora the rest of the stack is a stub that answers “unavailable”, and KScreenLocker stops using a service that answers that until the next lock.
KScreenLocker starts these services when the lock screen wakes (a key or mouse move), not when it locks, so walking up to a locked laptop and moving the mouse starts a scan. It doesn’t retry one that missed: moving the mouse again does nothing. To scan again, press Enter on an empty password field (or type a wrong one). The failed password restarts every service 3 seconds later.
Login screen
Face unlock at the Plasma login screen has three modes, off by default:
| Mode | PAM | At the login screen |
|---|---|---|
off |
Nothing | Password only |
both |
required line below plasmalogin’s password stack |
Type your password, then look at the camera. Both must pass. The password still unlocks KWallet |
face |
sufficient line above the password, in plasmalogin-fingerprint if the system has it, plasmalogin if not |
A match logs you in; anything else falls back to the password. KWallet stays locked (see Keyrings) |
Set it with sudo ./deploy.sh --login=off|both|face (or FACE_AUTH_LOGIN), the tray’s “Login
screen” submenu, or sudo /usr/local/share/face-auth/login-mode.sh off|both|face directly.
login-mode.sh status prints the current one. A deploy or upgrade without --login keeps
whatever is set.
plasmalogin-fingerprint runs hands-free beside the password field. Fedora 45 ships only
plasmalogin, so there face needs you to select your account and press Enter with the password
field empty. Only one of the two is ever wired, or the greeter would scan twice.
In both, the camera is a hard requirement. A covered camera, a closed lid, an active face
lockout or a broken NPU driver means no graphical login until it’s fixed; log in on a text console
(Ctrl+Alt+F3) and run sudo /usr/local/share/face-auth/login-mode.sh off. A wrong password still
starts a scan, since PAM runs the rest of the stack either way; the login fails regardless.
GDM and COSMIC aren’t covered: gdm-password and cosmic-greeter also run their lock screens,
where they keep the face-or-password line.
The greeter runs face-auth in SELinux’s xdm_t, which needs deploy.sh’s policy (see
install.md). Sealed templates (seal_embeddings = true) are unsealed there
by vinoauthface-unseal in its own domain, so the greeter never gets the TPM or systemd’s host
key. An install without the helper (a release from before it) can’t unseal at the greeter:
face falls back to the password, and login-mode.sh refuses both, which nobody could get
past. Re-run deploy.sh to fix that.
Plasma before 6.7 has a bug where a biometric unlock counts against pam_faillock
(kscreenlocker 29d01bf7), so repeated face unlocks can lock the password out until it expires.
Update Plasma or drop pam_faillock from the stack if you hit it.
COSMIC
cosmic-greeter is one service for both the lock screen and the greeter. It shows a single PAM
message at a time, so the password field is hidden while vinoAuthFace scans, and there is no text
to say so. At login it runs as the greeter user rather than the person unlocking.
Vendor-only services
On image-based distros these services often exist only as a vendor default in /usr/lib/pam.d.
deploy.sh copies that file to /etc/pam.d first to have something to patch (as it does for
polkit-1), and uninstall.sh deletes the copy rather than “restoring” a file that never
existed.
polkit
polkit-1 covers every polkit auth_self prompt: pkexec, package-manager GUIs, settings
changes, and apps like Bitwarden that ask polkit to re-authenticate you. Most distros ship only
the vendor default in /usr/lib/pam.d/polkit-1, so deploy.sh copies it to /etc/pam.d/polkit-1
first to have something to patch. uninstall.sh deletes that copy rather than “restoring” a file
that never existed.
vinoAuthFace only authenticates the account running the prompt. When an admin authenticates on behalf of another logged-in user, it falls through to the password.
Bitwarden biometric unlock
If a Bitwarden desktop client is installed (native, Flatpak or Snap), deploy.sh also installs
Bitwarden’s polkit action (/usr/share/polkit-1/actions/com.bitwarden.Bitwarden.policy). Flatpak
and Snap builds are sandboxed and can’t write it themselves. The content is transcribed from
Bitwarden’s own source (os-biometrics-linux.service.ts in
bitwarden/clients), not downloaded. Then enable
Settings → Unlock with system authentication in Bitwarden.
Keyrings
A face match means PAM never sees a password. Any module that unlocks a secret store from the login password has nothing to unlock it with, so after a face login:
| Store | Module | After face login |
|---|---|---|
| KWallet | pam_kwallet5 |
Locked |
| oo7 (Fedora 45’s default Secret Service) | pam_oo7 |
Locked |
| GNOME Keyring | pam_gnome_keyring |
Locked |
The first app that needs a secret asks for the password once, then the store stays open for the session.
- Lock screen unlock is fine. The store was opened at login and stays open across screen locks, so there’s nothing for vinoAuthFace to gate there.
- Plasma Login Manager quirk. If you typed a password and your face matched first, PLM still
hands the typed text to
pam_kwallet5, so the wallet unlocks. A mistyped password gives a face login with a locked wallet. - No TPM-sealed password. Some projects seal a copy of the login password to the TPM and feed
it back as
PAM_AUTHTOKafter a face match.pam_execcan’t setPAM_AUTHTOK, so that needs a real PAM.somodule, which this project doesn’t ship. Not planned.