So, I am pretty lazy when it comes to typing out long commands and constantly typing in my password on my Mac. I worked with my coding coach (ChatGPT – and by coach I mean I just have it spit out the code). I had it write this, if you are using iTerm2, and you should, it will give you a TouchID prompt IF you have a device with a TouchID sensor connected, or are using your MacBook keyboard itself with TouchID, otherwise it will just give a password prompt, like an animal. It backs up all the files it touches, because I don’t trust ChatGPT that much. If it borks you, I’m sorry, so make a backup of your machine first and I’ll buy you an adult beverage when next we see each other.
To create the we are going to: nano install_touchid_sudo.sh and then add:
#!/bin/zsh
# Install Touch ID for sudo in iTerm2 only when a Touch ID Magic Keyboard is connected.
# Backs up every file it touches with .bak.<timestamp> and records a manifest for clean backout.
set -euo pipefail
TS="$(date +%Y%m%d-%H%M%S)"
INSTALL_DIR="$HOME/.local/share/touchid-sudo-iterm2"
MANIFEST="$INSTALL_DIR/manifest.$TS"
PAM_SUDO="/etc/pam.d/sudo"
BIN_DIR="$HOME/bin"
SUDO_WRAPPER="$BIN_DIR/sudo"
ZSHRC="$HOME/.zshrc"
mkdir -p "$INSTALL_DIR"
: > "$MANIFEST"
note() { printf '%s\n' "$*"; }
record() { printf '%s\t%s\n' "$1" "$2" >> "$MANIFEST"; } # type<TAB>path
# 1) Backup and ensure pam_tid.so is present in /etc/pam.d/sudo
note "Backing up and enabling Touch ID in $PAM_SUDO..."
sudo cp "$PAM_SUDO" "${PAM_SUDO}.bak.${TS}"
record "backup" "${PAM_SUDO}.bak.${TS}"
if ! grep -q 'pam_tid\.so' "$PAM_SUDO"; then
tmp="$(mktemp)"
# Insert pam_tid.so as the first non-comment line
awk 'BEGIN{ins=0}
/^#/ && ins==0{print; next}
ins==0{print "auth sufficient pam_tid.so"; ins=1}
{print}
END{if(ins==0) print "auth sufficient pam_tid.so"}' \
"$PAM_SUDO" > "$tmp"
sudo cp "$tmp" "$PAM_SUDO"
rm -f "$tmp"
record "modified" "$PAM_SUDO"
else
note "pam_tid.so already present; leaving $PAM_SUDO content unchanged (backup still created)."
fi
# 2) Create ~/bin and install sudo wrapper (backup any existing one)
note "Installing conditional sudo wrapper at $SUDO_WRAPPER..."
mkdir -p "$BIN_DIR"
if [[ -f "$SUDO_WRAPPER" ]]; then
cp "$SUDO_WRAPPER" "${SUDO_WRAPPER}.bak.${TS}"
record "backup" "${SUDO_WRAPPER}.bak.${TS}"
fi
cat > "$SUDO_WRAPPER" <<'ZWRAP'
#!/bin/zsh
# iTerm2-scoped sudo wrapper that prefers Touch ID only when a Touch ID Magic Keyboard is connected.
set -euo pipefail
is_iterm2() {
[[ "${TERM_PROGRAM:-}" == "iTerm.app" ]]
}
has_touchid_keyboard() {
# Bluetooth: look for Magic Keyboard with Touch ID entries that are connected
if system_profiler SPBluetoothDataType 2>/dev/null | \
awk 'BEGIN{IGNORECASE=1}
/Magic Keyboard with Touch ID( and Numeric Keypad)?/ {seen=1}
/Connected: Yes/ && seen {connected=1}
/^$/{ if(connected){print "YES"; exit} seen=connected=0 }' | grep -q YES; then
return 0
fi
# USB: wired usage
if system_profiler SPUSBDataType 2>/dev/null | \
grep -Ei 'Magic Keyboard with Touch ID( and Numeric Keypad)?' >/dev/null; then
return 0
fi
return 1
}
if is_iterm2 && has_touchid_keyboard; then
exec /usr/bin/sudo "$@"
else
exec /usr/bin/sudo "$@"
fi
ZWRAP
chmod +x "$SUDO_WRAPPER"
record "created" "$SUDO_WRAPPER"
# 3) Ensure ~/bin is in PATH via ~/.zshrc (backup before edit)
ensure_path_line='export PATH="$HOME/bin:$PATH"'
if ! print -r -- "$PATH" | tr ':' '\n' | grep -qx "$HOME/bin"; then
note "Ensuring $HOME/bin precedes PATH in $ZSHRC..."
if [[ -f "$ZSHRC" ]]; then
cp "$ZSHRC" "${ZSHRC}.bak.${TS}"
record "backup" "${ZSHRC}.bak.${TS}"
else
# Touch to create, then back it up empty for symmetry
: > "$ZSHRC"
cp "$ZSHRC" "${ZSHRC}.bak.${TS}"
record "backup" "${ZSHRC}.bak.${TS}"
fi
# Only append if not already present
if ! grep -Fxq "$ensure_path_line" "$ZSHRC"; then
printf '\n%s\n' "$ensure_path_line" >> "$ZSHRC"
record "modified" "$ZSHRC"
fi
else
note "~/bin already on PATH in current shell; no edit to $ZSHRC."
fi
# 4) Save a copy of the wrapper and metadata for reference
cp "$SUDO_WRAPPER" "$INSTALL_DIR/sudo.wrapper.$TS"
record "created" "$INSTALL_DIR/sudo.wrapper.$TS"
note "Install complete.
Manifest: $MANIFEST
Open a new iTerm2 session or 'source ~/.zshrc' to pick up PATH changes.
Behavior:
- In iTerm2 with a Touch ID Magic Keyboard connected: sudo will allow Touch ID.
- Otherwise: sudo falls back to password."Now hit control-x to exit and y to save
The rollback!
Create the file:
nano uninstall_touchid_sudo.sh
and add this:
#!/bin/zsh
# Back out the most recent install by restoring backups from the newest manifest.
# You can pass a specific manifest path as $1 to target that install.
set -euo pipefail
INSTALL_DIR="$HOME/.local/share/touchid-sudo-iterm2"
MANIFEST="${1:-}"
if [[ -z "$MANIFEST" ]]; then
MANIFEST="$(ls -1t "$INSTALL_DIR"/manifest.* 2>/dev/null | head -n1 || true)"
fi
if [[ -z "$MANIFEST" || ! -f "$MANIFEST" ]]; then
printf 'No manifest found. Nothing to do.\n' >&2
exit 1
fi
printf 'Using manifest: %s\n' "$MANIFEST"
restore_file() {
local backup="$1"
# Original path is the backup path without the trailing ".bak.<timestamp>"
local orig="${backup%\.bak.*}"
if [[ -f "$backup" ]]; then
# If restoring /etc/pam.d/*, use sudo
if [[ "$orig" == /etc/pam.d/* ]]; then
sudo cp "$backup" "$orig"
printf 'Restored (sudo): %s -> %s\n' "$backup" "$orig"
else
cp "$backup" "$orig"
printf 'Restored: %s -> %s\n' "$backup" "$orig"
fi
else
printf 'Backup missing, skipping: %s\n' "$backup" >&2
fi
}
# Read manifest lines: "<type>\t<path>"
# We restore backups and then optionally remove created files saved under INSTALL_DIR.
while IFS=$'\t' read -r typ path; do
case "$typ" in
backup)
restore_file "$path"
;;
created)
# Only delete created artifacts under our install dir; leave ~/bin/sudo in place
# unless there is also a backup we restored above.
if [[ "$path" == "$INSTALL_DIR/"* ]]; then
rm -f "$path" && printf 'Removed created artifact: %s\n' "$path"
fi
;;
modified)
# Nothing to do here; restoring from backups handles this.
:
;;
*)
:
;;
esac
done < "$MANIFEST"
# If we restored a backup of ~/bin/sudo, that copy is now back in place.
# If we did NOT restore one but want to remove our wrapper, uncomment the next block:
# if [[ -f "$HOME/bin/sudo" ]]; then
# rm -f "$HOME/bin/sudo"
# printf 'Removed wrapper at %s\n' "$HOME/bin/sudo"
# fi
printf 'Backout complete.\n'Now hit control-x to exit and y to save
Now to execute it!
First we make them executable:
chmod +x install_touchid_sudo.sh uninstall_touchid_sudo.sh
./install_touchid_sudo.shNow to load it into our zsh open a new iTerm2 tab or run:
source ~/.zshrcThen we will test:
sudo -v && echo "sudo cache primed; next sudo should prompt Touch ID if eligible." && sleep 2 && sudo trueIf you want to kill it with fire:
./uninstall_touchid_sudo.sh
Lemme know how it goes if you trust me trusting ChatGPT enough to try it!
On my Github:
https://github.com/bionicrocky





st and foremost, the Shon Harris All-In-One Guide is a must. This is the Golden Book. I have known some folks that have used only this resource and passed.

