Designing for App Sandbox
There’s a common, basic workflow for designing or converting an app for App Sandbox. The specific steps to take for your particular app, however, are as unique as your app. To create a work plan for adopting App Sandbox, use the process outlined here, along with the conceptual understanding you have from the earlier chapters in this document.
Six Steps for Adopting App Sandbox
The workflow to convert an macOS app to work in a sandbox typically consists of the following six steps:
Determine whether your app is suitable for sandboxing.
Design a development and distribution strategy.
Resolve API incompatibilities.
Apply the App Sandbox entitlements you need.
Add privilege separation using XPC.
Implement a migration strategy.
Determine Whether Your App Is Suitable for Sandboxing
Most macOS apps are fully compatible with App Sandbox. If you need behavior in your app that App Sandbox does not allow, consider an alternative approach. For example, if your app depends on hard-coded paths to locations in the user’s home directory, consider the advantages of using Cocoa and Core Foundation path-finding APIs, which use the sandbox container instead.
If you choose to not sandbox your app now, or if you determine that you need a temporary exception entitlement, use Apple’s bug reporting system to let Apple know what’s not working for you. Apple considers feature requests as it develops the macOS platform. Also, if you request a temporary exception, be sure to use the Review Notes field in iTunes Connect to explain why the exception is needed.
The following app behaviors are incompatible with App Sandbox:
Use of Authorization Services
With App Sandbox, you cannot do work with the functions described in Authorization Services C Reference.
Use of accessibility APIs in assistive apps
With App Sandbox, you can and should enable your app for accessibility, as described in Accessibility Programming Guide for OS X. However, you cannot sandbox an assistive app such as a screen reader, and you cannot sandbox an app that controls another app.
Sending Apple events to arbitrary apps
With App Sandbox, you can receive Apple events and respond to Apple events, but you cannot send Apple events to arbitrary apps.
However, for applications that specifically provide scripting access groups, you can send appropriate Apple events to those apps if your app includes a scripting targets entitlement.
For other applications, by using a temporary exception entitlement, you can enable the sending of Apple events to a list of specific apps that you specify, as described in Entitlement Key Reference.
Finally, your app can use the subclasses of
NSUserScriptTaskclass to run user-provided AppleScript scripts out of a special directory,
/). Although your app can read files within this directory, it cannot write files into this directory; the user must manually place scripts here. For details, see the documentation for
NSUserScriptTaskand WWDC 2012: Secure Automation Techniques in OS X.
Posting keyboard or mouse events to another app
You cannot sandbox an app that controls another app. Posting keyboard or mouse events using functions like
CGEventPostoffers a way to circumvent this restriction, and is therefore not allowed from a sandboxed app.
Sending user-info dictionaries in distributed notifications to other tasks
With App Sandbox, you cannot include a
userInfodictionary when posting to an
NSDistributedNotificationCenterobject for messaging other tasks. (You can, as usual, include a
userInfodictionary when messaging other parts of your app by way of posting to an
Loading kernel extensions
Loading of kernel extensions is prohibited with App Sandbox.
Simulation of user input in Open and Save dialogs
If your app depends on programmatically manipulating Open or Save dialogs to simulate or alter user input, your app is unsuitable for sandboxing.
Accessing or setting preferences on other apps
With App Sandbox, each app maintains its preferences inside its container. Normally, your app has no access to the preferences of other apps.
However, if your app requires access to the preferences files of other applications, there are temporary exception entitlements available that allow you to specify a list of named preference domains that your app needs to access. For details, see Entitlement Key Reference.
Configuring network settings
With App Sandbox, your app cannot modify the system’s network configuration (whether with the System Configuration framework, the CoreWLAN framework, or other similar APIs) because doing so requires administrator privileges.
Terminating other apps
With App Sandbox, you cannot use the
NSRunningApplicationclass to terminate other apps.
Resolve API Incompatibilities
If you are using macOS APIs in ways that were not intended, or in ways that expose user data to attack, you may encounter incompatibilities with App Sandbox. This section provides some examples of app design that are incompatible with App Sandbox and suggests what you can do instead.
Opening, Saving, and Tracking Documents
If you are managing documents using any technology other than the
NSDocument class, you should convert to using this class to benefit from its built-in App Sandbox support. The
NSDocument class automatically works with Powerbox.
NSDocument also provides support for keeping documents within your sandbox if the user moves them using the Finder.
Remember that the inheritance path of the
NSSavePanel classes is different when your app is sandboxed. See Open and Save Dialog Behavior with App Sandbox.
If you don’t use the
NSDocument class to manage your app’s documents, you can craft your own file-system support for App Sandbox by using the
NSFileCoordinator class and the
NSFilePresenter protocol, but this requires a lot of extra work.
Retaining Access to File System Resources
If your app depends on persistent access to file system resources outside of your app’s container, you need to adopt security-scoped bookmarks as described in Security-Scoped Bookmarks and Persistent Resource Access.
Creating a Login Item for Your App
To create a login item for your sandboxed app, use the
SMLoginItemSetEnabled function (declared in
ServiceManagement/SMLoginItem.h) as described in Adding Login Items Using the Service Management Framework.
(With App Sandbox, you cannot create a login item using functions in the
LSSharedFileList.h header file. For example, you cannot use the function
LSSharedFileListInsertItemURL. Nor can you manipulate the state of Launch Services, such as by using the function
Accessing User Data
Most macOS path-finding APIs return paths relative to the container instead of relative to the user’s home directory. If your app, before you sandbox it, accesses locations in the user’s actual home directory (
~) and you are using Cocoa or Core Foundation APIs, then, after you enable sandboxing, your path-finding code automatically uses your app’s container instead.
For first launch of your sandboxed app, macOS automatically migrates your app’s main preferences file. If your app uses additional support files, perform a one-time migration of those files to the container, as described in Migrating an App to a Sandbox.
If you are using a POSIX function such as
getpwuid to obtain the path to the user’s actual home directory from Directory Services (rather than by using the
HOME environment variable), consider instead using a Cocoa or Core Foundation symbol such as the
NSHomeDirectory function. By using Cocoa or Core Foundation, you support the App Sandbox restriction against directly accessing the user’s home directory.
If your app requires access to the user’s home directory in order to function, let Apple know about your needs using the Apple bug reporting system. In addition, be sure to follow the guidance regarding entitlements provided on the iTunes Connect website.
Accessing Preferences of Other Apps
Because App Sandbox directs path-finding APIs to the container for your app, reading or writing to the user’s preferences takes place within the container. Preferences for other sandboxed apps are inaccessible. Preferences for apps that are not sandboxed are placed in the
~/Library/Preferences directory, which is also inaccessible to your sandboxed app.
If your app requires access to another app’s preferences in order to function—for example, if it requires access to the playlists that a user has defined for iTunes—let Apple know about your needs using the Apple bug reporting system. In addition, be sure to follow the guidance regarding entitlements provided on the iTunes Connect website.
Using HTML5 Embedded Video in Web Views
If you are compiling an app that uses the WebKit framework, and your target is OS X 10.7, you must also link your app against the AV Foundation framework. If you do not do so, because of the way App Sandbox interacts with CoreMedia, your app will be unable to play HTML5 embedded videos.
This additional linking step is not required for apps that run only on macOS 10.8 and later.
Apply the App Sandbox Entitlements You Need
To adopt App Sandbox for a target in an Xcode project, apply the
<true/> value to the
com.apple.security.app-sandbox entitlement key for that target. Do this in the Xcode target editor by selecting the Enable App Sandboxing checkbox.
Apply other entitlements as needed. For a complete list, refer to Entitlement Key Reference.
Add Privilege Separation Using XPC
When developing for App Sandbox, look at your app’s behaviors in terms of privileges and access. Consider the potential benefits to security and robustness of separating high-risk operations into their own XPC services.
When you determine that a feature should be placed into an XPC service, do so by referring to Creating XPC Services in Daemons and Services Programming Guide.
Implement a Migration Strategy
Ensure that customers who are currently using a pre-sandbox version of your app experience a painless upgrade when they install the sandboxed version. For details on how to implement a container migration manifest, read Migrating an App to a Sandbox.