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 OS X app to work in a sandbox typically consists of the following six steps:

  1. Determine whether your app is suitable for sandboxing.

  2. Design a development and distribution strategy.

  3. Resolve API incompatibilities.

  4. Apply the App Sandbox entitlements you need.

  5. Add privilege separation using XPC.

  6. Implement a migration strategy.

Determine Whether Your App Is Suitable for Sandboxing

Most OS X 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 OS X 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:

Resolve API Incompatibilities

If you are using OS X 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 NSOpenPanel and 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” in Daemons and Services Programming Guide.

(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 LSRegisterURL.)

Accessing User Data

Most OS X 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, OS X 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 v10.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 OS X v10.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.

Here’s a basic workflow to use to determine which entitlements you need:

  1. Run your app and exercise its features.

  2. In the Console app (available in /Applications/Utilities/), look for sandboxd violations in the All Messages system log query.

    Each such violation indicates that your app attempted to do something not allowed by your sandbox.

    Here’s what a sandboxd violation looks like in Console:

    ../Art/sandbox_errors.png../Art/sandbox_errors.png

    Click the paperclip icon to the right of a violation message to view the backtrace that shows what led to the violation.

  3. For each sandboxd violation you find, determine how to resolve the problem. In same cases, a simple change to your app, such as using your Container instead of other file system locations, solves the problem. In other cases, applying an App Sandbox entitlement using the Xcode target editor is the best choice.

  4. Using the Xcode target editor, enable the entitlement that you think will resolve the violation.

  5. Run the app and exercise its features again.

    Either confirm that you have resolved the sandboxd violation, or investigate further.

If you choose not to sandbox your app now or to use a temporary exception entitlement, use Apple’s bug reporting system to let Apple know about the issue you are encountering. Apple considers feature requests as it develops the OS X platform. Also, be sure use the Review Notes field in iTunes Connect to explain why the exception is needed.

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.”