Time to add some variety to the blog, so I’m starting a series of post which I’ll mix in between other more mainstream topics. I want to spend some time testing some hidden or maybe less known gems that will make your life as a macAdmin a bit easier.

And the honour for the first awesome little tool I’d like to discuss goes to: SAP – Privileges. I knew about the existence of this tool but never took the time to check it out…

So, let’s not waste any time and dive right into it!

Note: Little disclaimer from the SAP Github project page.

This project is 'as-is' with no support, no changes being made. You are welcome to make changes to improve it but we are not available for questions or support of any kind.

That said, there is no need to, as it just works as expected. Within the limitations of the design of course. Nevertheless, Rich Trouton was so friendly to point me to his own Privileges scripts and recipes to enhance the deployment! This made it even easier to use! Thanks Rich!

The basic idea behind the app is to ensure that your end users, who need to be Admin for specific tasks, don’t use their Admin account while performing day to day tasks which don’t require Admin privileges at all.

While there might be other solutions available, such as scripting the elevated privileges via Self Service, the SAP privileges app makes it all possible without too much effort, and even when the end User is offline.

While it’s really a beautiful little tool, it does however have some limitations by design. But don’t worry nothing that can’t be fixed or tweaked. First of all, when you run the default app for the first time, it asks for Admin rights to install the “Helper Tools”:

I wanted to add this app to a workflow where I’d make all my end users ‘Standard Accounts’ (demote everyone, change the pre-stage enrolment to Standard Accounts, etc). Bye bye admin rights as per default deployment, and then only give this app to those users who really need it.

But the prompt for the admin rights to install the “Helper Tools” was initially a little blocker, so MacAdmins Slack to the rescue! And before I lost any time trying to script it myself… Rich reminded me of his GitHub collection, which include some options to automate the process!

I grabbed one of the recipes and used autopkg to get a nice pkg to deploy ‘Privileges’ with the automated installation of the ‘Helper Tools’. However, I also found the scripts alongside the recipes, so just to test this options as well, I repackaged ‘Privileges’ myself with composer and added the Post-Install script from Rich’s Github (Script by Marc Thielemann).

Built the pkg, upload it to Jamf Pro and create a Self Service policy… don’t forget to add the Dock item !

Don’t forget the Dock Item! And just ignore the custom trigger… just used it for testing.
Self Service policy with the custom pkg, scoped to only those who need to become Admin!

Let’s run it! Once installed, hit the icon in the Dock and click on “Request Privileges”…

… no prompt for Admin credentials to install the “Helper Tool” ! And we immediately get the notification that the Privileges have been granted. So let’s confirm it in Users & Groups…

Admin, with just a press on a button… Sweet!

Harry Potter couldn’t do it any better with all his so called magic! Also check out the Dock item! How cool is that! What do you think? For what it’s worth, I love it!

Next, have a look at the Dock item on it’s own, and do a ctrl/right click on it. Apart from locking the screen or going back to the Login Window (without logging out the user) the end user has the possibility to set a timer on his/her admin rights. Instead of clicking the app to request elevated privileges, the ‘Toggle Privileges’ function via the Dock menu can be used to limit the use of Admin rights in time. The timeout can be set in the preferences of the app.

While this really gives us a tool to educate end users not to use admin rights for daily tasks, it will only work if you can assume a level of trust or confidence in the fact that the end user will use the ‘Toggle Privileges’ function, and not abuse the tool to stay Admin all the time.

The fact that the app does not have a built in functionality to force the user to remove the Admin rights automatically may seem as a limitation, but as they mention on the project page you are free to put your dev skills to work and enhance it were needed for your deployment.

I’m however not a developer, so let’s check out some other options. There are probably plenty of different (better) solutions (apart from changing the app itself), but as a proof of concept I just went with a LaunchDaemon and a script.

I could have deployed the script as part of the custom package, together with the LaunchDaemon, but this would mean that I have to repackage it each time I want to make changes to the script. To avoid that I only added the LaunchDaemon to the custom pkg…

… and added a command to the end of the post-install script to immediately load the LaunchDaemon:

launchctl load -w /Library/LaunchDaemons/com.ttg.demote.privileges.plist

Then I made a LaunchDaemon which I set on an interval of 10 minutes for testing (change it to what you want – displayed in seconds). As I am not deploying the script locally, I’m calling a Jamf Policy via a custom trigger ‘checkAdmin’:

Add the LaunchDaemon to the custom package in Composer, build it as pkg, upload it to Jamf Pro and make a Self Service policy scoped to those users who are entitled elevate themselves to Admin.

