Status: Accepted Date: 2026-02-22
Steps 1-5 delivered a working face authentication pipeline: camera capture, ONNX inference, D-Bus daemon, PAM module, and IR emitter integration. All components compile, 42 tests pass, and face auth works end-to-end via manual D-Bus calls.
However, installation requires manual steps: building from source, copying files to system paths, editing PAM configs, creating systemd units, and downloading ONNX models. Step 6 closes the gap between "works for developers" and "works for users."
Success criteria: sudo apt install ./visage_*.deb on clean Ubuntu 24.04 installs
everything. sudo echo test authenticates via face. sudo apt remove visage restores
password-only auth cleanly.
Decision: Use visaged crate's Cargo.toml for [package.metadata.deb] with assets
referencing the CLI binary and PAM .so from sibling crates.
Rationale: The daemon is the natural "main" package. cargo-deb's assets array handles
multi-binary packages without needing a separate packaging crate.
Decision: visaged runs as root, protected by ProtectSystem=strict, ProtectHome=true,
NoNewPrivileges=true, PrivateTmp=true, and DeviceAllow=char-video4linux rw.
Rationale: Matches fprintd precedent. Running as a dedicated user would require udev rules for camera access and group management — complexity deferred to v3.
Decision: Models are downloaded on-demand via sudo visage setup, not during package
installation (postinst).
Rationale: Offline installs should work. Users control when 182 MB downloads happen. postinst prints a reminder if models are missing.
Decision: Use raw libc::openlog/syslog with LOG_AUTHPRIV facility.
Rationale: Standard PAM pattern. No new crate dependencies (libc already in scope). Messages appear in auth log, not terminal output.
Decision: Keep tracing_subscriber::fmt() — systemd's StandardOutput=journal captures
stdout/stderr automatically.
Rationale: Already works. No additional configuration needed.
Decision: Default policy allows only Verify and Status. Enroll, RemoveModel, and
ListModels are implicitly restricted to root (no <allow> in default context).
Rationale: Sufficient for v0.3. In-method UID checks via GetConnectionCredentials are
deferred to v3. v0.3 performs in-method caller UID validation via D-Bus UNIX UID lookup
(GetConnectionUnixUser) and an NSS-backed username→UID resolution.
Decision: Send PAM_TEXT_INFO "Visage: face recognized" on successful match. Silent on
failure (password prompt speaks for itself).
Rationale: Matches fprintd pattern. Avoids confusing error messages when daemon is simply not configured.
Decision: PAM module sets a 3-second method_timeout via
zbus::blocking::connection::Builder::method_timeout() — applied at connection creation,
not on the proxy.
Rationale: Most critical safety feature. Without it, a hung daemon blocks sudo for 25+ seconds (D-Bus default timeout). 3 seconds is enough for normal verification (~80ms) but short enough that users perceive a quick fallback to password.
Implementation note: zbus 5 exposes method_timeout on the connection builder, not the
proxy builder. The timeout applies to all method calls on that connection, which is correct
since the PAM module makes exactly one call per authentication attempt.
- Runtime quirk override directory (
/usr/share/visage/quirks/) visage discover --probe(test activation pulse)VISAGE_EMITTER_WARM_UP_MSenvironment variable- In-method D-Bus UID validation via
GetConnectionCredentials - Dedicated service user with udev rules
/usr/bin/visaged — daemon binary
/usr/bin/visage — CLI tool
/usr/lib/security/pam_visage.so — PAM module
/usr/share/dbus-1/system.d/org.freedesktop.Visage1.conf — D-Bus policy
/usr/lib/systemd/system/visaged.service — systemd unit
/usr/share/pam-configs/visage — pam-auth-update profile
/usr/share/doc/visage/README.md — documentation
| Decision | Benefit | Cost |
|---|---|---|
| Daemon as root | Avoids udev/group complexity | Root process is a higher-value attack target |
Models via visage setup |
Offline-safe install; user controls 182MB download | Extra manual step after install |
| No dedicated service user | Simpler packaging | Weaker isolation than fprintd's dedicated uid |
| root-only D-Bus mutations | Easy to implement | visage list requires sudo; inconvenient for scripting |
| 3-second PAM timeout | Login never hangs | Face match has 3s total budget (not just inference time) |
| syslog via libc FFI | No extra crate deps | Raw FFI, no structured logging fields |
-
No apt-get install from a PPA. Users must build the
.debfrom source withcargo build --release --workspace && cargo deb -p visaged. There is no Launchpad PPA or published release asset yet. -
No integration test of the full install lifecycle. The
.debhas been constructed and inspected but has not been tested viasudo apt installon a clean Ubuntu 24.04 VM. The acceptance criteria remain unverified. -
Model checksums are for HuggingFace's buffalo_l. If InsightFace publishes updated model weights, the checksums in
setup.rswill reject them. Users must build from source to update. -
MemoryDenyWriteExecute=falseallows W+X pages. Required for ONNX Runtime's JIT execution provider. This is a meaningful systemd hardening regression; the alternative would be to use the ORT CPU provider exclusively and disable JIT, which may be slower but would allow restoring this restriction. -
Daemon restarts require face re-enrollment if database is purged.
apt purgeremoves/var/lib/visage/including all enrolled models. Users must re-enroll after purge. -
PAM conversation message requires terminal display. The "Visage: face recognized" feedback only appears if the PAM application (sudo, gdm, etc.) calls the conversation function. SSH sessions and headless contexts may not display it.
-
No Debian changelog or proper package versioning. The
.debuses workspace version 0.1.0 directly. Adebian/changelogfile with proper version history is absent — needed for PPA submission.
The following must be done before v0.1 can be publicly announced:
- End-to-end install test on Ubuntu 24.04 VM — verify the full
apt install → visage setup → enroll → sudoflow - GitHub release asset — build
.debin CI and attach to the v0.1 tag - PPA or release binary — users cannot currently install without building from source
- Launchpad PPA (or GitHub Actions
.debbuild) — prerequisite for Ubuntu distribution strategy systemd-tmpfiles.dentry — idiomatic alternative topostinst mkdirfor/var/lib/visage- Debian changelog — required for PPA; track version changes
preinstguard — check ifpam-auth-updateis available before running it- NixOS package — Augmentum OS overlay integration (Tier 1 in distribution strategy)
- Users with build tooling can install with a single
apt install ./visage_*.deb - PAM configuration is automatic via
pam-auth-update - Clean removal restores password-only auth
- Model download is explicit and offline-safe
- Daemon hardening limits blast radius of potential vulnerabilities