Problem overview
This script addresses the difficulty of maintaining accurate control over administrative privileges on macOS systems by cross-referencing a list of detected admins against an authorized list. It ensures that you can quickly spot and remediate any unapproved accounts before they pose a security risk.
#!/bin/bash
# This resource is provided as a convenience for Level users. We cannot
# guarantee it will work in all environments. Please test before deploying
# to your production environment. We welcome contributions to our community
# library
#
# Level Library
# https://level.io/library/script-macos-unauthorized-admins
# Define authorized admins
AUTHORIZED_ADMINS="{{cf_authorized_admins}}"
# Always-excluded accounts (case-insensitive)
EXCLUDED_ADMINS=("root" "_mbsetupuser")
# Get all local admin users on macOS
admins=$(dscl . -read /Groups/admin GroupMembership | awk '{$1=""; print $0}' | xargs)
active_admins=()
for admin in $admins; do
if [[ -n "$admin" ]]; then
# Skip excluded accounts
admin_lc=$(echo "$admin" | tr '[:upper:]' '[:lower:]')
skip=false
for ex in "${EXCLUDED_ADMINS[@]}"; do
if [[ "$admin_lc" == "$ex" ]]; then
skip=true
break
fi
done
[[ "$skip" == true ]] && continue
# Check if the account is expired
exp_date=$(dscl . -read /Users/"$admin" accountPolicyData 2>/dev/null | grep -A1 "accountExpires" | tail -1 | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}')
if [[ -z "$exp_date" || "$exp_date" > "$(date +%Y-%m-%d)" ]]; then
# Check if the account is locked
status=$(pwpolicy -u "$admin" -getpolicy 2>/dev/null | grep "isDisabled=1")
if [[ -z "$status" ]]; then
active_admins+=("$admin")
fi
fi
fi
done
# Convert array to comma-separated string
DETECTED_ADMINS=$(IFS=','; echo "${active_admins[*]}")
# Convert lists to arrays (lowercase for case-insensitive comparison)
IFS=',' read -r -a detectedArray <<< "$(echo "$DETECTED_ADMINS" | tr '[:upper:]' '[:lower:]' | sed 's/, */,/g')"
IFS=',' read -r -a authorizedArray <<< "$(echo "$AUTHORIZED_ADMINS" | tr '[:upper:]' '[:lower:]' | sed 's/, */,/g')"
# Find unauthorized admins
unauthorizedAdmins=()
for detected in "${detectedArray[@]}"; do
found=false
# Skip excluded accounts (defense-in-depth)
for ex in "${EXCLUDED_ADMINS[@]}"; do
if [[ "$detected" == "$ex" ]]; then
found=true
break
fi
done
[[ "$found" == true ]] && continue
for authorized in "${authorizedArray[@]}"; do
if [[ "$detected" == "$authorized" ]]; then
found=true
break
fi
done
if [[ "$found" == false ]]; then
unauthorizedAdmins+=("$detected")
fi
done
# Join unauthorized admins into a comma-separated string
unauthorizedString=$(IFS=,; echo "${unauthorizedAdmins[*]}")
# Output unauthorized admins or success message
if [[ ${#unauthorizedAdmins[@]} -gt 0 ]]; then
echo "ALERT: Unauthorized Admins Detected"
echo "$unauthorizedString"
exit 1
else
echo "No unauthorized admins detected."
exit 0
fi
It retrieves a comma-separated list of admin accounts that Level has detected on a macOS endpoint and compares each username to the organization’s sanctioned list of authorized admins. If any user is found to be unauthorized, the script returns a flagged result, allowing you to take immediate corrective action. By exiting with a non-zero code when unauthorized admins are detected, it seamlessly integrates with Level’s alerting and monitoring features, enabling on-demand checks or scheduled audits without manual intervention.
Use cases
- Spotting and responding to sudden additions or changes in macOS admin privileges
- Strengthening compliance efforts by regularly validating approved admins
- Preventing dormant, rogue, or compromised admin accounts from persisting unchecked
- Integrating into a broader admin compliance automation for comprehensive monitoring
Recommendations
- Pair this script with a script-based monitor in Level to trigger alerts whenever unauthorized admins are detected
- Schedule regular checks by creating a Level automation with a time-based trigger to ensure continuous compliance
- Update the “AuthorizedAdmins” custom field to reflect changes in your official admin list
- Test the script in a non-production environment before deploying to production systems