Next is the script to check the usage of the elevated Admin privileges:



# Travelling Tech Guy - 6th of March 2019

# Proof of concept - use at own risk!

# This script is an attempt to add a little enforcement to return to standard privileges when using the SAP privileges app

# The SAP Privileges project page:
# https://github.com/SAP/macOS-enterprise-privileges

# set time limit (set to 5 minutes for testing)


timeStamp=$(date +%s)

# check if file exists

		if [ -f $logFile ]; then
		  echo "File ${logFile} exists."
		  echo "File ${logFile} does NOT exists"
		  touch $logFile
		  echo $timeStamp > $logFile

# grab the logged in user
loggedInUser=$(/usr/bin/python -c 'from SystemConfiguration import SCDynamicStoreCopyConsoleUser; import sys; username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]; sys.stdout.write(username + "\n");')

# check if the user is admin

		if [[ $("/usr/sbin/dseditgroup" -o checkmember -m $loggedInUser admin / 2>&1) =~ "yes" ]]; then
  			echo "User is Admin... keeping an eye on him/her!"
  			echo "User is not admin... bye bye"
  			rm $logFile
# process Admin time

		if [[ $userType = "Admin" ]]; then	

			oldTimeStamp=$(head -1 ${logFile})
			rm $logFile
			touch $logFile
			echo $timeStamp > $logFile

			adminTime=$(($timeStamp - $oldTimeStamp))
			echo "Admin time in seconds: " $adminTime
			adminTimeMinutes=$(($adminTime / 60))
			echo "Admin time in minutes: " $adminTimeMinutes


echo "Time Limit is: " $timeLimit
# if user is admin for more than the time limit, ask if to confirm need for superpowers

if [[ "$adminTimeMinutes" -ge $timeLimit ]]; then

confirmAdmin=`/usr/bin/osascript <<EOT
tell application "Finder"
	set myReply to button returned of (display dialog "Do you still need Admin Super Power?" buttons {"Yes", "No"} default button 2)
end tell


# take action

if [[ "$confirmAdmin" == "No" ]]; then
echo "Demoting the user!"
/usr/local/bin/jamf displayMessage -message "OK, Admin rights revoked"

# Demote the user
sudo -u $loggedInUser /Applications/Privileges.app/Contents/Resources/PrivilegesCLI --remove

if [[ "$confirmAdmin" == "Yes" ]]; then
/usr/local/bin/jamf displayMessage -message "OK, but use them wisely you must - Yoda"

Upload the script to Jamf Pro, add it to a policy with a custom trigger (same as the one you put in the LaunchDaemon obviously) and frequency ongoing.

Important: as we are not deploying the script locally, don’t forget to make the policy available offline!

Make the policy available offline to ensure the user is also forced to limit the use of Admin privileges when Jamf Pro is not reachable!

Now, whenever a user installs our custom privileges package, the LaunchDaemon will be deployed as well. Following the interval you set in the Daemon, it will call the script which will check if the user is Admin, write a timestamp in a hidden file and check again on the next run of the Daemon. If the difference between the 2 timestamps is exceeding the time limit you put in the script (see line 14 of the script), it will prompt the user to confirm he/she still needs Admin rights. If the user is not using elevated privileges when the Daemon triggers the script, it will reset the timestamp and silently exit.

If the end users replies Admin privileges are not needed, the script will demote the user back to Standard:

For this I’m just calling the built in CLI feature in the Privileges app:
sudo -u $loggedInUser /Applications/Privileges.app/Contents/Resources/PrivilegesCLI –remove

Also, check out the Dock item which reverted back to green – Standard!

But if the user claims to need the Admin privileges, it will just remind him/her not to abuse it:

Just know that the interval at which the LaunchDaemon is triggered, and recording the timestamps, will not correspond with the real time the user was elevated to Admin. This might trigger false positives, as it might ask the user for confirmation while he/she just recently elevated to Admin again. Hence the script might think the user has continually been in Admin mode since the last check. You could potentially change the strategy here and build some lookup into the script to find timestamps in the logs from when the Admin group was added to the user account. For me, this did however feel a little bit too much work for the intended goal here: educate our end users.

You could of course also play the bad IT Admin guy, and just kill the Admin privileges after a certain time… but yeah…

As said, this is just a proof of concept and the idea is to catch people who are staying in Admin mode all day… Depending the Daemon interval and the time limit you set in the script, you can limit it to only a few spot checks a day

Or as as said, re-engineer the app and built this kind of functionality directly inside the Privileges application.

That’s it, let me know what you thing. Happy to hear how you added similar functionality or if you have a custom version of the app for this!