Remove local admin rights on macOS with Endpoint Privilege Management
This guide is for engineers rolling out least-privilege on managed Macs without breaking developer workflows. You’ll remove existing local administrator rights, keep a break-glass path, and verify that elevation is handled through your Endpoint Privilege Management tooling instead of permanent admin membership.
TL;DR — The job is to get managed Macs to a state where standard users are no longer members of the local
admingroup, while approved admin tasks are handled through your Endpoint Privilege Management (EPM) workflow. The most common failure is removing admin rights before validating a working EPM policy or break-glass account; test elevation first on one device, then bulk-remove users from theadmingroup. Reading time: ~5 min
Goal
When you finish, target macOS devices will show developers’ day-to-day accounts as standard users instead of local admins, at least one separate support or break-glass admin account will still exist, and privileged actions will be approved and executed through your Endpoint Privilege Management workflow rather than permanent local admin membership.
Prerequisites
- A managed macOS device running macOS 13, 14, or 15
- Terminal access on a test Mac
- A device management platform that can deploy scripts/profiles and your EPM policy already assigned to the test device
- One working break-glass local admin account name and password, or a verified remote admin path from your management platform
- The short name of the user account to demote — check with:
whoami
dseditgroup,sysadminctl, andidavailable locally — verify with:
sw_vers
which dseditgroup sysadminctl id
- If FileVault is enabled, the list of FileVault-enabled users — check with:
sudo fdesetup list
- If you use directory/mobile accounts, the exact local short name as seen by macOS — check with:
id -un
Steps
Step 1: Confirm you have another admin path before changing anything
⚠️ Removing the only working admin path can lock you out of software installs, system settings changes, and some recovery actions. Do not continue until you have either a separate local admin account or a tested remote admin workflow.
Run these commands on a test Mac:
whoami
id -Gn
getent_passwd() { dscl . -read "/Users/$1" 2>/dev/null | sed -n '1,8p'; }
getent_passwd "$(whoami)"
If you already have a separate local admin account, confirm it is in the admin group:
id -Gn breakglassadmin
Expected success: the current user is shown, and id -Gn breakglassadmin includes admin in the output.
Step 2: Validate the EPM policy on one device before removing admin
Use your EPM product’s test action to trigger elevation for a known admin-only task. On macOS, a simple test is installing a package or writing to a root-owned location. From Terminal as the target user, run:
touch /private/var/root/epm-test 2>&1 | sed -n '1,3p'
If your EPM product exposes a context menu, self-service action, or approval prompt for privileged actions, trigger it now using your provider’s dashboard or agent UI on the test device. Then retry the command through the approved elevation path.
Expected success: without elevation you see a permissions error like:
touch: /private/var/root/epm-test: Permission denied
and through the EPM workflow the privileged action completes or the product shows an approval/elevation event for the device.
Step 3: Inventory current local admins on the Mac
List members of the local admin group:
dscl . -read /Groups/admin GroupMembership
For a cleaner list, run:
dscl . -read /Groups/admin GroupMembership | cut -d: -f2 | xargs -n1 echo
Check whether the target user is currently an admin:
id -Gn "$(whoami)"
Expected success: you get a list of admin-group members and the current user’s groups include admin before the change.
Step 4: Remove the target user from the local admin group
Replace developer1 with the macOS short name you want to demote:
sudo dseditgroup -o edit -d developer1 -t user admin
If you are demoting the logged-in user, verify immediately:
id -Gn developer1
If your environment uses sysadminctl, you can also verify account type with:
sudo sysadminctl -secureTokenStatus developer1
Expected success: dseditgroup exits with code 0, and id -Gn developer1 no longer contains admin.
Step 5: Keep or create one separate local admin account for support
If no separate local admin exists, create one before broad rollout. Replace the placeholders exactly:
sudo sysadminctl -addUser breakglassadmin -fullName "Break Glass Admin" -password 'REPLACE_WITH_LONG_RANDOM_PASSWORD' -admin
Confirm it is an admin:
id -Gn breakglassadmin
If FileVault is enabled and this account must unlock the disk at login, add it to FileVault:
sudo fdesetup add -usertoadd breakglassadmin
Expected success: id -Gn breakglassadmin includes admin; if you add FileVault access, fdesetup prompts for credentials and completes without error.
Step 6: Deploy the removal at scale from your management platform
Use your device management platform to push this exact script to the target smart group or device group after the EPM policy is already assigned. Replace developer1 with a variable from your platform if supported; otherwise test with a fixed user on one device first.
#!/bin/bash
set -euo pipefail
TARGET_USER="developer1"
if id "$TARGET_USER" >/dev/null 2>&1; then
/usr/sbin/dseditgroup -o edit -d "$TARGET_USER" -t user admin
/usr/bin/id -Gn "$TARGET_USER"
else
echo "User not found: $TARGET_USER" >&2
exit 2
fi
If your platform supports running as root, run it as root. If it supports exit-code reporting, treat 0 as success and 2 as user-not-found.
Expected success: the job reports success on the device, and the final printed group list for the target user does not include admin.
Verify it works
Run these checks on a remediated Mac:
id -Gn "$(whoami)"
dscl . -read /Groups/admin GroupMembership
touch /private/var/root/post-removal-test 2>&1 | sed -n '1,3p'
Expected results:
staff everyone localaccounts _appserverusr _appserveradm _lpadmin
The current user’s groups should not include admin.
GroupMembership: root breakglassadmin
The admin group should still include a support or break-glass account, not the developer’s day-to-day account.
touch: /private/var/root/post-removal-test: Permission denied
That confirms the user is no longer permanently privileged. Then trigger one approved privileged action through your EPM workflow and confirm the action succeeds or is logged as elevated by your EPM product.
Common pitfalls
Removing the last admin account on the Mac
Mistake: demoting the only local admin before creating or validating a separate admin path.
Symptom: sudo prompts for a password but the user cannot perform admin tasks, and there is no other local account to recover with.
Fix: bootstrapping a separate admin first with:
sudo sysadminctl -addUser breakglassadmin -fullName "Break Glass Admin" -password 'REPLACE_WITH_LONG_RANDOM_PASSWORD' -admin
Using the full name instead of the short name
Mistake: passing "Jane Doe" to dseditgroup instead of janedoe.
Symptom: dseditgroup returns an error like:
dseditgroup: Group not changed.
or the user remains in admin.
Fix: get the short name with:
id -un
and use that exact value in the removal command.
EPM policy not assigned before demotion
Mistake: removing admin rights first and planning to assign the EPM policy later.
Symptom: developers immediately lose the ability to install tools, approve system extensions, or change protected settings, and support volume spikes.
Fix: assign and test the EPM policy on one device first, then bulk-remove from admin.
Confusing FileVault unlock rights with admin rights
Mistake: assuming a user must stay local admin to unlock a FileVault-encrypted Mac.
Symptom: admins hesitate to demote users because they think login at boot will break.
Fix: check current FileVault users with:
sudo fdesetup list
and add required unlock users explicitly with:
sudo fdesetup add -usertoadd breakglassadmin
Cached group membership in the current session
Mistake: checking privileges in an existing session immediately after changing group membership and assuming the change failed.
Symptom: id -Gn developer1 run from another admin shell is correct, but the logged-in user still appears to have old behavior until re-login.
Fix: log out and back in, then rerun:
id -Gn "$(whoami)"
Targeting the wrong account on directory-backed Macs
Mistake: removing a network identity string from admin when the actual local mobile account short name is different.
Symptom: the script exits 0 on some platforms but the user still shows as admin locally.
Fix: query the local account directly on the Mac with:
id -un
and target that short name in your script or device variable mapping.
This article was written by an AI system and published pending human review. Verify anything you intend to act on.
Have a project in mind?
Get an instant AI price estimate for it, or talk directly to our team.
One email a month on what we learn building with AI