Your face unlocks Linux: login, sudo, the lock screen, and app prompts
(Bitwarden, pkexec). Works in the dark, resists photo & screen spoofs, never
stored as an image.
Works with the camera you have: an IR (Windows Hello) camera unlocks the full secure tier, a regular webcam gives convenient screen unlock, and a fingerprint reader slots in as a companion factor.
Built to match or beat Windows Hello, on a fully open, commercially clean stack.
Install · How it works · Security · Limits · FAQ · Docs
From a one-line install to a wired face login: guided face enrollment in the TUI, greeter and lock-screen wiring, and opt-in face-sudo.
| 🌑 Works in the dark | Active infrared recognition (Windows-Hello cameras); no ambient light needed. |
| 🔒 Unlocks everything | Login greeter, lock screen, sudo (opt-in via login enable --with-sudo), and app prompts like Bitwarden's biometric unlock via polkit (opt-in via login enable --with-polkit; approve with a deliberate nod, details), with the password always as fallback (no lockout, ever). |
| 🙋 On-demand, by consent | The camera fires only when you ask: leave the password field empty and press Enter. Typing a password never starts a scan. A grace window after the gesture (~15 s at login/lock, ~5 s for sudo) keeps retrying while you settle into frame, but never retries a failed match. Wiring is tailored per login manager (GDM · SDDM · Plasma Login · LightDM · greetd · COSMIC · ly). |
| 🗝️ Opens your keyring | On IR hardware a face match TPM-unseals your login password so the wallet unlocks at login, like Hello. |
| 👁️ Real liveness | Algorithmic IR anti-spoof gate + opt-in passive blink detection (no prompt, no action). |
| 🧬 No face images stored | Stores 512-D embeddings, never images; on TPM hardware they're AES-256-GCM encrypted under a TPM-sealed key (without a TPM: root-only files, and the TUI says so). |
| 🎚️ Adapts to your hardware | IR camera → Secure tier · RGB-only → Convenience (screen-unlock) tier · fingerprint reader → face OR fingerprint (coexist, either unlocks). All auto-detected. |
| 🩺 Self-healing | A live TUI (irlume tui) detects & one-key-fixes daemon/PAM/reader/config faults, and a systemd watcher re-applies the PAM wiring if a distro update (authselect / pam-auth-update) strips it. |
| 📦 Self-contained | One package per distro, all models bundled. git clone and go. |
How irlume stacks up against Windows Hello and the Linux face-unlock projects you've probably met (Howdy, visage):
| Windows Hello | Howdy | visage |
irlume | |
|---|---|---|---|---|
| Liveness / anti-spoof | IR only (bypassable: CVE-2021-34466) | ❌ none; its own README warns a "well-printed photo of you could be enough" | ✅ algorithmic IR gate on by default (blocks screens and matte prints); opt-in passive blink adds a glossy-print/replay defense.† Self-tested vs ISO/IEC 30107-3 | |
| Camera-injection defense | device-trust (newer HW) | ❌ none | ❌ none | ✅ device pinning + cross-spectrum RGB↔IR |
| Template protection | TPM-bound enclave | AES-256-GCM, key in a 0600 disk file (not TPM-sealed) | ✅ AES-256-GCM, TPM-sealed key (survives disk theft) | |
| Opens your keyring/wallet | ✅ | ❌ (keyring stays locked) | ❌ | ✅ TPM-unseals it at login |
| Stores your face as… | template | encoding | embedding | embedding only, never an image |
| Model licensing | proprietary | MIT code · dlib weights | ✅ permissive, bundleable | |
| Runs on | Windows | Linux | Linux | Linux: Fedora · Arch · Debian/Ubuntu · NixOS |
† The default IR gate blocks screens and matte prints (0% APCER in self-test), but a determined life-size glossy print passed it at 98.6% APCER; the opt-in passive-blink challenge closes that at the cost of a slower login. Enrollment on IR hardware offers to enable it. See Honest limitations.
v0.7.0. Works end-to-end on real hardware across all three families, including face-approved app prompts (Bitwarden). Not yet certified (no iBeta lab pass); see Honest limitations.
You need: x86-64 Linux with systemd & PAM; the distros below are packaged and tested. A TPM 2.0 is strongly recommended (encrypted templates, keyring unlock) but not required. Any camera works; it just sets your tier: IR camera → secure login · RGB webcam → screen unlock · fingerprint → companion.
curl -fsSL https://raw.githubusercontent.com/archledger/irlume/main/scripts/install.sh | shDetects your distro and installs from the signed Copr repo (Fedora), the
PPA (Ubuntu LTS), the AUR (Arch), or a checksum-verified release
.deb (Debian 12+, Ubuntu derivatives). It installs a package only and wires nothing into your
login, and it stops without changing anything if irlume is already installed
(use irlume update to upgrade). Prefer to read it before running it?
curl -fsSL https://raw.githubusercontent.com/archledger/irlume/main/scripts/install.sh -o install.sh
less install.sh && sh install.shOr install manually with your package manager:
| Fedora | Ubuntu | Arch | Debian 12+ |
|---|---|---|---|
# Copr
sudo dnf copr enable \
archledger/irlume
sudo dnf install irlume |
# PPA
sudo add-apt-repository \
ppa:archledger/irlume
sudo apt install irlume |
# AUR
yay -S irlume |
# .deb from Releases
sudo apt install \
./irlume_*.deb |
Fedora and current-LTS Ubuntu update with the system (dnf upgrade /
apt upgrade). The PPA
carries the current Ubuntu LTS only; on an older LTS or a derivative (Mint,
Pop!_OS, Zorin, elementary) use the universal Debian .deb from
Releases; it needs glibc
2.35 or newer (Debian 12+, Ubuntu 22.04+, and their derivatives all qualify)
and refuses to install on anything older.
irlume update
handles every case: it detects how irlume was installed and updates the same way.
On NixOS, add nixosModules.irlume from this flake instead; it runs the daemon
and wires the PAM stacks declaratively. See docs/NIXOS.md.
Then, once:
irlume tui # enroll your face + configure, guided
sudo irlume login enable --apply # opt-in: wire the greeter + lock screenlogin enable (and the TUI's [w]) wires the greeter and lock screen for
your login manager. From then on face is on-demand: at the greeter or lock
screen, leave the password empty and press Enter. The camera fires only then.
Face-sudo is a separate opt-in; add it with
sudo irlume login enable --with-sudo --apply, since granting root by face is a
trade-off worth choosing deliberately (the password always still works).
Full step-by-step (both the guided TUI and the individual CLI commands, with
keyring unlock, recovery, and fingerprint): docs/SETUP.md.
Every command and flag on one page: docs/COMMANDS.md.
Something not working, or want to audit every decision?
docs/DEBUGGING.md: irlume doctor runs the platform
checks in one pass (TPM, Secure Boot, camera, models), irlume logs puts every
face-auth journal line in one view, and sudo irlume logs debug on traces
every pipeline stage (scores, liveness cues, thresholds, timings; numbers
only, never frames or embeddings).
Usually no IR-emitter step is needed. Many Hello cameras drive their own
illuminator whenever the infrared stream is open, and for the modules irlume has
been validated against it applies the control those cameras document. Nothing
runs on its own: if your infrared frames stay dark, sudo irlume ir-setup will
look for a control, and it tells you first that it writes to your camera.
It only ever addresses the extension unit your camera's USB descriptor identifies as Microsoft's camera-control unit, only selectors that unit advertises, and only with values built from the camera's own answers. Before 0.7.1 it did something very different, and it destroyed a reporter's camera; see #159.
Safe to try. Installing the package wires nothing into your login.
Auth only changes when you run login enable, and without --apply it's a
dry run that prints the full per-file wiring plan without writing anything. Your password always keeps
working, and one command undoes everything: sudo irlume login disable --apply.
irlume update checks for a new release the way your distro expects. Prefer to
build from source? See packaging/ and scripts/install-host.sh.
Privilege separation first. The thin pam_irlume.so module and irlume
CLI are untrusted clients of the privileged irlumed daemon, the only thing
that ever touches the camera, IR emitter, models, templates, or TPM. They speak
over a Unix socket authenticated with SO_PEERCRED.
flowchart LR
subgraph U["Untrusted clients"]
direction TB
P["pam_irlume.so<br/>greeter · sudo · lock"]
C["irlume CLI<br/>+ live TUI"]
end
subgraph D["irlumed · privileged daemon (root)"]
direction TB
CAM["Camera + IR emitter"]
ML["YuNet + rescue → AuraFace<br/>IR liveness gate · matcher"]
T["TPM seal · encrypted templates"]
end
P -->|"Unix socket · SO_PEERCRED"| D
C -->|"Unix socket · SO_PEERCRED"| D
A login, end to end. Every branch that isn't a clean, live match falls back to the password; there is no lockout.
flowchart TD
A["Greeter / lock screen:<br/>leave password empty, press Enter"] --> B["Camera fires, on demand<br/>captures RGB + IR in parallel"]
B --> DET["Detect face<br/>YuNet → BlazeFace rescue"]
DET --> L{"IR liveness gate<br/>relief ratio · reflectance · glint"}
L -->|spoof or no face| PW["Type your password<br/>no lockout, ever"]
L -->|live| M{"Match embedding<br/>at or above threshold?"}
M -->|no| PW
M -->|yes| G["Grant<br/>+ TPM-unseal your keyring"]
Model bill-of-materials. Every weight is permissive or first-party, all GPLv3-compatible, so the whole thing is bundleable:
| Stage | Model | License |
|---|---|---|
| Detection | YuNet | MIT |
| Detection rescue | BlazeFace short-range (fires only on a YuNet miss) | Apache-2.0 |
| Recognition | AuraFace (512-D ArcFace) | Apache-2.0 |
| IR liveness gate | self-built, algorithmic (no weights) | n/a |
| Passive blink liveness + rescue alignment | MediaPipe FaceMesh (478-pt) → eye-aspect-ratio (opt-in) | Apache-2.0 |
| IR domain match | raw AuraFace + per-enrollment on-device calibration (fitted from your own scans; no third-party data, ADR-0004) | n/a |
More depth: Architecture · Threat model · Standards mapping · Cross-distro notes.
irlume stores only 512-D embeddings (a one-way projection; you can't rebuild a photo from it), AES-256-GCM encrypted, under a key the TPM seals to your boot state. We audited this live:
- 🧑💻 A normal user account →
catting the files gives Permission denied (root-only, 0600). - 💽 Disk-theft test: copied the encrypted templates and the sealed key to a
second machine with its own TPM →
tpm: integrity check failed. The stolen data is undecryptable off the original box.
The delta vs Hello: Hello isolates templates in a VBS/TPM enclave the kernel
never sees; irlume's daemon is a root process holding decrypted embeddings in RAM
during a match, so root on the live machine is the trust boundary (as with
most Linux secrets). Full write-up: docs/SECURITY_AT_REST.md.
Every claim here maps to something you can run on your own machine:
docs/VERIFY.md.
The current gaps:
- Passive blink liveness is a deterrent, not a guarantee. It closes casual and typical print/screen attacks, but a determined life-size glossy print still slips through occasionally, and it doesn't cover glasses-wearers (IR lens reflections hide the eyelid). Every miss falls safely to the password. Beating a determined glossy print is the passive-cue ceiling; it needs a trained PAD model or true depth hardware. See ADR-0002 and the PAD self-test results.
- RGB-only laptops get the Convenience tier: face unlocks the screen only,
never
sudo, login, or the keyring (those keep the password). By design. - Bright IR behind you defeats the relief check. The anti-spoof gate infers shape from how the IR emitter's light falls across the face; when the scene's own infrared floods it, no such signal is left, and a genuine face is rejected to the password. It is a brightness ratio, not a range measurement: the sensor does not measure distance, and a glossy print with a hot centre passes it. Measured in a 430-sample field session (2026-07-16, cloudy-bright sky): reliable below ambient ~120 on the 0-255 IR scale (indoors, inside vehicles, shade, a closed car with 20% tint passed 99/99), marginal to ~170, and 0/129 genuine samples passed above ~170 (open sky or sun behind the user; the emitter's contribution fell to noise and 46-82% of the IR frame was saturated). irlume can't tell sky from a bright lamp (both are just infrared), so the rejection names the condition and the fix: turn away from the light, or type the password.
- Not lab-certified. We self-test against ISO/IEC 30107-3; there's no paid iBeta pass. Demographic FMR tuning (FAIRNESS.md) is ongoing.
Is this "Windows Hello for Linux"?
Yes, that's the bar. irlume brings Windows Hello-style face login to Linux:
face-unlock the login screen, lock screen, sudo, and your keyring/wallet,
using the same IR (Windows Hello) camera your laptop already has. And it aims
past Hello where Hello is weak: real anti-spoof liveness, encrypted
TPM-sealed templates, and a fully open stack.
How is irlume different from Howdy?
Howdy is the best-known face unlock for Linux, and it's honest about being a convenience: its README says a well-printed photo of you could be enough to fool it. irlume is built as an authenticator: an IR liveness gate (self-tested against ISO/IEC 30107-3), AES-256-GCM-encrypted templates under a TPM-sealed key, camera pinning, and TPM keyring unlock at login, with tiers, so RGB-only face match is deliberately limited to screen unlock. See the comparison.
Do I need an IR camera?
No. An IR (Windows Hello) camera gets the full Secure tier: greeter
login, sudo, keyring unlock, works in the dark. A regular RGB webcam
gets the Convenience tier: face unlock for the lock screen only. A
fingerprint reader works as a companion factor on either. All
auto-detected.
Is this AI-generated?
AI-assisted, human-directed, and disclosed throughout the git history: the
large majority of commits carry Co-Authored-By trailers naming the AI
assistant (Anthropic's Claude, also visible under this repo's contributors). A human maintainer sets
direction, reviews the changes, and validates every release with clean-slate
installs on real hardware (Fedora, Arch, Ubuntu; IR camera, TPM, fingerprint)
before anything ships. Judge the project by its verifiable artifacts: the
threat model, measured error rates, spoof-test results, and the code itself
are all in the repo, reproducible regardless of what tools wrote them.
Can I verify these claims myself?
That's the point of docs/VERIFY.md. Each claim maps to a
command you can run: see your own camera's anti-spoof score, confirm the stored
template is encrypted ciphertext (not an image), run the presentation-attack
self-test against your own spoofs, reproduce the real-face FAR on LFW, and build
and run the test suite. Some checks take two minutes, some take real effort, but
every one is runnable.
Glasses, beards, outdoors: when should I re-enroll?
One enrollment usually lasts. A profile is one identity, and a face can only
own one profile, so different looks of the same person are extra scans on
that profile, not a second profile. Wear glasses sometimes? Add a scan with
Improve Recognition (TUI Profiles → [a], or irlume profiles add-scan) while
wearing them. Major appearance change (shaved beard, new heavy frames)? Same
thing, add a scan rather than starting over. Recognition flaky in bright
sunlight? Strong ambient IR can wash out the emitter's illumination; add a
scan captured in that environment.
Profiles are per-user and deletable any time.
Does it work on Ubuntu / Fedora / Arch, GNOME / KDE, Wayland?
It does. irlume authenticates through PAM, and tailors the greeter wiring to the
login manager it detects. Validated live on real machines: Fedora KDE
end-to-end on IR hardware (Plasma Login Manager greeter, lock screen, sudo,
TPM keyring unlock; Wayland), Ubuntu GNOME on an RGB+fingerprint laptop
(lock-screen face unlock, fingerprint, correct password-only refusals for
login/sudo), and the full login-manager matrix: GDM (on-demand on GNOME ≥ 46;
face-first before that), SDDM, LightDM (gtk and slick greeters, X11),
greetd (tuigreet), and COSMIC's greeter. Arch is validated for packaging,
install, and the full CLI/daemon stack (that testbed has no camera). Reports
from other hardware are very welcome.
I changed my login password and now my keyring/wallet won't open
This is general Linux behaviour, not specific to irlume. Changing your login
password (passwd or a settings dialog) updates /etc/shadow, but it does not
re-encrypt your KWallet / GNOME keyring. The wallet keeps the key derived from
your old password until you change the wallet's password separately, so it no
longer matches the new login password.
irlume seals whatever password you armed and hands it to the wallet, so it passes along the old one and cannot fix this by itself. To bring all three back in sync after a password change:
- Login password is already updated by
passwd. - Wallet password: change it to the new one in KWallet Manager → "Change Password" (KDE), or Seahorse → the "Login" keyring → "Change Password" (GNOME).
- irlume's sealed copy: run
irlume keyring armto re-seal the new password.
Rule of thumb: whenever the wallet password changes, re-run irlume keyring arm
so irlume's seal keeps matching it. Your typed password opens everything in the
meantime, so nothing locks you out.
How fast is a face login, and why is the blink challenge slower?
A normal face login takes about 2.5 seconds on an integrated IR camera (measured on an ASUS Zenbook, CPU inference). Most of that is opening the camera and letting auto-exposure settle, not the neural networks. The RGB and IR captures run in parallel, which cuts the capture stage by about a third; docs/DEBUGGING.md shows how to time every stage on your own hardware.
The opt-in blink challenge (irlume profiles challenge on) is a deterrent
against a glossy print or vinyl that mimics the infrared relief pattern: it
watches for a
natural blink, which a static image cannot do. Detecting a blink is inherently
temporal, so it captures a roughly 5-second infrared sequence, and the login
takes about 10 seconds (measured across six runs, glasses on and off). That
is the trade: the challenge closes a spoof gap the default single-frame gate
cannot, at about four times the latency.
It is off by default. Turn it on with irlume profiles challenge on if you
want the extra deterrent, or leave it off for the ~2.5-second login; the
default IR-structure gate already rejects photos, screens, and video replays.
| I want to… | Go to |
|---|---|
| Install and set up, guided or by hand | docs/SETUP.md |
| Look up every command and flag | docs/COMMANDS.md |
| Write software that drives irlume | docs/INTEGRATION.md |
| Look up the versioned machine API, field by field | docs/MACHINE-API.md |
| Understand the architecture | docs/ARCHITECTURE.md |
| Read the threat model and standards mapping | docs/THREAT_MODEL.md · docs/STANDARDS.md |
| Verify the claims on my own machine | docs/VERIFY.md |
| Debug a login or trace every stage | docs/DEBUGGING.md |
| Contribute and set up a dev shell | CONTRIBUTING.md · docs/DEVELOPMENT.md |
| Run it on NixOS | docs/NIXOS.md |
| See what changed in each release | CHANGELOG.md |
v0.7.0: working and validated on real hardware. Fedora runs the full IR Secure tier end to end, including face-approved app prompts (Bitwarden biometric unlock via polkit, verified live); Ubuntu / Pop!_OS runs the RGB Convenience tier plus a fingerprint; Arch is validated for packaging and the CLI/daemon on a camera-less testbed. Packaged for all three families (Copr · AUR · PPA). Interfaces may still shift before 1.0.
- ✅ Presentation attacks tested and denied on a NexiGo N930W: printed photo (including in direct sunlight), laptop screen, phone screen at full brightness, and a video replay with real head motion. All rejected at the infrared stage; a physical 3D mask is not yet tested (contributions welcome).
- ✅ TPM sealing picks the strongest tier the machine supports (signed-PCR → pcrlock → literal PCR-7) and round-trip-verifies it before trusting it, so a policy that cannot unseal on this boot never holds the secret.
- 🧪 Self-tested against ISO/IEC 30107-3; not lab-certified (no iBeta pass). Demographic FMR tuning (FAIRNESS.md) is ongoing.
- 🧰 Contributor-ready: a reproducible Nix dev shell and developer guide; CI runs fmt / clippy / build / test on every push and PR.
The per-release detail (0.1.x through 0.7.0) lives in CHANGELOG.md.
irlume relies on models and code from other projects. The bundled models:
- YuNet (OpenCV Zoo, MIT) detects faces in both the RGB and IR streams.
- AuraFace by fal (Apache-2.0) is the 512-D ArcFace recognizer; irlume ships only its
glintr100.onnx. - MediaPipe FaceLandmarker mesh (Google, Apache-2.0) supplies the 478 dense landmarks behind the opt-in blink liveness and refines rescue detections into alignment points.
- MediaPipe BlazeFace short-range (Google, Apache-2.0) is the detection-rescue stage: it runs only when YuNet finds no face, such as sun-saturated frames.
The TPM and camera code builds on:
- rust-tss-esapi (the Parsec project, Apache-2.0) wraps the TPM 2.0 ESAPI. irlume builds from a small patch branch that adds the
PolicyAuthorizeNVwrapper (upstream PR #486) plus the PR #530 session-leak fix, pinned to an exact commit. - systemd (LGPL-2.1-or-later): the Tier-2 pcrlock seal and unseal in
crates/irlume-core/src/tpm.rsfollows the scheme in systemd'ssrc/shared/tpm2-util.candsrc/pcrlock/pcrlock.c. - linux-enable-ir-emitter first showed that the 850nm emitter on integrated Hello cameras can be driven from userspace over UVC Extension Units. irlume no longer uses its search technique: irlume's own version of it destroyed a camera (#159), and upstream gates that search behind an interactive warning about firmware corruption that irlume did not have.
- ort binds Microsoft's ONNX Runtime, which irlume loads at runtime for every model above.
Prior art that shaped the design: Windows Hello for the infrared, dual-sensor credential model, and Howdy and visage as the existing Linux face-unlock projects (see the comparison). irlume is the from-scratch successor to the author's earlier linhello.
Windows and Windows Hello are trademarks of Microsoft Corporation. irlume is an independent project, not affiliated with, sponsored by, or endorsed by Microsoft; the marks are used only to describe compatibility and prior art.
GPL-3.0-or-later, fully open, copyleft: modifications stay free, nobody can lock this down. Contributions welcome under the DCO; no CLA, no commercial relicensing. Security reports: see SECURITY.md.
Questions, setup help, hardware reports → GitHub Discussions. Reports from laptops with IR cameras (working or not) are the most valuable contribution right now. Bugs → Issues.
Note
AI disclosure: assisted, human-directed. irlume is built by a human
maintainer working with an AI assistant (Anthropic's Claude), disclosed
throughout the git history via Co-Authored-By trailers; see the log or the
contributors page.
Direction, review, and releases are human-driven; every release is validated
with clean-slate installs on real hardware, and the security claims rest on
reproducible evaluations in this repo, not on who typed the code.