New
Apps 283Makers 283This week 283
Promote your app−30%
Intel T2 Touch ID for Linux screenshot 1
1views in
the last 30 days

Intel T2 Touch ID for Linux

Experimental Touch ID authentication for Intel Macs with Apple T2 chips on Linux

Built with Claude Code

by jmurth1234 · from GBUnited Kingdom · added Oct 29, 2026
no ratings0 comments
Open app Code

Intel T2 Touch ID for Linux

Experimental, fail-closed Touch ID authentication for Intel Macs with an Apple T2 chip. It talks to bridgeOS BiometricKit over BridgeXPC and exposes a minimal fprintd-compatible D-Bus service for PAM clients.

This is research software, not an upstream libfprint driver. The complete research workflow has been proven on one machine, while the boot and authentication path has been reproduced on a second model. macOS remains the recovery environment. Read Before you start before installing anything.

Contents

Status

"Exposed" means a user can invoke it on an installed system. "Hardware-tested" means it has been proven on the proven configuration below, and nowhere else.

Feature Exposed? Hardware-tested?
Fingerprint verification through fprintd and PAM Yes, installed and enabled Yes, including negative controls and password fallback
Keybag unlock (manual, PAM hook, or encrypted credential) Yes, installed Yes, including cold boot
Persistent BridgeOS network and boot ordering Yes, installed and enabled through service dependencies Yes, including reboot and recovery from the observed SEP timeout race
Diagnostics and identity inventory Yes, installed Yes
Enrollment from Linux (t2-touchid-enroll) Yes, separate root-only CLI Yes, one identity enrolled and re-proven after Linux reboot; a later macOS boot removed it
Label rename (t2-touchid-manage rename-fprint) Yes, separate root-only CLI Yes
Adaptive Catacomb persistence Yes, opt-in (T2_TOUCHID_AUTO_SYNC_ADAPTIVE=1) Partly; the journaled path is installed but has no dedicated live control
Single-identity deletion (t2-touchid-manage delete) Yes, behind explicit acknowledgements No; the first live hardware test has not been performed
Native fprintd-enroll / fprintd-delete No; default-off flags and an uninstalled drop-in No
Multi-user / mapped Linux accounts No; t2-touchid-user-map only writes forced-disabled records Read-only AKS gates only; no live multi-user operation
Endpoint-10 / ACM transport Opt-in research only (T2_TOUCHID_ENABLE_ACM_RESEARCH=1) Preflight and one transient-context lifecycle test only
Suspend/resume Yes, installer selects s2idle Yes; live match and all health controls passed after resume. deep remains broken

The fprintd service never exposes enrollment or deletion. The experimental mutation commands are separate root-only, journaled brokers.

Normal operation after setup

The default setup does not store either password and does not display a boot password prompt. Each Linux boot follows this sequence:

  1. t2-bridge-network.service detaches the configured T2 cdc_ncm interface from NetworkManager, brings up its link-local IPv6 path, and verifies the configured BridgeOS peer.
  2. The biometric BridgeXPC port is refreshed before t2-sep-transport.service negotiates with SEP. This ordering avoids the capability timeout observed when discovery and transport startup overlapped.
  3. t2-keybag-load.service loads the exported macOS keybag and records its boot-specific handles under /run/t2-touchid. The handles are still locked, and fingerprint PAM is deliberately skipped.
  4. The first sudo authentication asks for the Linux password normally. Only after that succeeds, a separate hidden prompt asks for the macOS login password. The passwords are never assumed to match.
  5. The macOS password is used once from locked process memory to unlock both SEP handles. A root-only readiness marker is published for that boot and fprintd is refreshed.
  6. Later sudo requests and the Omarchy lock screen can use Touch ID. Rebooting clears the runtime handles and readiness marker, so the first-sudo sequence repeats.

Cancelling or entering the wrong macOS password does not turn a valid sudo password into an authentication failure. Sudo succeeds, Touch ID remains unavailable, and the separate macOS prompt is offered after the next successful password-authenticated sudo. sudo t2-keybag-unlock remains the manual recovery path. t2-interactive-unlock.service is installed but disabled by default; it is only for systems with a working systemd password agent during boot.

