The immurok Linux client, verified on Arch / Fedora 38+ / Debian 12+ (incl. Ubuntu 22.04+) / KDE & GNOME. This document covers dependencies and install steps for the three distro families, plus common troubleshooting.
- Linux kernel 5.10+
- A Bluetooth adapter (BLE 4.2+)
systemduser services (satisfied by default on virtually all mainstream desktop distros)- PAM 1.4+, polkit 0.120+
- A desktop environment (GNOME / KDE / any DE running GTK4)
⚠️ This project does not support musl libc distros (Alpine / Void musl) — the PAM module depends on glibc.
sudo pacman -S --needed rust gcc pkgconf dbus pam bluez bluez-utils \
gtk4 libadwaita python-gobject polkit
# python-dbus-fast is in the AUR
yay -S python-dbus-fast
# Or skip the AUR and use pip:
pip install --user dbus-fastsudo dnf install rust cargo gcc pkgconf-pkg-config dbus-devel pam-devel \
bluez bluez-libs \
gtk4 libadwaita python3-gobject \
python3-dbus-fast polkitsudo apt install gcc pkg-config libdbus-1-dev libpam0g-dev bluez \
libgtk-4-1 libadwaita-1-0 python3-gi \
policykit-1
# Rust: the apt version is usually too old, prefer rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
# dbus-fast: not always in apt, use pip
pip install --user dbus-fast
# Or on Debian 12+ (PEP 668 enforced), use pipx:
sudo apt install pipx && pipx install dbus-fastUbuntu 24.04+ ships
python3-dbus-fastin apt, so you can skip pip.
git clone https://github.com/immurok/app-linux-rs
cd app-linux-rs
make check-deps # Preflight: lists every missing system component at once + the install command for your distro
make # Equivalent to `make build pam` (build runs check-deps automatically first)
check-depsfails fast on missing build deps (cargo / C compiler / PAM headers) and warns about missing runtime deps (dbus_fast/ PyGObject+Gtk4 / bluez).makeruns it automatically before building.
Artifacts:
target/release/immurok-daemon— main daemontarget/release/immurok-cli— interactive TUI + configuration / pairing CLItarget/release/imk— agent command wrapperpam/pam_immurok.so— PAM module
The first
cargo builddownloads dependencies and compiles ~200 crates: 10–30 minutes (depending on the machine).
make installWhat this step does:
| File | Path | Needs sudo |
|---|---|---|
immurok-daemon / imk / immurok-cli |
~/.local/bin/ |
No |
immurok-auth-dialog / immurok-pam-helper / ble-notify-helper.py |
~/.local/bin/ |
No |
pam_immurok.so |
/usr/lib64/security/ (Fedora) / /lib/x86_64-linux-gnu/security/ (Debian) / /usr/lib/security/ (Arch) |
Yes |
| PAM service config | /etc/pam.d/sudo / /etc/pam.d/polkit-1 / /etc/pam.d/gdm-password |
Yes |
| polkit policy | /usr/share/polkit-1/actions/com.immurok.pam-helper.policy |
Yes |
| systemd polkit overrides | /etc/systemd/system/polkit.service.d/immurok.conf |
Yes |
| systemd user service | ~/.config/systemd/user/immurok-daemon.service |
No |
No
/etc/pam.d/gdm-password(KDE / SDDM setups) is fine — the Makefile skips that entry. For login-screen fingerprint unlock on SDDM:sudo immurok-pam-helper add sddm.
After make install completes, the daemon should already be running:
systemctl --user status immurok-daemonEverything below is also available from a single interactive terminal UI — the recommended way to manage immurok:
immurok-cli tuiNumber keys switch pages, ? shows the full key reference, q quits.
| Page | Key | What you can do |
|---|---|---|
| Dashboard | 1 |
pair/unpair (p/u), enroll (e, auto-picks the lowest empty slot), delete (d), verify (v), unlock toggles (s/o/k/L), recent-event feed |
| Keys | 2 |
SSH / OTP / API keystore: add (a), delete (d), fetch OTP code (o), show SSH pubkey (c), show API value (s) |
| PAM | 3 |
install / remove / repair the PAM hooks (i/r/R, pkexec prompts) |
| Logs | 4 |
live-tail daemon logs with scrollback |
| Firmware | 5 or U |
check for updates and install with a progress bar (see 4.5) |
The one-shot CLI subcommands below do the same things — use them for scripting.
# Power on / hold the device button to enter pairing mode (LED slowly blinks blue)
immurok-cli pair # or: press `p` in the TUI
# Confirm by pressing the device button within 30sIn the TUI just press e — it enrolls into the lowest empty slot. Or via CLI:
immurok-cli fp enroll 0 # slot 0
# Touch the sensor 6 times, following the position hints
# (if a fingerprint is already enrolled, verify with it first to authorize)
immurok-cli fp list # view enrolled slots5 slots are supported (0–4). To delete: immurok-cli fp delete 0.
Toggle directly on the TUI Dashboard (s/o/k/L), or via CLI:
immurok-cli set sudo on
immurok-cli set polkit on
immurok-cli set screen on # screen unlock
immurok-cli set lock on # long-press device button to lock the screen (optional)
immurok-cli settings # view all settingsCheck and install official firmware from immurok.com:
immurok-cli fw check # compare device firmware with the latest release
immurok-cli fw update # download, verify and install (asks for confirmation)
immurok-cli fw update -y # non-interactive
immurok-cli fw status # last check result + interrupted-update resume stateNotes:
- Devices below 1.6.0 (old signing era) upgrade in two hops via a bridge package — handled automatically, including resume after an interruption.
- Requires ≥30% battery. Downloads are cached under
~/.immurok/fwupdate/. - The TUI (tab 5, or press
Uon the Dashboard) offers the same flow with a progress bar.immurok-cli ota <file.imfw>remains available for manually built packages.
immurok-cli daemon restart # systemctl --user restart + wait for the socketBefore the device is paired, only fw/ota (firmware update),
daemon restart, pair, status and logs are available — everything
else exits with a hint to pair first. The TUI opens normally but gates
device-facing actions the same way.
sudo -k && sudo whoami
# Should pop a GTK dialog or go straight to fingerprint (no re-prompt within the 10s cooldown)If it works, after touching the sensor the terminal immediately prints root (the identity sudo elevated to), with no password prompt.
Test imk run --agent:
imk run --agent -- sudo systemctl restart NetworkManager
# Pops a single GTK dialog showing the wrapped command; approve with a fingerprint touchThe auth line format in the PAM config wasn't recognized. The current helper supports both ^auth and ^@include styles. If your distro uses something else (rare), manually edit /etc/pam.d/sudo and add this before all auth lines:
auth sufficient pam_immurok.so
The PAM module was installed to the wrong directory. Check your distro's standard location:
find /usr/lib* /lib* -name 'pam_*.so' 2>/dev/null | head -5
# Use the first directory as the target and copy it there
sudo cp pam/pam_immurok.so /usr/lib64/security/ # use the path found above- The daemon isn't running:
systemctl --user start immurok-daemon - The device isn't connected:
immurok-cli statusshould showStatus: Connected - PAM doesn't have immurok:
sudo grep pam_immurok /etc/pam.d/sudo; if empty, runimmurok-cli pam install sudo(a wrapper aroundsudo immurok-pam-helper add sudo)
# Check whether the polkit override took effect
systemctl show polkit | grep BindPaths
# Should show BindPaths=/run/user
# polkitd usually fails because ProtectHome=yes blocks access to /run/user
# The Makefile writes the override, but it needs systemctl daemon-reload + restart
sudo systemctl daemon-reload && sudo systemctl restart polkitbluetoothctl scan le # should list "immurok IK-1"
grep BLE ~/.immurok/logs.txt # daemon writes its own log file, not the journalBlueZ cached stale GATT handles from an old firmware layout. Forget and re-pair once:
bluetoothctl remove <MAC> # then: immurok-cli pairDo not work around this with a global
[GATT] Cache = noin/etc/bluetooth/main.conf— it breaks reconnection for all BLE peripherals (mice, headphones). Keep the defaultCache = always.
python3 -c 'import dbus_fast' # should not error
# If you get ModuleNotFoundError:
pip install --user dbus-fast
# If installed via pipx, add the script path to the daemon user's PATHNote that ble-notify-helper.py uses #!/usr/bin/python3, i.e. the system python (not a venv), so a pip install --user lands in ~/.local/lib/python3.X/site-packages where the system python can find it.
Intentional — it never steals keyboard focus and closes itself once the fingerprint passes. Alt+Tab to it if you need the Cancel button.
cd app-linux-rs
make uninstallThis stops the service and removes the PAM config, polkit policy, and override, but keeps ~/.immurok/ (pairing keys, settings, logs).
To wipe everything:
rm -rf ~/.immurokWorks out of the box. Screen unlock listens to the org.gnome.ScreenSaver D-Bus signal.
- Install
libadwaita(KDE doesn't pull it in by default), otherwise the dialog won't launch - Screen lock listens to the freedesktop
org.freedesktop.ScreenSaverinterface, which KDE is compatible with - Login-screen fingerprint unlock requires installing the PAM hook for
sddm. Currentlyimmurok-cli pam installonly whitelistssudo/gdm-password/polkit-1; to add sddm, manually edit/etc/pam.d/sddmand insert before the first auth line:auth sufficient pam_immurok.so
GTK4 dialogs launch fine. Screen lock depends on your lockscreen (swaylock / hyprlock); these generally don't emit D-Bus signals, so fingerprint screen-unlock may not work — just fall back to the password stack.
Apache License 2.0 — including the PAM module in pam/. Device firmware is licensed separately under BSL 1.1.