App Sandbox Quick Start

In this Quick Start you get an OS X app up and running in a sandbox. You verify that the app is indeed sandboxed and then learn how to troubleshoot and resolve a typical App Sandbox error. The apps you use are Xcode, Keychain Access, Activity Monitor, and Console.

Create the Xcode Project

The app you create in this Quick Start uses a WebKit web view and consequently uses a network connection. Under App Sandbox, network connections don’t work unless you specifically allow them—making this a good example app for learning about sandboxing.

bullet
To create the Xcode project for this Quick Start
  1. In Xcode 4, create a new Xcode project for an OS X Cocoa application.

    • Name the project AppSandboxQuickStart.

    • Set a company identifier, such as com.yourcompany, if none is already set.

    • Ensure that Use Automatic Reference Counting is selected and that the other checkboxes are unselected.

  2. In the project navigator, click the MainMenu nib file (MainMenu.xib).

    The Interface Builder canvas appears.

  3. In the Xcode dock, click the Window object.

    The app’s window is now visible on the canvas.

  4. In the object library (in the utilities area), locate the WebView object.

  5. Drag a web view onto the window on the canvas.

  6. (Optional) To improve the display of the web view in the running app, perform the following steps:

    • Drag the sizing controls on the web view so that it completely fills the window’s main view.

    • Using the size inspector for the web view, ensure that all of the inner and outer autosizing constraints are active.

  7. Add the WebKit framework to the app.

    • Import the WebKit framework by adding the following statement above the interface block in the AppDelegate.h header file:

      #import <WebKit/WebKit.h>
    • Link the WebKit framework to the Quick Start project as a required framework.

  8. Create and connect an outlet for the web view in the AppDelegate class.

    In the app delegate’s interface (either in AppDelegate.h or in a category in AppDelegate.m), add this:

    @property (weak) IBOutlet WebView *webView;

    Then synthesize the property in the implementation (in AppDelegate.m):

    @synthesize webView = _webView;
  9. Add the following awakeFromNib method to the AppDelegate.m implementation file:

    - (void) awakeFromNib {
        [self.webView.mainFrame loadRequest:
            [NSURLRequest requestWithURL:
                [NSURL URLWithString: @"http://www.apple.com"]]];
    }

    On application launch, this method requests the specified URL from the computer’s network connection and then sends the result to the web view for display.

Now, build and run the app—which is not yet sandboxed and so has free access to system resources including its network sockets. Confirm that the app’s window displays the page you specified in the awakeFromNib method. (If you get a blank window, make sure the outlet is properly connected to the web view.)

When done, quit the app.

Enable App Sandbox

You enable App Sandbox by selecting a checkbox in the Xcode target editor.

In Xcode, click the project file in the project navigator and click the AppSandboxQuickStart target, if they’re not already selected. View the Summary tab of the target editor.

bullet
To enable App Sandbox for the project
  1. In the Summary tab of the target editor, be sure the “Use Entitlements file” checkbox is checked, and specify a file for those entitlements.

    An entitlement is a key-value pair, defined in a property list file, that confers a specific capability or security permission to a target.

    When you click Enable Entitlements, Xcode automatically checks the Code Sign Application checkbox and the Enable App Sandboxing checkbox. Together, these are the essential project settings for enabling App Sandbox.

    When you click “Use Entitlements file”, Xcode also creates a .entitlements property list file, visible in the project navigator. As you use the graphical entitlements interface in the target editor, Xcode updates the property list file.

  2. If you are using an older version of Xcode that does not have a checkbox for enabling iCloud, clear the contents of the iCloud entitlement fields.

    This Quick Start doesn’t use iCloud. Because older versions of Xcode automatically added iCloud entitlement values when you enabled entitlements, delete them as follows:

    • In the Summary tab of the target editor, select and then delete the content of the iCloud Key-Value Store field.

    • Click the top row in the iCloud Containers field and click the minus button.

