Touch ID for sudo on macOS Sonoma and later, in tmux and IDE terminals

Touch ID for sudo that survives macOS updates is one pam_tid.so line in /etc/pam.d/sudo_local. Add pam_reattach above it for tmux and IDE terminals.
Since macOS 14 Sonoma, /etc/pam.d/sudo includes a file called sudo_local, and that file survives system updates. Put auth sufficient pam_tid.so in it and you have Touch ID for sudo: sudo asks for your fingerprint instead of your password. Inside tmux, screen or some IDE terminals you also need pam_reattach, ordered above that line, because those processes are detached from the session that can draw the Touch ID prompt.
The rest of this post is the walkthrough: what the files contain, the manual edit, why tmux misses the prompt, where you will still type your password, and how to undo all of it. If you would rather run one command, the studio's MIT-licensed Touch ID for sudo makes the same edit, with a backup and an undo.
What macOS ships in /etc/pam.d
sudo authenticates through PAM, and its policy lives in /etc/pam.d/sudo. On the Mac this was written on, running macOS 27.0.1, that file reads:
# sudo: auth account password session
auth include sudo_local
auth sufficient pam_smartcard.so
auth required pam_opendirectory.so
account required pam_permit.so
password required pam_deny.so
session required pam_permit.soThe first auth line pulls in a second policy, sudo_local, before the smart-card and password checks run. The include form, per man 5 pam.conf, "causes entries from a different chain … to be included in the current one". Apple does not ship sudo_local itself. It ships /etc/pam.d/sudo_local.template, which on the same Mac reads:
# sudo_local: local config file which survives system update and is included for sudo
# uncomment following line to enable Touch ID for sudo
#auth sufficient pam_tid.soThat first comment is the whole point. Before Sonoma the usual advice was to add pam_tid.so to /etc/pam.d/sudo directly, and every macOS update replaced that file and quietly removed the line. Six Colors noted the change in August 2023, during the Sonoma betas.
You can check the survival claim on your own machine. Here, every Apple-managed file in /etc/pam.d carries the timestamp of the last system update, 24 September, while sudo_local still carries 15 August, the day it was written:
ls -l /etc/pam.d/pam_tid.so is the Touch ID module. It lives at /usr/lib/pam/pam_tid.so.2, and Apple ships no man page for it (man pam_tid returns "No manual entry"), so what it does has to be read off its behaviour and the PAM control flags around it.
The manual method
If your /etc/pam.d/sudo has the auth include sudo_local line, three steps do it. First, keep a root shell open in a second terminal window while you work. It costs nothing, and it is the way back if you break the file:
sudo -sThen, in your first window, write sudo_local with the template's line uncommented:
sudo tee /etc/pam.d/sudo_local > /dev/null <<'EOF'
# sudo_local: local config file which survives system update and is included for sudo
auth sufficient pam_tid.so
EOFSix Colors' version copies the template and uncomments the line in an editor, which ends in the same file:
cd /etc/pam.d
sudo cp sudo_local.template sudo_local
sudo pico sudo_localFinally, clear your cached credentials and try it. sudo -k "invalidates the user's cached credentials for the current session", per man sudo, so the next sudo has to authenticate:
sudo -k
sudo trueYou should see the system dialog asking for Touch ID, with a "Use Password" button underneath.
What sufficient means
man 5 pam.conf defines it: "If this module succeeds, the chain is broken and the result is success. If it fails, the rest of the chain still runs." A matching fingerprint ends authentication there. A cancelled prompt, a failed match, or Touch ID being unavailable lets the chain carry on to pam_opendirectory.so, which is the ordinary password check. The fingerprint is an alternative to the password, never a replacement for it.
Why tmux, screen and IDE terminals ask for the password
Set up as above, sudo in Terminal shows the prompt, and the same sudo inside tmux asks for your password. Nothing is broken. The pam_reattach README explains it: services tied to the GUI, "such as pasteboard and Touch ID", are "strictly tied to the login session of a user and as such unavailable for programs in the background session". A tmux server is exactly such a background program, built to outlive the terminal that started it, so a sudo running under it has no route to the session that draws the dialog. pam_tid cannot prompt, fails, and sufficient lets the chain fall through to the password.

