Note
Gaze includes local liveness anti-spoofing and support for infrared (IR) cameras to secure authentication against spoofing attacks. For high-security environments, it is recommended to keep standard system authentication active as a fallback.
Facial authentication for Linux with on-device face recognition, PAM integration, and tools for login, lock screen, sudo, and desktop management.
curl -fsSL https://gaze.gundulabs.com/install.sh | shThe installer installs the Gaze daemon, CLI, and GUI. It supports openSUSE Tumbleweed on x86_64 through its native zypper package manager and a Tumbleweed-specific RPM repository. It installs the GNOME Shell extension only when it detects a GNOME desktop session; on KDE Plasma it installs gaze-kde instead, and on other non-GNOME desktops it skips GNOME-specific packages so it does not pull in GNOME Shell. If you installed the GNOME extension manually or automatic enablement was not possible, reboot (so GNOME Shell scans the new extension) and then run from GNOME:
gnome-extensions enable gaze@gundulabs.com
gsettings set org.gnome.shell.extensions.gaze enable-face-authentication trueRunning
gnome-extensions enablebefore rebooting will returnExtension "gaze@gundulabs.com" does not exist. Shell only rescans extension directories at session start, and it drops extension IDs it has not scanned, so an enable applied before the reboot can vanish at the next logout. Reboot first, then run the commands.gaze doctorreports this case and prints the steps.
Manual install (Debian/Ubuntu, Fedora/openSUSE RPM systems, Arch/Manjaro/CachyOS)
Debian / Ubuntu
Each apt suite carries only the builds for that release: noble (Ubuntu 24.04), questing (Ubuntu 25.10), resolute (Ubuntu 26.04), trixie (Debian 13), forky (Debian 14, testing).
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://packages.gundulabs.com/keys/gundulabs-repo.gpg \
| sudo tee /usr/share/keyrings/gundulabs-archive-keyring.gpg >/dev/null
suite="$(. /etc/os-release && echo "${VERSION_CODENAME:-$UBUNTU_CODENAME}")"
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/gundulabs-archive-keyring.gpg] https://packages.gundulabs.com/deb $suite main" \
| sudo tee /etc/apt/sources.list.d/gundulabs.list >/dev/null
sudo apt update
sudo apt install gaze gaze-guiFedora and compatible DNF systems
sudo rpm --import https://packages.gundulabs.com/keys/gundulabs-repo.asc
sudo tee /etc/yum.repos.d/gundulabs.repo >/dev/null <<'EOF'
[gundulabs]
name=Gundu Labs
baseurl=https://packages.gundulabs.com/rpm/fedora/$releasever/$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.gundulabs.com/keys/gundulabs-repo.asc
EOF
sudo dnf makecache
sudo dnf install gaze gaze-guiFedora OSTree (Silverblue / Bazzite / Kinoite)
sudo tee /etc/yum.repos.d/gundulabs.repo >/dev/null <<'EOF'
[gundulabs]
name=Gundu Labs
baseurl=https://packages.gundulabs.com/rpm/fedora/$releasever/$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.gundulabs.com/keys/gundulabs-repo.asc
EOF
sudo rpm-ostree install gaze gaze-guiFedora via Copr (alternative to the repository above; do not enable both)
sudo dnf install dnf-plugins-core
sudo dnf copr enable @gundulabs/gaze
sudo dnf install gaze gaze-guiopenSUSE Tumbleweed (x86_64)
sudo rpm --import https://packages.gundulabs.com/keys/gundulabs-repo.asc
sudo tee /etc/zypp/repos.d/gundulabs.repo >/dev/null <<'EOF'
[gundulabs]
name=Gundu Labs
baseurl=https://packages.gundulabs.com/rpm/opensuse/tumbleweed/$basearch
enabled=1
autorefresh=1
type=rpm-md
gpgcheck=1
gpgkey=https://packages.gundulabs.com/keys/gundulabs-repo.asc
EOF
sudo zypper refresh
sudo zypper install gaze gaze-guiArch / Manjaro / CachyOS
# Requires an AUR helper such as yay or paru. yay shown here.
yay -S --needed gaze-bin gaze-gui-binFlatpak (GUI only; also install one of the system packages above for the gazed daemon)
flatpak install --from https://packages.gundulabs.com/flatpak/com.gundulabs.Gaze.flatpakrefOn openSUSE Tumbleweed, the RPM post-install script enables the shared PAM stack; reapply it manually with sudo pam-config --add --gaze && sudo pam-config --update if needed. For GNOME lock screen face unlock after manual package installation, also install gaze-gnome-extension (gaze-gnome-extension-bin on Arch), reboot, then from your GNOME session run gnome-extensions enable gaze@gundulabs.com and gsettings set org.gnome.shell.extensions.gaze enable-face-authentication true. On KDE Plasma, install gaze-kde (gaze-kde-bin on Arch) for hands-free lock screen face unlock and a Face Unlock entry in System Settings; see the KDE guide.
Nix / NixOS (flake)
The repo is a Nix flake with packages (gaze, gaze-gui, gaze-gnome-extension) and a NixOS module that configures the daemon, D-Bus/polkit, and PAM declaratively:
# flake.nix inputs
inputs.gaze.url = "github:GunduLabs/gaze";
# NixOS configuration
imports = [ inputs.gaze.nixosModules.default ];
services.gaze = {
enable = true;
gui.enable = true;
};See the Nix & NixOS guide for module options, GNOME lock screen setup, hyprlock, and home-manager usage.
After installation (any method), reboot once to ensure all system-level changes are fully applied.
sudo reboot# Enroll your face
gaze add-face default
# Test authentication
gaze auth
# Or use the GUI
gaze-guiGaze runs a daemon (gazed) that communicates over DBus. When authentication is requested (by PAM at login, the GNOME extension on the lock screen, or the CLI), the daemon captures a frame from your webcam, detects and aligns the face, computes an embedding using an ONNX model, and compares it against stored enrollments.
All processing happens locally. Face embeddings are stored on disk, not transmitted anywhere.
Camera → Face Detection (SCRFD) → Alignment → Embedding (ArcFace) → Match → Liveness (MiniFASNet-V2)
| Component | Description |
|---|---|
gazed |
System daemon exposing com.gundulabs.Gaze on DBus |
gaze |
CLI for enrollment and authentication (crate: gaze-cli) |
gaze-gui |
GTK4/Adwaita graphical application |
pam-gaze |
PAM module for login/lock screen integration |
gaze-gnome-extension |
GNOME Shell extension for lock screen auth |
gaze-hyprlock |
PAM service for hyprlock face unlock on Hyprland |
# /etc/gaze/config.toml
[inference]
execution_provider = "cpu" # cpu | openvino (requires an OpenVINO build)
device = "cpu" # cpu, or gpu | npu on an OpenVINO build
[security]
level = "medium" # low | medium | high | maximum | custom
[cameras]
rgb = "primary"
dark_luma_threshold = 20
[auth]
abort_if_ssh = true
abort_if_lid_closed = true
[enrollment]
max_templates = 2
min_face_size_ratio = 0.25
[liveness]
enabled = true
threshold = 0.8OpenVINO selects its device at run time. An OpenVINO-enabled installation
should use execution_provider = "openvino" and device = "npu" to select the
Intel NPU. The same binary can select the Intel GPU by changing device to
"gpu". The released packages are CPU-only; OpenVINO requires building from
source with just build-rust-openvino.
See the configuration guide for all options.
gaze add-face <name> Enroll a new face
gaze refine-face <name> Add samples to an existing enrollment
gaze auth Authenticate
gaze auth --verbose Authenticate with detailed metrics
gaze auth --silent Authenticate silently (exit code only)
gaze list-faces List enrolled faces
gaze rename-face <old> <new> Rename a face
gaze remove-face <name> Remove a face
gaze clear-user Remove all face data for current user
gaze config Interactive configuration editor
gaze config --show Print current config and exit
gaze doctor Check config, daemon, cameras, enrollments, PAM, and TPM
gaze doctor --benchmark Also measure detector/recognizer/liveness inference speed
gaze uninstall Completely remove Gaze (packages, PAM, config, models, data)
gaze uninstall -y Skip confirmation prompt
Enrollment first captures a straight-on reference, then asks for small up, down, left, and right movements relative to that reference.
Dependencies: Rust 1.85+, just 1.51+, nfpm
# Ubuntu/Debian
sudo apt install build-essential pkg-config clang libclang-dev \
libopencv-dev libv4l-dev libpam0g-dev libtss2-dev libssl-dev \
libgtk-4-dev libadwaita-1-dev \
libcairo2-dev libglib2.0-dev libgdk-pixbuf-2.0-dev libpango1.0-dev libgraphene-1.0-dev \
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev \
gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-pipewire \
gettext-base
# Build
just build-rust
# Build with OpenVINO support (requires an OpenVINO-enabled system ONNX Runtime)
just build-rust-openvino
# Package
just package <deb | rpm | archlinux>See the development guide for more.
Gaze is free software licensed under the GNU General Public License, version 3 or later (GPL-3.0-or-later).
Gaze - Facial authentication for Linux
Copyright (C) 2026 Gundu Labs <maintainers@gundulabs.com>
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program. If not, see <https://www.gnu.org/licenses/>.
Contributions are accepted under the same license.