At this point in the Quick Start, you have enabled App Sandbox but have not yet provided a code signing identity for the Xcode project. If you have already configured your system with a signing identity, Xcode should default to using your development identity when signing this app.

If your system is not configured with a development identity and you attempt to build the project, the build will fail; before you continue with this tutorial, create a code signing identity as described in App Distribution Guide.

Now, build the app.

Confirm That the App Is Sandboxed

Build and run the Quick Start app. The window opens, but if the app is successfully sandboxed, no web content appears. This is because you have not yet conferred permission to access a network connection.

Apart from blocked behavior, there are three specific signs that an OS X app is successfully sandboxed.

bullet
To confirm that the Quick Start app is successfully sandboxed
  1. In Finder, look at the contents of the ~/Library/Containers/ folder.

    If the Quick Start app is sandboxed, there is now a container folder named after your app. The name includes the company identifier for the project, so the complete folder name would be, for example, com.yourcompany.AppSandboxQuickStart.

    The system creates an app’s container folder, for a given user, the first time the user runs the app.

  2. In Activity Monitor, check that the system recognizes the app as sandboxed.

    • Launch Activity Monitor (available in /Applications/Utilities).

    • In Activity Monitor, choose View > Columns.

      Ensure that the Sandbox menu item is checked.

    • In the Sandbox column, confirm that the value for the Quick Start app is Yes.

      To make it easier to locate the app in Activity monitor, enter the name of the Quick Start app in the Filter field.

  3. Check that the app binary is sandboxed.

    codesign -dvvv --entitlements :- executable_path

    where executable_path is the complete path for the app’s main executable binary (for example, Quick Start.app/Contents/MacOS/Quick Start).

Resolve an App Sandbox Violation

An App Sandbox violation occurs if your app tries to do something that App Sandbox does not allow. For example, you have already seen in this Quick Start that the sandboxed app is unable to retrieve content from the web. Fine-grained restriction over access to system resources is the heart of how App Sandbox provides protection should an app become compromised by malicious code.

The most common source of App Sandbox violations is a mismatch between the entitlement settings you specified in Xcode and the needs of your app. In this section you observe and then correct an App Sandbox violation.

bullet
To diagnose an App Sandbox violation
  1. Build and run the Quick Start app.

    The app starts normally, but fails to display the webpage specified in its awakeFromNib method (as you’ve previously observed in “Confirm That the App Is Sandboxed”). Because displaying the webpage worked correctly before you sandboxed the app, it is appropriate in this case to suspect an App Sandbox violation.

  2. Open the Console application (available in /Applications/Utilities/) and ensure that All Messages is selected in the sidebar.

    In the filter field of the Console window, enter sandboxd to display only App Sandbox violations.

    sandboxd is the name of the App Sandbox daemon that reports on sandbox violations. The relevant messages, as displayed in Console, look similar to the following:

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

    The problem that generates these console messages is that the Quick Start app does not yet have the entitlement for outbound network access.

The steps in the previous task illustrate the general pattern to use for identifying App Sandbox violations:

  1. Confirm that the violation occurs only with App Sandbox enabled in your project.

  2. Provoke the violation (such as by attempting to use a network connection, if your app is designed to do that).

  3. Look in Console for sandboxd messages.

There is also a simple, general pattern to use for resolving such violations.

bullet
To resolve the App Sandbox violation by adding the appropriate entitlement
  1. Quit the Quick Start app.

  2. In the Summary tab of the target editor, look for the entitlement that corresponds to the reported sandboxd violation.

    In this case, the primary error is deny network-outbound. The corresponding entitlement is Allow Outgoing Network Connections.

  3. In the Summary tab of the target editor, select the Allow Outgoing Network Connections checkbox.

    Doing so applies a TRUE value, for the needed entitlement, to the Xcode project.

  4. Build and run the app.

    The intended webpage now displays in the app. In addition, there are no new App Sandbox violation messages in Console.