Proven configuration

The complete verification, enrollment, rename, reconciliation, and mutation research described below was developed on an Intel MacBookPro16,2, bridgeOS build 23P1072, BridgeXPC 39, and Omarchy/Arch Linux.

Persistent BridgeOS networking, ordered port/transport startup, keybag loading, the separate Linux/macOS first-sudo prompts, sudo Touch ID, and Omarchy lock screen Touch ID were additionally verified on an Intel MacBookPro15,2 with bridgeOS build 23P350. This does not imply that enrollment, deletion, or every research command has been validated on that second model.

A positive right-index control and a negative unenrolled-finger control were both verified at the raw bridge, fprintd, and sudo/PAM layers. After the first Linux enrollment and a reboot, the macOS-enrolled right index and the Linux-enrolled right thumb were reconciled and assigned the canonical right-index-finger and right-thumb labels. Both independently return verify-match through an explicit fprintd-verify -f any "$USER" request, while an unenrolled finger returns verify-no-match; named requests also select only their corresponding identity.

That Linux-only thumb did not appear in macOS Touch ID settings. After macOS booted, the next Linux boot found one stable SEP identity but two records in the Linux-local Catacomb. fprintd correctly failed closed. This cross-OS boundary and its host-only recovery are documented below.

Prerequisites

Hardware and firmware

  • An Intel Mac with an Apple T2 chip. Full research coverage is limited to MacBookPro16,2 on bridgeOS 23P1072; the authentication path is also verified on MacBookPro15,2 on bridgeOS 23P350.
  • macOS still installed on the same machine, with at least one enrolled finger. macOS is both the source of the exported keybags and the recovery environment.

Kernel and T2 support

  • A Linux kernel with the T2 support stack (t2bce / apple-bce), providing the T2 USB-network (cdc_ncm) interface used to reach BridgeXPC. Development used the t2linux patched kernels.
  • Kernel build headers for the running kernel (/lib/modules/$(uname -r)/build), a C compiler, and make. The installer builds t2_sep_transport and two small helper binaries.
  • dkms is optional but strongly recommended; without it, the installer must be rerun by hand after every kernel upgrade.

Userspace

  • systemd, including systemd-creds and libsystemd, plus D-Bus and polkit.
  • fprintd 1.94.5 and its PAM module pam_fprintd.so. The documented client behaviour, including the PAM_SILENT workaround described under Installation, is specific to that version.
  • Python 3.12 or newer, with venv and pip, plus git. CI covers Python 3.12 and 3.14. The installer creates /opt/t2-touchid/.venv and installs dbus-next plus pymobiledevice3 from a pinned git revision, so it needs network access on first run.
  • sudo, and root access to the machine.

Optional desktop feedback

  • libnotify (notify-send) and libcanberra (canberra-gtk-play) for the audible and visual cues described under Desktop feedback. Everything works without them.

Before you start

Two things are far more likely to ruin your day than anything else in this document. Read these first:

  • Keep macOS available, and keep password authentication working. macOS is the only recovery environment for the fingerprint state in SEP. Never remove password authentication from PAM.
  • PAM changes can lock you out. Install the PAM templates only after both the positive and negative fingerprint controls pass, keep a root shell open while you test, and remember that sudo tools/rollback-pam.sh restores the unchanged project-managed stacks and removes the project hook from system-auth without discarding unrelated later edits. Backups are kept in /var/lib/t2-touchid/pam-backups.
  • Use s2idle, not deep. The installer selects the live-proven mode with a systemd sleep drop-in. Deep-S3 resume still breaks T2 communication until reboot on the proven machine; see Suspend/resume.
  • The kernel module is pinned after DMA registration. Never unload it; reboot before replacing it.
  • Deletion is irreversible in SEP and has never been tested on hardware.

The full recovery and removal commands are collected under Recovery and uninstall.

Concepts

These terms recur throughout the document and the commands.

Operation lock. A single machine-wide lock serialising every biometric operation. Inventory, enrollment, rename, deletion, and the adaptive Catacomb sync all take it, so two of them can never touch SEP at once.

