Use Jamf Self Service to Enable TouchID for sudo

As you may be aware, it is possible to use a fingerprint on any TouchID enabled Mac (or Magic Keyboard with TouchID) to authenticate sudo at the command line.

This possibility has been discussed many times by many MacAdmins, and Mac enthusiasts over the years. The earliest mention I could find is from 2017. Cabel Sasser tweeted:

Pro MacBook Pro Tip: have a Touch Bar with Touch ID? If you edit /etc/pam.d/sudo and add the following line to the top…

auth sufficient pam_tid.so

…you can now use your fingerprint to sudo!— Cabel

(@cabel) November 16, 2017

sudo on the command-line is great. It enforces security and separation by running under your own user, and it logs actions taken using sudo. But it can be a pain to type longer passwords and passphrases repeatedly. By using TouchID to authenticate, we can keep all the security, while reducing long password entries.

All we have to do is edit the file /etc/pam.d/sudo and add the following line at the top:

auth sufficient pam_tid.so

Save and you’re done. However, there are a few caveats. For one, the sudo file gets overwritten with default values each time macOS is updated. That is where our Self Service policy comes in. The script below can be placed in Self Service, allowing users to re-enable the feature with the click of a button after each update.

The script will check if TouchID is already enabled for sudo, and only enable it if needed. The original sudo file gets backed up to /etc/pam.d/sudo.bak.

Another caveat is that this feature does not work in iTerm2 unless a specific setting is changed. The script handles that too. If iTerm is installed, it will check if the required setting is enabled to allow TouchID. If the setting needs to be changed, a Jamf Helper message will let the user know what to do. Note this is a one time only change, once the setting is correct, users will not see the following message.

Additional step required for iTerm

If you do not use Jamf, the Jamf Helper section could easily be replaced with something more appropriate for your environment, or removed altogether.

Without further ado, here is our script:

#!/bin/bash
# Get the current user and their UID
currentUser=$( scutil <<< "show State:/Users/ConsoleUser" | awk '/Name :/ && ! /loginwindow/ { print $3 }' )
currentUserID=$( id -u "$currentUser" )
# This is the line we need to add to enable TID
enableTouchID="auth sufficient pam_tid.so"
# Original sudo file location
sudoFile="/etc/pam.d/sudo"
# If TouchID is already enabled exit. Otherwise modify the sudo file
if fgrep -q "$enableTouchID" "$sudoFile"; then
echo "TouchID for sudo is already enabled. Doing nothing…"
else
echo "TouchID not enabled for sudo. Enabling now…"
# Write new file with line to enable touch ID
awk 'NR==2 {print "auth sufficient pam_tid.so"} 1' $sudoFile > $sudoFile.new
# Make a backup of the current sudo file
cp $sudoFile $sudoFile.bak
# Replace the current file with the new file
mv $sudoFile.new $sudoFile
fi
# If iTerm is installed, tell the user what they need to change to enable this setting
if [ -d '/Applications/iTerm.app' ]; then
# Read iTerm preference key
iTermPref=$( launchctl asuser "$currentUserID" sudo -u "$currentUser" defaults read com.googlecode.iterm2 BootstrapDaemon 2>/dev/null )
# If preference needs to be set, show Jamf Helper window with instructions
if [[ "$iTermPref" == "0" ]]; then
echo "iTerm preference is already set properly. Doing nothing…"
else
echo "Notifying user which iTerm setting needs to be changed…"
# Set notification description
description="We have detected that you have iTerm installed. There is an additional step needed to enable this functionality.
To enable TouchID for iTerm: Navigate to Preferences » Advanced » Session, then ensure \"Allow sessions to survive logging out and back in\" is set to \"No\""
# Display notification
"/Library/Application Support/JAMF/bin/jamfHelper.app/Contents/MacOS/jamfHelper" \
-windowType utility \
-title "Tech Services Notification" \
-heading "Additional Step Required for iTerm" \
-description "$description" \
-alignDescription left \
-icon "/Applications/iTerm.app/Contents/Resources/AppIcon.icns" \
-button1 "OK" \
-defaultButton 1
fi
fi

I would advise adding the above script to Jamf Pro, then setting up a Self Service policy like so:

  • General
  • Name: Enable TouchID for sudo
  • Trigger: Self Service
  • Frequency: Ongoing
  • Scripts
  • Select script uploaded previously.
  • Scope
  • Targets: Computers with TouchID enabled

Unfortunately, scoping to only computers with TouchID enabled requires an extension attribute (and a smart group). I have included the extension attribute I use below:

#!/bin/bash
# Check to see if TouchID is enabled and returns the number of enrolled fingerprints per user
touchIDstatus=$( sudo bioutil -s -c | sed 's/Operation performed successfully.//g' )
if [ "$touchIDstatus" != "There are no fingerprints in the system." ]; then
echo "<result>$touchIDstatus</result>"
else
echo "<result>Not configured</result>"
fi

I would also add something to the description in Self Service indicating that the user needs to return and run the policy again after each macOS update, and check the box to ensure that users view the description.

Should you ever need to undo this action, it is as simple as restoring the original sudo file from the one we backed up. The following command can be run with a Jamf policy to restore the original settings:

mv /etc/pam.d/sudo.bak /etc/pam.d/sudo

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s