pam_reattach is a PAM module that "will attempt to move the current program (e.g. sudo) to the current active login session, after which the remaining PAM modules will have access to the per-session services like Touch ID". It has to run before pam_tid. Its author suggests marking it optional "to prevent getting locked out in case of bugs".
The same applies to editors that run sudo in an embedded terminal. The Touch ID for sudo README puts it carefully: VS Code and JetBrains IDEs "run sudo in an embedded terminal that may not be attached to your GUI session", and pam_reattach fixes that case too.
iTerm2 has its own switch
iTerm2 can host your shells in a separate long-lived process so sessions survive a logout. Its source names the trade-off directly: the Advanced setting "Allow sessions to survive logging out and back in" is on by default, and its description says "This breaks the 'auth sufficient pam_tid.so' hack some people use to allow sudo to authenticate with Touch ID." Either turn it off in Settings, Advanced, or keep it and add pam_reattach, which addresses the same detachment.
Adding pam_reattach
Install it with Homebrew (formula page, MIT licensed) or MacPorts:
brew install pam-reattachsudo port install pam-reattachHomebrew on Apple silicon puts the module under /opt/homebrew, which PAM does not search, so the README says to give the full path. The sudo_local then reads:
# sudo_local: local config file which survives system update and is included for sudo
auth optional /opt/homebrew/lib/pam/pam_reattach.so
auth sufficient pam_tid.soOn an Intel Mac with Homebrew the module is at /usr/local/lib/pam/pam_reattach.so, and MacPorts installs it to /opt/local/lib/pam/pam_reattach.so. Check which one you have:
ls /opt/homebrew/lib/pam/ /usr/local/lib/pam/ /opt/local/lib/pam/ 2>/dev/nullTwo details matter. The order: pam_reattach above pam_tid, or the reattach happens after the prompt has already failed. And optional: if a Homebrew upgrade ever moves or breaks the module, sudo degrades to your password instead of refusing you. Open a new tmux pane and run sudo -k; sudo true to test.
From the studio: Touch ID for sudo gets both details right for you: if it finds
pam_reattach.so, it writes it asoptionalabovepam_tid.so, with the full path.
The ignore_ssh option
pam_reattach also accepts ignore_ssh. Its man page says it detects probable SSH sessions by "the presence of $SSH_CLIENT, $SSH_CONNECTION, or $SSH_TTY in the environment" and becomes a no-op, which "helps prevent erroneously prompting for a touch when SSH and a terminal multiplexer like tmux(1) is in use". If you attach to the same tmux session both at the desk and over SSH, add it:
auth optional /opt/homebrew/lib/pam/pam_reattach.so ignore_ssh
auth sufficient pam_tid.soWhere you will still type your password
pam_tid is a convenience with a fallback, so knowing where it steps aside saves confusion:
- Over SSH. The
pam_reattachREADME notes thatpam_tid"will try to avoid prompting for a touch when connected via SSH or another remote login method". You get the password prompt, as you should: the person at the keyboard may not be you. - With the lid closed, or on a Mac without a sensor. The sensor is unavailable,
pam_tidfails, andsufficientpasses you to the password. - With no fingerprint enrolled.
bioutil -cprints the count for the current user. On this Mac it reportsUser 501: 1 biometric template(s). Zero meanspam_tidhas nothing to match. - Inside tmux, screen, an IDE terminal or iTerm2's persistent sessions, until
pam_reattachor the iTerm2 setting above is in place.
Doing it with one command
Touch ID for sudo is the studio's MIT-licensed script for exactly this edit. It does nothing you could not do by hand with the steps above, and since it runs as root, here is everything it does, read from bin/touchid-sudo:
- Preflight. It refuses to run unless
/etc/pam.d/sudocontains theauth include sudo_localline, so it never edits/etc/pam.d/sudoitself. It checks thatpam_tid.soexists and warns ifbioutil -creports no enrolled fingerprint. - Writes only
/etc/pam.d/sudo_local, asroot:wheelwith mode 444. Ifpam_reattach.sois found under/opt/homebrew,/usr/localor/opt/local(checked in that order), it writes it asoptionalabovepam_tid.so, with the full path. Lines insudo_localthat it did not write are preserved. - Backs up any existing file to
/etc/pam.d/sudo_local.bakfirst. - Validates by running
sudo -n -k trueas you and searching the output for PAM errors. A healthy stack answers that a password is required; a broken one names the failure. - Rolls back on any sign of a PAM error, restoring the backup (or deleting the new file if there was none), and exits non-zero.
- Is idempotent. A second run reports
Already configuredand changes nothing.
brew install abd3lraouf-studios/tap/macos-touchid-sudo
sudo touchid-sudotouchid-sudo --status needs no root and prints the state, whether pam_reattach is active, and the file's contents. sudo touchid-sudo --disable removes the lines; if nothing else is left in sudo_local, it deletes the file, which is the factory state. It needs macOS 14 or later, for the same reason the manual method does.
Undoing it, and getting out of a broken file
By hand, deleting the file reverts sudo to password-only, because the include then has nothing to add:

sudo rm /etc/pam.d/sudo_localIf you wrote a broken sudo_local and closed every root shell, sudo may be unable to fix its own configuration. The way out is macOS Recovery: on Apple silicon, press and hold the power button until the startup options load, then choose Options; on an Intel Mac, hold Command-R at startup. Terminal is in the Utilities menu there. One detail trips people up: /etc is a symlink to /private/etc, and /private is listed in /usr/share/firmlinks, which means it lives on the data volume, not the read-only system volume. In Recovery, make sure the data volume is mounted in Disk Utility, then remove private/etc/pam.d/sudo_local from it.
The second terminal window from the manual method makes all of this unnecessary, which is why it comes first.
What it changes about security
Less than it seems in either direction. sudo still needs someone physically at the Mac with a matching finger, and it falls back to your password rather than around it. The real difference is that a sudo prompt no longer travels through your keyboard, which removes one place a keylogger could read it. Anyone who can already run code as you is not stopped by either mechanism, so if that is your threat model, the prompt is not where the fix lives.
To let a script make the edit, with a backup and an undo, use Touch ID for sudo. If you also build with a JDK from SDKMAN, this fix is the same kind of one-time macOS setup, for Xcode and java_home.
Authenticate sudo with Touch ID
Enables Touch ID authentication for sudo on macOS, keeps it working across system updates, and fixes the case the stock setup misses: tmux.
MITmacOS 14+