Mutation journal. Every mutating broker writes durable intent before it dispatches a command to SEP, and records the reconciled outcome afterwards. An interrupted or ambiguous operation therefore leaves a journal that must be reconciled with a recover* subcommand. Never blindly replay a mutation: inspect status first and follow only the recovery path it identifies.

Post-reboot proof. A completed enrollment, rename, or deletion stays blocking — it is the only mutation allowed — until the resulting identity and Catacomb state have been proved again from a different Linux boot and a different Bridge connection. t2-touchid-post-reboot.service performs that read-only proof automatically before fprintd starts; the manual verify-post-reboot commands remain diagnostic fallbacks.

Compatibility alias. While any reconciled label is not a unique canonical fprint finger name, fprintd-list and fprintd-verify deliberately expose one configured logical finger slot (for example right-index-finger). That slot means "authenticate against any built-in identity owned by the configured Apple user". It is not an enrollment count. Use sep_identity_count from t2-touchid-inventory, or t2-touchid-enroll list, for the truthful hardware identity count. Once every label is uniquely canonical, the service automatically lists every finger, restricts a named verification to only that identity, and reports the exact canonical identity selected by a successful any match.

Management slot. t2-touchid-identities prints numbered slots for the reconciled identities. A slot number is valid only for that one reconciled invocation and is the selector used by the identity-management commands.

Acknowledgement flags. --acknowledge-* options are statements that you have already performed a control or accepted a consequence. They never run a control and never, by themselves, authorize anything else.

Generation pinning. Live operations pin one Bridge connection generation, one Linux boot, and one Linux account generation. If any of them changes mid-operation, the operation fails closed rather than continuing against different state.

Installation

  1. Keep macOS available and enroll exactly the finger you intend to use.

  2. Run the export helpers in tools/macos/ from macOS and transfer the outputs privately. Never commit or publish them.

  3. On Linux, identify the T2 USB-network interface and BridgeOS link-local IPv6 peer, then run sudo ./install.sh. Edit /etc/t2-touchid.conf when prompted, including the interface, peer, numeric macOS user ID, and corresponding special bag. Once configured, t2-bridge-network.service prepares this path automatically and keeps NetworkManager from racing it.

  4. Start t2-sep-transport.service for initial bring-up. The installer builds the module for the running kernel and enables ordered startup for later boots. PCI autoload remains observation-only; the service loader requests register_ool=1 and probe_capabilities=1 only after BridgeOS port discovery completes. Neither option is configured for early modalias autoload because early capability negotiation caused a persistent -110 timeout before BridgeOS was ready. The loader accepts an already operational module and can safely replace an early observation-only instance; it never unloads an instance that registered SEP DMA. After /dev/t2-aks exists, do not unload the module: reboot before rebuilding or replacing it. Re-run the installer after a kernel upgrade.

  5. Place the extracted keybag at /var/lib/t2-touchid/user.kb, owned by root and mode 0600. Provision the validated, root-private local Catacomb from the macOS export, then start t2-keybag-load.service:

    sudo t2-touchid-provision-catacomb /private/path/t2-touchid-catacomb.tar.gz
    

    The command rejects symlinks and non-private archives, independently validates all three components, atomically creates the local store, and is idempotent only when an existing store is byte-equal. It does not retain a second raw archive copy. This local baseline is required because fprintd fails closed rather than listing identities from unreconciled SEP state.

  6. Unlock the loaded normal handle and the special user bag with the macOS password.

    t2-keybag-load.service records the boot-specific values in /run/t2-touchid/keybag.env (mode 0700 directory, root-only):

    sudo cat /run/t2-touchid/keybag.env
    

    T2_KEYBAG_HANDLE is the handle SEP returned for the loaded keybag; it changes on every boot. T2_KEYBAG_SPECIAL is the special bag from T2_TOUCHID_SPECIAL_BAG in /etc/t2-touchid.conf (-501 for macOS user 501). Unlock both with the boot-scoped helper:

    sudo t2-keybag-unlock
    

    The helper validates the root-only runtime values, asks once through systemd-ask-password, and uses that in-memory secret for both unlocks. Its C helper disables dumps, locks the password buffer in RAM, and explicitly wipes it after both requests; the password is never placed in argv, the environment, or persistent storage. A root-only boot-scoped readiness marker is recorded only when both unlocks succeed. The helper also restarts fprintd when the daemon is already active, so no separate service restart is normally needed. Before that marker exists, the supplied sudo PAM stack skips fingerprint immediately and asks for the password instead of waiting for a biometric timeout.

    After PAM is installed, manual unlocking is no longer the normal boot workflow. See Unlocking keybags from password authentication for the default first-sudo path, or Unattended boot unlock for its higher-risk stored-credential alternative.

  7. Start fprintd.service and run the controls under Verification.

  8. Only after those controls pass, install the relevant files from pam/ into /etc/pam.d/ with sudo tools/install-pam.sh. Keep password authentication as a fallback and keep a root shell open while you test; sudo tools/rollback-pam.sh restores the originals.

    The sudo template displays a generic pre-capture sensor message through a fixed-text helper that writes to the controlling terminal or sudo's terminal-output channel. This is intentional: sudo sets PAM_SILENT, which hides conversation-based pam_echo messages, while fprintd 1.94.5's PAM client suppresses the ABI-valid VerifyFingerSelected("any") prompt when multiple identities are available. The message never names one finger because either enrolled identity is valid, and warns not to type until the hidden-input password prompt appears: terminal input can otherwise echo while pam_fprintd owns the sequential PAM transaction. The clamshell guard skips both the message and the fingerprint module when the laptop is closed.

