App Sandbox Quick Start
In this Quick Start you get a macOS 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, Activity Monitor, Terminal, 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.
In Xcode, create a new Xcode project for a macOS Cocoa application.
Name the project AppSandboxQuickStart.
Set an organization name and identifier, if none is already set. The organization identifier, which becomes the first part of the bundle identifier, is typically constructed using the reverse-DNS format, as described in About Bundle IDs. So if your organization name is Acme, your organization identifier would be
com.Acme, which results in a bundle identifier of
Ensure that the Use Storyboards checkbox is selected and that the other checkboxes are unselected.
In the project navigator, click the
The Interface Builder canvas appears.
In the object library (in the utilities area), locate the
Drag a web view onto the view managed by the view controller in the View Controller Scene on the canvas.
(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 view controller’s main view.
Add constraints to the web view to pin its top, bottom, left, and right edges to the main view.
Add the WebKit framework to the app.
Import the WebKit framework by adding the following statement above the interface block in the
Link the WebKit framework to the Quick Start project as a required framework.
Create and connect an outlet for the web view in the
In the view controller’s interface (either in
ViewController.hor in a category in
ViewController.m), add this:
@property (weak) IBOutlet WebView *webView;
Connect the web view to the app delegate outlet you just created.
Add the following to the
viewDidLoadmethod of the view controller:
[NSURL URLWithString: @"http://www.apple.com"]]];
When the view loads, 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
viewDidLoad 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 setting the App Sandbox switch to On in the Capabilities pane of the Xcode target editor.
In Xcode, select the project file in the project navigator and then select the
Click Capabilities at the top of the project editor to reveal the Capabilities pane, and use the disclosure triangle to expand the App Sandbox item.
Click on the App Sandbox switch to turn it On.
When you enable App Sandbox, Xcode creates an
.entitlementsproperty list file, visible in the project navigator. You are free to view and modify this file directly, either in the Xcode property list editor or in a text editor, but you don’t have to. As you use the graphical entitlements interface in the target editor, Xcode updates it for you.
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 a macOS app is successfully sandboxed.
In Finder, look at the contents of the
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,
The system creates an app’s container folder, for a given user, the first time the user runs the app.
In Activity Monitor, check that the system recognizes the app as sandboxed.
Launch Activity Monitor (available in
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.
Check that the app binary is sandboxed. In a Terminal window, enter the following command:
codesign -dvvv --entitlements :- <executable-path>
<executable-path>is the complete path for the app’s main executable binary inside the app bundle (for example,
AppSandboxQuickStart.app/Contents/MacOS/AppSandboxQuickStart). The output generated by this command contains the property list of entitlements, which includes
trueif the app is sandboxed.
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.
Build and run the Quick Start app.
The app starts normally, but fails to display the webpage specified in its
viewDidLoadmethod (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.
Open the Console application (available in
/Applications/Utilities/). In the filter field of the Console window, enter
SandboxViolationand hit enter to display only App Sandbox violation messages, similar to this:
The problem that generates these messages is that the Quick Start app does not yet have the entitlement that allows it to make outbound network connections.
The steps in the previous task illustrate the general pattern to use for identifying App Sandbox violations:
Confirm that the violation occurs only with App Sandbox enabled in your project.
Provoke the violation (such as by attempting to use a network connection, if your app is designed to do that).
Look in Console for
There is also a simple, general pattern to use for resolving such violations.
Quit the Quick Start app.
In the Capabilities tab of the target editor, within the App Sandbox section, look for the entitlement that corresponds to the reported
In this case, the primary error is
deny network-outbound. The corresponding entitlement is Outgoing Connections (Client).
In the Capabilities tab of the target editor, select the Outgoing Connections (Client) checkbox.
Doing so applies a
TRUEvalue, for the needed entitlement, to the Xcode project by modifying the
.entitlementsproperty list file.
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.
This chapter has shown how to use entitlements to enable App Sandbox and request resource access for a simple example app, but this is only a start. For a real app, you additionally code sign your app with a distribution identity before you can distribute it. When you begin to access the file system, you work within your container directories. When files are brought into your sandbox by the user through natural interactions like drag and drop, you create security-scoped bookmarks to maintain persistent access to these files over time. As your app grows in complexity, you introduce privilege separation to implement even finer grained resource control. Together, these techniques offer a means to contain damage if the worst happens.