Before an assistive application can make use of a PFUIElement, PFApplicationUIElement, or PFObserver object, the user must authorize the application to monitor and control the computer using accessibility features. Access to the computer must also be authorized before an application can use the PFEventTaps Framework to create an event tap that monitors or posts key up and key down events. Authentication with an administrator password is required.
In OS X v10.9 Mavericks and newer, access can only be authorized on a per-application basis, and the user must do it manually in System Preferences. The Privacy pane in Security & Privacy preferences includes an Accessibility list containing all applications that have been granted or denied access. A user can authorize access by another assistive application by dropping its icon into the list and selecting its checkbox or using the Add button. Authentication with an 6
administrator password is required to unlock Security & Privacy preferences. An assistive application can make this somewhat easier for the user by calling the Accessibility API’s AXIsProcessTrustedWithOptions() function, new in Mavericks, to add the application to the list automatically and present a built-in system access alert allowing the user to open System Preferences or deny access by clicking a button. The user must still authenticate and select the application in the Accessibility list manually to authorize access. Once access is authorized, it remains granted until the user denies access by unselecting the application in the Accessibility list.
In OS X v10.8 Mountain Lion or older, enabling access is easier but less secure. Global access can be enabled for all assistive applications at once by selecting the "Enable access for assistive devices" setting in Accessibility (or Universal Access) preferences in System Preferences, or the application can be made a trusted process by itself through use of the Accessibility API's older AXMakeProcessTrusted() function. Global access can even be enabled programmatically using the System Events application’s ‘UI elements enabled’ AppleScript property or the AppleScript Utility application’s ‘GUI Scripting enabled’ property, both of which are read-write AppleScript properties in Mountain Lion or older. Authentication is required.
IMPORTANT WARNING: Access is turned off by default due to security concerns. As this Programming Guide
demonstrates, the Accessibility and Quartz Event Taps APIs are very powerful, allowing an assistive application to control any other application in virtually every respect. Although access can be left on all the time, you should do so only if you are comfortable with the security of your environment.
The most straightforward way to grant access in all recent versions of OS X is to tell the user to open System
Preferences and authorize or enable access manually. In Mavericks and newer, the user authorizes access by individual applications in Security & Privacy preferences, and in Mountain Lion or older the user enables access for all applications at once by selecting the “Enable access for assistive devices” checkbox in Accessibility (or Universal Access)
preferences.
Sandboxed applications and other applications that do not use accessibility features cannot be dropped into the list.
In all versions of OSX, the user can be assisted in granting access by using an AppleScript script addressed to System Events or AppleScript Utility, both of which are scriptable faceless background applications located in /System/Library/ CoreServices. The following AppleScript handlers for Mavericks and newer present an alert inviting the user to open System Preferences or deny access. If the user clicks the Open System Preferences button, the script opens System Preferences to the Accessibility list for the user, adds the application to the list, and leaves it to the user to unlock the preference and select the application’s checkbox in the list.
on enableGUIScripting(showAlert)
tell application "System Events" to set isEnabled to UI elements enabled if not isEnabled then
if showAlert is true then
set scriptRunner to name of current application activate
display alert "Enable GUI Scripting for " & scriptRunner & "?" message "To use this script's GUI Scripting commands, open System Preferences and grant access to " & scriptRunner & " by selecting its checkbox in the Accessibility list. Then run this script again." & linefeed & linefeed & "Authentication with an administrator password is required to unlock Security & Privacy preferences." buttons {"Open System Preferences", "Cancel"} cancel button "Cancel"
end if openAccessibilityList() end if return isEnabled end enableGUIScripting to openAccessibilityList()
tell application "System Preferences"
reveal anchor "Privacy_Accessibility" of pane id "com.apple.preference.security"
activate end tell
end openAccessibilityList
The next AppleScript handler, for Mountain Lion and older, presents a dialog where the user can authenticate, and then it enables or disables access for the user depending on the value of the flag argument without opening System
on enableGUIScripting(flag)
tell application “System Events” activate
set UI elements enabled to flag return UI elements enabled end tell
end enableGUIScripting
An assistive application can enable or disable access for the user by sending similar AppleScript commands to the System Events or AppleScript Utility application. It can execute the script itself using methods in Cocoa’s NSAppleScript class or OSAKit’s OSAScript class, or it can use the Scripting Bridge. The details are beyond the scope of this
Programming Guide. AppleScript cannot authorize access for the user in Mavericks or newer.
Finally, the most user friendly and at the same time secure way in which an assistive application can be granted access is to use the Accessibility API’s AXIsProcessTrustedWithOptions() function in Mavericks and newer or its
AXMakeProcessTrusted() function in Mountain Lion and older to make it a trusted process. This is by far the most secure solution in Mountain Lion and older, because it grants access only to one application instead of all applications, allowing the user to turn off the global “Enable access for assistive devices” setting. It is the only solution in Mavericks and newer. As a trusted process, an assistive application can make full use of the Accessibility and Quartz Event Taps APIs.
Making an assistive application trusted in Mavericks and newer is very easy because no helper applications are required. Sample code is available at PFiddlesoft.com in the form of the Accessibility Testbench project.
Making an application trusted in Mountain Lion and older takes considerable effort on the part of the developer. As a result, very few applications have taken this route. PFiddlesoft’s UI Browser, UI Actions, and Event Taps Testbench applications are three that did use this technique. In outline, these are the requirements:
• Include a very small SUID helper application in the Contents folder of the assistive application’s bundle that runs as root and executes the AXMakeProcessTrusted() function on the assistive application’s main application process.
• Include another very small helper application in the Contents folder that terminates the assistive application and relaunches it, so that it will begin running as a trusted process.
• Add an appropriate user interface to the assistive application whereby the user can authenticate and run the helper applications.
• The assistive application must not contain any embedded frameworks, because Apple considered embedded frameworks in a trusted process to be a security concern. This is why we recommend that the PFAssistive and PFEventTaps Frameworks be installed in the standard location for shared frameworks, /Library/Frameworks. This has the advantage of allowing multiple assistive applications to use the same shared framework, reducing overall memory requirements. It has the disadvantage of requiring you to write an installer package. Additional technical requirements are explained in the next chapter, How to Build an Application Using the Frameworks.
• The assistive application must be installed using an installer package to ensure that the frameworks are installed in the correct location.
The PFUIElement class includes three class methods for use by an assistive application to test the current state of access or trust, +isAccessImplemented, +isAccessEnabled, and +isProcessTrusted. It also implements +isProcessTrustedWithOptions: in Mavericks and newer.