The installer is safe to rerun and replaces only project-managed files. When DKMS is available it registers the transport for kernel upgrades; otherwise it warns that the installer must be rerun after an upgrade.

If the desktop user's systemd user manager is already running, installation reloads it through that user's /run/user/<uid>/bus. If no user bus exists, the reload is skipped quietly and the units are discovered at the next login; the root environment is never mistaken for a desktop user session. Uninstall uses the same bounded user-bus rule after removing the feedback units.

Unlocking keybags from password authentication

Linux and macOS passwords are treated as separate credentials. On the first sudo after boot, PAM validates the Linux password normally and then the helper asks separately for the macOS password used to unlock both T2 keybags. The macOS password is kept only in locked process memory and is not placed in argv, the environment, logs, or persistent storage. The helper reads the boot-specific handle recorded under /run by t2-keybag-load.service and always exits successfully, so a T2 failure cannot block password authentication.

The PAM installer validates the known Arch system-auth ordering, then places a sudo-only gate and unlock hook after pam_faillock.so authsucc. It refuses to patch unfamiliar or administrator-modified stacks and preserves rollback state:

auth [success=ignore default=1] pam_succeed_if.so quiet service = sudo
auth optional pam_exec.so quiet seteuid /usr/local/sbin/t2-pam-unlock

Omarchy uses SDDM autologin followed by separate unprivileged lock-screen PAM services, so the initial desktop password does not traverse system-auth and cannot execute the root-only keybag helper. Do not add this hook to omarchy-lock-password; use manual keybag unlock or the encrypted system credential described below. The supplied Omarchy password template preserves the stock password stack, while omarchy-lock-fingerprint provides the separate fingerprint path after the keybags are unlocked.

Only sudo reaches the helper. It unlocks the bags after the first successful Linux password authentication and separate macOS password prompt after boot. It cannot touch SEP after an incorrect Linux password. The helper also checks PAM_SERVICE=sudo and restricts itself to T2_TOUCHID_USER from /etc/t2-touchid.conf.

Unattended boot unlock

For unattended keybag availability after SDDM autologin, provision an encrypted systemd credential:

sudo tools/provision-credential.sh
sudo systemctl enable t2-credential-unlock.service

The provisioning prompt is local and hidden. The plaintext password is piped directly into

Description taken from the repository README.

Ratings

–
0 ratings
5 0
4 0
3 0
2 0
1 0

Rate this app

Sign in to rate

Comments 0

Sign in to comment

No comments yet.

Related apps

#dev-tools