Modern face recognition authentication for Linux using PAM.
SecureEye is a clean, modern reimplementation of facial authentication for Linux systems. It enables users to authenticate via face recognition while maintaining a modular, secure, and maintainable architecture.
This project is inspired by the Howdy project but is being redesigned with updated technologies, improved structure, and long-term maintainability in mind.
- Face recognition-based authentication
- PAM (Pluggable Authentication Modules) integration
- Modular recognition pipeline
- CLI tools for user management
- Designed for modern Python environments
Early development. Core architecture and modules are being actively built.
These mirror the package Build-Depends in secureEye/debian/control:
- Meson 0.64 or higher, Ninja, pkg-config, a C++ compiler (
build-essential) - Python 3 with pip (
python3,python3-pip) libpam0g-dev,libevdev-dev,libinih-dev(INIReader is provided bylibinih-dev; it is not downloaded, the build runs with--wrap-mode=nodownload)
On Debian / Ubuntu:
sudo apt-get update && sudo apt-get install -y \
meson ninja-build pkg-config build-essential \
python3 python3-pip python3-venv \
libpam0g-dev libinih-dev libevdev-devOn Arch Linux (libinih provides INIReader, pam provides the PAM headers):
sudo pacman -S --needed base-devel meson ninja pkgconf \
python python-pip pam libinih libevdevmeson setup build
meson compile -C buildWarning
Do not run meson install on a machine where you also use the packaged
builds (.deb, .rpm or the AUR package). Meson's default prefix is
/usr/local, and /usr/local/lib/... shadows the packaged /usr/lib/...
systemd unit (and /usr/local/bin shadows /usr/bin), which breaks the
daemon and CLI. On Debian and Fedora a bare meson install also does not
create the recognition virtualenv, that is built by the secureeye-authd
package at install time, so the daemon will not start. For a working system
install, build and install your distribution's packages below.
SecureEye ships as three packages:
libpam-secureeye— the C/C++ PAM module (no Python)secureeye-authd— the authentication daemon and Python recognition runtimesecure-eye— a transitional metapackage that depends on both
Download the latest .deb files from the
GitHub releases page and
install all of them together so dependencies (including python3-venv) resolve:
sudo apt install ./libpam-secureeye_*.deb ./secureeye-authd_*.deb ./secure-eye_*.debOn install, secureeye-authd builds its recognition virtualenv from the bundled
wheels (this takes a short while) and enables the secureeye-authd.service.
sudo add-apt-repository ppa:vhrabar/tools
sudo apt update && sudo apt install secure-eyeThe easiest way is the COPR repository.
On Fedora:
sudo dnf copr enable vhrabar/SecureEye
sudo dnf install secure-eyeOn RHEL / CentOS Stream / Rocky / AlmaLinux (enable EPEL first for the copr
plugin and dependencies):
sudo dnf install epel-release
sudo dnf copr enable vhrabar/SecureEye
sudo dnf install secure-eyeThis installs the same three packages as on Debian (libpam-secureeye,
secureeye-authd, secure-eye). On install, secureeye-authd builds its
recognition virtualenv from the bundled wheels and enables the
secureeye-authd.service.
Alternatively, download the .rpm files from the
GitHub releases page and install
them together:
sudo dnf install ./libpam-secureeye-*.rpm ./secureeye-authd-*.rpm ./secure-eye-*.rpmNote
On Fedora/RHEL there is no pam-auth-update, so the PAM module is not
enabled automatically. Enable it as shown in Usage step 3b below (the
Debian-only pam-auth-update / common-auth steps do not apply).
SecureEye is packaged for the AUR as secureeye, which builds two packages:
libpam-secureeye: the C/C++ PAM module (no Python)secureeye-authd: the authentication daemon and Python recognition runtime
There is no transitional metapackage; install both. With an AUR helper:
paru -S libpam-secureeye secureeye-authd # or: yay -S ...Or manually with makepkg (the recognition dependencies python-mediapipe
and python-sounddevice also come from the AUR and must be built first):
git clone https://aur.archlinux.org/secureeye.git
cd secureeye
makepkg -siYou can also build straight from a checkout of this repository:
cd secureEye/archlinux/secureEye
makepkg -siUnlike the .deb/.rpm packages, the Arch build does not bundle a recognition virtualenv: every dependency is a
real package and the daemon runs on the system interpreter, so there is nothing to rebuild after a Python upgrade. On
aarch64 there is no MediaPipe, so the package depends on
python-dlib and ships detector_backend = dlib in the default config.
Following Arch policy, the service is not started for you:
sudo systemctl enable --now secureeye-authd.serviceNote
Arch has neither pam-auth-update nor authselect, so the PAM module is
not enabled automatically. Enable it as shown in Usage step 3c below.
1. Set your camera device. The default config ships with device_path = none,
so recognition does nothing until you point it at a real capture device. Open the
config and set device_path (e.g. /dev/video0):
sudo secureEye configYou can list capture-capable nodes with v4l2-ctl --list-devices. After changing
the device, restart the daemon: sudo systemctl restart secureeye-authd.
2. Enroll your face. SecureEye needs to learn your face so it can recognise you later:
sudo secureEye add3. Make sure the PAM profile is enabled.
3a) Ubuntu / Debian. It is normally enabled automatically on install, but
pam-auth-update will skip a profile it has already "seen" from a previous
install. Verify (and enable if needed):
grep -q pam_secureEye.so /etc/pam.d/common-auth && echo enabled || sudo pam-auth-update --enable secureEye.pam-config3b) Fedora / RHEL. There is no pam-auth-update; enable the module with an
authselect custom profile:
sudo authselect create-profile secureeye -b local
# Add this line near the top of the auth section of
# /etc/authselect/custom/secureeye/{system,password}-auth:
# auth sufficient pam_secureEye.so
sudo authselect select custom/secureeye --forceOr, for a single service (e.g. sudo only), add to /etc/pam.d/sudo:
auth sufficient pam_secureEye.so
Do not edit /etc/pam.d/system-auth directly as authselect overwrites it.
3c) Arch Linux. There is no pam-auth-update and no authselect; edit the PAM stack yourself. For a single service
(recommended, e.g. sudo only), add this as the first auth line of /etc/pam.d/sudo:
auth sufficient pam_secureEye.so
To cover every service that includes it (login, sudo, display-manager greeters, polkit), add the same line at the
top of the auth section of
/etc/pam.d/system-auth instead. That file belongs to the pam package, so back it up and re-apply your change when
pacman leaves a system-auth.pacnew
after an upgrade.
4. Try it. Open a new terminal and run sudo -i — you should be able to
authenticate by showing your face. If face auth fails or times out, SecureEye
falls back to your password. Please check
this wiki page if
you're experiencing problems or
search for similar issues.
The installer adds a secureEye command to manage face models for the current user. Use secureEye --help or
man secureEye to list the available options.
Usage:
secureEye [-U user] [-y] command [argument]
| Command | Description |
|---|---|
add |
Add a new face model for a user |
clear |
Remove all face models for a user |
config |
Open the config file in your default editor |
disable |
Disable or enable SecureEye |
list |
List all saved face models for a user |
remove |
Remove a specific model for a user |
snapshot |
Take a snapshot of your camera input |
test |
Test the camera and recognition methods |
version |
Print the current version number |
- PAM/authd split overview: docs/auth-architecture.md
- IPC protocol contract: docs/auth-protocol-v1.md
- PAM return-code mapping: docs/pam-behavior-matrix.md
- Python 3.12+
- pip / virtualenv
Use the Compose pam-smoke service to run an automated in-container PAM flow without touching host PAM.
smoke flow (build/install + PAM patch + sudo check):
docker compose --profile pam build pam-smoke
docker compose --profile pam run --rm pam-smokefull flow (smoke + secureEye add + secureEye test):
PAM_FLOW=full docker compose --profile pam run --rm pam-smokeInteractive flow (prompts for user/password/device and optional add/test):
PAM_FLOW=interactive docker compose --profile pam run --rm pam-smokeOverride camera device if needed:
SECUREEYE_VIDEO_DEVICE=/dev/video0 docker compose --profile pam run --rm pam-smokeThis project is licensed under the GNU General Public License v2.0.
Copyright © 2026 Vedran Hrabar
It includes code derived from the Howdy project, which is licensed under the MIT License.
See the NOTICE file and /licenses/MIT.txt for details.
This project is inspired by the Howdy project. Original authors and contributors are credited via the preserved Git history.
Contributions are welcome, check the Contributing guide for guidelines.
This software interacts with system authentication mechanisms. Use with caution and at your own risk.
