DevToolsSecurity on macOS and debugger authorization on unattended CI
When a debugger attaches to a program built in Xcode or the terminal on a Mac, or when Instruments starts, a “Developer Tools Access” prompt can appear and ask whether one process may control another. On my own Mac, typing the password ends it. On an unattended test or a headless CI/CD runner, the job stalls while that prompt waits for input.
The command that removes the prompt ahead of time is sudo DevToolsSecurity -enable. This post covers what the command changes and where to look when the prompt remains after enabling. What I confirmed with read-only commands on macOS 27.0.1 on October 4, 2026 is marked as such. I did not run -enable or the group command again this time.
Why a debugger asks for authorization
macOS isolates the memory of each process. Stopping another process, reading or writing its memory, and injecting code into it are restricted.
lldb and Instruments need access to the target process to analyze it. They get the target’s Mach task port through task_for_pid in XNU, and use that port to step line by line or dump memory. Without enough privilege, the request is denied or goes through an administrator password prompt. Authorization Services handles that authorization, and the rules are stored in /var/db/auth.db.
The rule that DevToolsSecurity changes
/usr/sbin/DevToolsSecurity changes the rule of a right named system.privilege.taskport. The earlier version of this post explained that before enabling, the rule asks for the login password or root credentials, and that after enabling, it is tied to the _developer group. Of these, I could not check the behavior before enabling this time.
I read the rule in the enabled state with security authorizationdb read system.privilege.taskport. These are the values I read (macOS 27.0.1).
classisuser.groupis_developer.authenticate-useris true, andallow-rootis false.timeoutis 36000.
An earlier version of this post said the class after enabling is rule, but the value I read this time was user. The comment on the rule says this right is used by task_for_pid and applies only when the requesting program and the target program are run by the same user. It does not authorize access to another user’s program. I could not check the values before enabling, because the Mac I checked already had it enabled.
Use -status to check the state
Running /usr/sbin/DevToolsSecurity with no argument does not show the state. According to the usage text, the default action is -enable.
This is the usage text, printed by passing an option that does not exist.
$ /usr/sbin/DevToolsSecurity -help
DevToolsSecurity: unrecognized option `-help'
Changes the security authorization policies for developer systems
Usage: /usr/sbin/DevToolsSecurity [-verbose] [-enable | -disable | -status]
-enable :: (default) enable developer mode policies
-disable :: return policies to system default
-status :: prints out whether or not developer mode policies are in effect
-verbose :: makes output more verbose
To see only the state, use -status.
$ /usr/sbin/DevToolsSecurity -status
Developer mode is currently enabled.
The earlier version said to run the command with no argument and look for enabled. That explanation was wrong, and it is corrected as shown above.
When the prompt remains after enabling
After -enable, lldb in the terminal or C++ debugging in VS Code can still show the prompt or fail with attach failed. The place to look is whether the account is in the _developer group.
This command adds the currently logged-in account to the group.
# 현재 로그인된 계정을 _developer 그룹에 강제 멤버십 추가
sudo dscl . append /Groups/_developer GroupMembership $(whoami)
The Korean comment says the command adds the currently logged-in account to the _developer group.
After adding, reopening the terminal or logging out and back in is recommended. The members of the group can be listed with dscl . read /Groups/_developer GroupMembership.
I did not compare causes myself for this part. On the Mac I checked, the _developer group had no GroupMembership key at all.
$ dscl . read /Groups/_developer GroupMembership
No such key: GroupMembership
I did not check how attaching a debugger behaves on this Mac, where the GroupMembership key was absent, or under exactly which condition group membership is needed. There is also no basis for saying that joining the group resolves every attach failed.
What happens on an unattended runner
Mobile release automation uses a Mac mini or a macOS virtual machine in the cloud as a runner. The problem case is when this setup step is omitted after a fresh Xcode install or an OS upgrade.
When Appium or an Xcode UI test installs the test app and tries to attach for debugging, the authorization request appears in the GUI in the background. Nobody is at the runner to answer. The job ends only after the configured time limit passes, and a runner with no time limit keeps waiting. A result from reproducing this flow and timing it is not included here.
So the script that prepares a runner runs two things together.
# 개발자 도구 액세스 허용 활성화
sudo /usr/sbin/DevToolsSecurity -enable
# 빌드 실행 에이전트 계정을 개발자 그룹에 병합
sudo dscl . append /Groups/_developer GroupMembership build_agent_user
The first comment says “enable developer tools access,” and the second says “add the build agent account to the developer group.”
Replace build_agent_user with the account name the runner uses. Putting the enable command into the runner setup guide as well keeps it from being missed on a new machine. There is no basis for saying that every server needs both commands. I also did not measure how installing a test app on a device or simulator connects to task port authorization on the Mac.
What is given up in security
This setting removes one authorization step. To that extent, developer tools can handle the memory of other processes run by the same user more widely. Access to the machine should be controlled, and binaries or code of unknown origin should not run on it.
Developer Mode on an iPhone or iPad targets something else. Developer Mode on a device allows locally installed apps, such as an app built and run from Xcode, to run on that device. It does not affect apps installed from the App Store or TestFlight. The setting in this post is the permission for tools such as lldb to control other processes on a Mac.
The values read this time come from one Mac running macOS 27.0.1, and because it was already enabled, the values before enabling could not be checked. A comparison across macOS versions is not included here either. I also could not confirm in the documentation exactly which signature the condition “only signed developer tools are allowed” refers to.
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.