A Practical Guide to the App Sandbox

Session 710 WWDC 2013

Discover how you can use App Sandbox to protect your app’s users from unintentional bugs or deliberate attempts to compromise security. Understand sandboxing’s security goals, how applications and their data are isolated from each other, and how to express the resources your application needs. Learn about App Sandbox-related APIs and entitlements, and how to adopt them for your app to meet the Mac App Store Guidelines.

[ Silence ]

Speaker 1: Hi.

How's it going?

Welcome to the most magical session at WWDC.

I think of this session as the centerpiece of the conference and then we announce some other stuff too.

But, we're going to be talking about App Sandbox today.

And, before we really get into that, we're going to talk about cars.

A lot of us drive, a lot of us know, sort of, how cars have been evolving as time has gone on.

And I found, I found it pretty interesting that just a couple of years ago traffic related fatalities in the United States have actually reached a 50 year low.

The NHDSA has statistics on this and the numbers have been getting better and better and they're, basically, at a really long low at this point.

And if you look at why that is, it's because the car industry has been investing into safety mechanisms for a long time.

It's because you can't sell a car without passing Federal Safety Certification.

But, what's more interesting to me, is how that investment into safety has actually worked out in practice.

On the one hand, there's been a tremendous amount of innovation in trying to prevent accidents from happening.

So, just in the last year or two, you're seeing a bunch of new mechanisms in modern cars where, for instance, there is blind spot detection.

The car will actually beep at you if you're trying to change lanes and there's a car in your blind spot.

There are really a number of new electronic mechanisms that are, for instance, how can you, if you're trying, if you're drifting out in the lane, sensors can now notice and warn you.

A lot of things that are trying to help drivers be more alert even on longer trips and make sure that you never get in a position where you're in an accident.

And all of those have been really helpful.

Almost orthogonal to all of those, there's been a number of mechanisms that try to make it so that if you wind up in an accident, harm is minimized.

Seatbelts and airbags are the prime examples of this.

For many of you, I'm sure, this is just something that's always been a part of the car but, actually, seatbelts were not standard equipment until, I think, the '60s.

Airbags were not standard equipment in most U.S. cars until the '90s.

And those standards are evolving even today.

So, it's interesting to me because, obviously, the best case scenario is you never wind up in an accident.

But, if you do, the car is trying to be prepared for it and is trying to keep you from getting harmed.

So, if you have that model in mind and you look at how computer security used to work on desktops and desktop operating systems, it's really been very, very different.

There has never been a seatbelt or an airbag for a desktop computer.

In other words, it was all about making sure that an attack never succeeds.

But, once it does, there was really no way to contain the damage, to contain the impact of a malicious piece of software that has successfully exploited the vulnerability.

It has just been defenders trying to defend 100 percent of the attack surface all the time, the attacker's finding 1 hole, 1 time and winning.

So, why is that?

It turns out that the way we got here, as an industry, is because of assumptions that were made in the era of the original UNIX being designed with Ritchie and Thompson.

Where they made this underlying assumption, that I now call the unfortunate assumption, which is that every program runs with the full privileges of the user that ran that program.

In other words, we should direct security barriers between different users of the same system, but not between different apps from the same user.

And, again, if you sort of look back and think about why 40 years ago this assumption was made, it was because it made total sense.

There was no such thing as untrusted code being run because all the code that would run was code that you manually put on a punch card, walked up to a machine, loaded and ran.

So it was pretty reasonable to say that that code should run with your full privileges and that that wouldn't be an issue in practice.

But, today, most machines are single user machines.

We run untrusted code all the time.

Every time you visit a website, that's what's happening under the covers.

And so it's sort of clear that apps should be only accessing the information they actually need to get their work done and not having unrestricted access to your whole computer.

I have an example that I, that I like.

This is a beautiful new application updated for Mavericks.

It's called Watch Grass Grow.

I spent a lot of time with this app and it's gorgeous.

It shows grass growing in real time and, you know, it connects to the network every once in a while to pick up new grass assets.

So, for instance, droplets on shimmering blades of grass that come over the network.

Beautiful stuff, but this app should never be able to access any of my data.

If somehow, in the process of making these network requests, this app were to become exploited, it could normally access all of my data.

It could read my E-mail, it could change my computer settings, it could look at my browsing history.

All stuff that it should never be able to do.

And the way that the computing industry has traditionally dealt with this is by erecting user interfaces that try and get users to make the right decision which is what this normally looks like to a normal user.

In other words, security interfaces generally don't work.

They're expecting way too much background understanding of how computers work from normal users who don't have that kind of knowledge.

And, as a result, over the years users have actually basically been conditioned to just look for the Allow button.

And press it because it maximizes the chances that they can get done the thing they were trying to get done.

Obviously, rendering the whole point of the user interface moot.

There's this great saying in Washington, D.C., it's a political saying which says, if you're explaining you're losing, and I think it applies to security interfaces as well.

If you're hoping that a user understands the details of X.509 and SSL certificates and can make a valid decision about what to do, you're probably losing.

So, that is how things used to be and, obviously, the landscape has really changed a lot in the last few years.

Tons of apps and tons of developers, it's never been this easy to be a developer or to write apps largely facilitated by the App Store revolution.

And, while that's happened, computers have also basically started to be always on networks.

Ubiquitous Wi-Fi and, for mobile devices, radios, our computers spend much, much more time connected than they do disconnected which didn't use to be the case.

Finding new software, super easy; it's never been this easy.

And so it really underscores that today's challenge for security is to isolate data between different programs, not between different users.

So, when I normally try and pitch people on, you know, how some of this background works, I get a lot of different responses.

And one frequent one is developers saying, well I have a really simple app, it doesn't do much.

And I am very careful, I understand security and I'm pretty sure that my code doesn't actually have vulnerabilities so why do I have to bother with any of this?

And the answer is because even though your app may be simple and pretty constrained in what it does, remember that you're linking against millions and millions and millions of lines of system libraries and other libraries and frameworks which are doing incredibly complex things behind the scenes where you might not have even thought of them.

So, you know, you might have a super simple app that just shows a web view to authenticate the user.

That web view, in terms of complexity, is practically a small operating system, right?

It's millions of lines of code to render HTML, to run a just-in-time JavaScript compiler, it's a huge amount of complexity.

And a single vulnerability anywhere in all the code that your app has plus all the code it links against used to mean a really bad day for the user.

Attack finds one hole, attack wins.

There's no containment of damage, that's it.

So it's against this backdrop that, in Lion, we introduced App Sandbox, a mechanism that tried to make it much easier to write secure applications for OS X.

And it tried to do this by doing something really different which is, instead of trying to drive security policy by explicit user choices through prompts, it tried to drive security policy through user intent.

And it tried to, in effect, do this so that it can then contain damage from exploitation or even a misbehaving app such as pathological bugs in the code that would try to delete or corrupt user data.

So, how does this work?

Well, the premise is this.

You write your apps which means you know what your apps are meant to be able to do when they're working properly.

We take that app in the operating system, we assign it its own space on the file system that we call a container, and then the operating system lets the user control what other data your app can get access to.

And it does this by making all the special cases like drag and drop and recent items and so forth just work magically under the covers.

So, let's talk about the key components here.

I mentioned that you specify what your app is meant to be able to do.

And the way it does this is by using what we call entitlements.

Entitlements are actually very simple, they're just a very simple plist.

You can Xcode gives you a beautiful interface for it and I'll show you that in a bit, but it is just a very simple plist.

And the idea behind entitlements is that they express concepts of access that should be easily understandable even to an end user even though it's not ever meant to be seen by an end user.

So here are some examples of things that are entitlements.

Entitlements are things like I want to be able to access a Downloads folder, I want to be able to talk to the network, I want to be able to access the user's Address Book.

Now I mentioned that we take your app and we put it in a container and the way this works is there's actually no deep magic happening.

When we're launching your app, we set 2 environment variables called Home and CFFIXED-USER-HOME and we point them at a file system location that we assign specifically for your app.

And we basically pretend that that location is the user's Home Directory.

So, here's what that looks like where we have an app, we just put in a Sandbox and, if in the app, we have a direct open system call with the specific path inside their real Home Directory of the user, the Sandbox denies this access.

And says, actually no, that's in the user's real Home Directory, this aisle doesn't yet have access to that.

But if the app, instead, calls Apple API like NSHomeDirectory, well the answer that it'll actually get is its own container location which means that it's within the Sandbox which means access is allowed.

So then, you might say, well okay, but an app is not going to be very useful if all it can access are files that it read, then wrote in its own little space.

How does it actually get access to the real files that the user has?

And the answer is the Powerbox.

The Powerbox is a trusted operating system facility in OS X that makes it so that Cocoa NSOpen and NSSave panels are actually drawn out of process by a trusted system service.

And, if you think about open and save panels, they're this really unambiguous declaration of user intent.

If you have an app open and there's an open panel and the user select a file or folder, it's really clear what the user's trying to do.

They're saying I want to open this file or folder in this app.

So by moving the open and save panels to be a trusted system service, we can take that declaration of user intent and then form security policy around it specifically by making those files and folders then available to the app.

Let me show you what this looks like.

Here's an app, it links against AppKit in the top and we're going to put it in the Sandbox.

And let's say that the app wants access to a file within tilde documents.

Well an NSOpen panel is presented and normally, because this app is Sandboxed, if AppKit were to try and get access to tilde Documents directly, this would just fail.

The sandbox would say, no you're not allowed.

But what happens in the App Sandbox world, because of the Powerbox, is that AppKit realizes it's running in a Sandbox and so, instead of presenting the open panel directly, it calls out the Powerbox and says, Powerbox, please present an open panel on my behalf.

Powerbox also links against AppKit, but it's not Sandboxed so it has access to documents which means it can draw the open panel on the app's behalf.

This looks exactly like it's always looked.

You never know that you're using the Powerbox, it's just completely under the covers.

But, once a user selects a file or folder in this open panel, that file or folder is then made available directly in the Sandbox of your app.

Finally, XPC Services are the easiest mechanism that there's ever existed to split up parts of your app into separate functional units that can have different security policies assigned to them.

Why does this matter?

Well because, as apps get more and more complex, they do more and more things.

And if, in the end, you have a single monolithic app that has to be able to access all kinds of things from hardware to private information to user documents.

Then, even though the app Sandbox still provides some mitigation if that app were to become exploited, it may be that an attack on that app that succeeds can already get access to so much information that maybe that's all the attacker cares about.

So to try and mitigate this, you can break out pieces of your code, especially, highly sensitive pieces of your code, for instance, the deal with the network into XPC services that are made available to your app.

And then you can, basically, Sandbox those independently and restrict their access to things like sensitive user information.

And with XPC, the service's lifetime is fully managed by the operating system so you don't have to worry about starting them up and tearing them down when you need to.

You don't have to worry about, you know, whether they're running when you want them.

It's just done for you by the OS.

So that's a lot of concepts.

What does this actually look like?

I'm going to show you this on TextEdit because it's you can look at that source code and TextEdit has been Sandboxed since Lion, but we're going to pretend it's not and we're going to show you what it looks like to Sandbox it.

And the process we're going to follow here is we're going to look at the Entitlements list and kind of pick the ones we think make sense for a program like TextEdit.

We're going to code sign TextEdit when building it which will cause the Entitlements to take effect.

We'll double check that TextEdit, as it runs, is in fact Sandboxed like we expect.

And then, finally, we'll look for Sandbox violations that the OS is reporting to try and figure out if we're maybe missing some Entitlements that we need.

And I should note that for the last two WWDCs, the app I've used as my demo app is Adium which is a really popular instant messaging client.

And I'm thrilled to be switching to TextEdit this year because the actual Adium app became Sandboxed.

The developers took it, Sandboxed it, and so if you download Adium now, it is Sandboxed so I feel like I needed a new example.

Okay. So here's the TextEdit project.

And what we'll do is just run it, here it is.

And what I've done is I've grabbed activity monitor here and I've filtered it by TextEdit so you can see the process right there.

And in the View menu in columns, I've actually enabled the Sandbox column so that you can see that right now TextEdit is running unsandboxed.

So let's see if we can Sandbox it.

We're going to click on the target and, in the Capabilities tab in Xcode 5, it's really this very nice graphical editor of various capabilities, App Sandbox is just one set of them.

So, we'll flip on the App Sandbox switch and TextEdit obviously needs to be able to edit files that a user selects so that seems like an obvious Entitlement to give it if it wants to be able to both read them and write to them so we'll say read/write to user selected files.

That seems about right.

Let's run it now.

There's TextEdit and in Activity Monitor, you'll notice now that the Sandbox column indicates yes.

So this thing is running Sandbox.

So that's it, is there anything more to it?

Well, we want to check if there were any errors encountered while TextEdit actually ran in the Sandbox so we'll switch here to Console where I'm filtering by output of the Sandbox daemon.

And, indeed, you'll notice that there's actually a bunch of messages indicating that SandboxD is telling us that TextEdit was denied certain operations by the Sandbox.

So it looks like it was denied the ability to do a mach lookup on SCNetworkReachability and some system socket access and then some more mach lookups to com.apple.networkd.

So why is that?

Well, it's because this particular TextEdit tries to make a network connection when it starts and I didn't enable that in my Entitlements.

All I need for TextEdit to be able access the network here is allow it to make outbound connections to the network to act as a network client.

So why don't we enable that?

And rerun TextEdit.

There it is.

And you'll notice there were no more violations shown meaning TextEdit is running Sandboxed, everything's operating like we want, no violations are getting logged, that's it.

TextEdit is Sandboxed.

What did we really accomplish there?

Why did we do this?

We did it because, even though that took us all of 3 minutes to do, the TextEdit before we Sandboxed it and the TextEdit after we Sandboxed it behave very differently if you can exploit them.

Right now, when it's Sandboxed, if you are able to somehow attack TextEdit and exploit it, all you get access to as an attacker are the files that the user currently has open in TextEdit.

Nothing else, no other access to the user's disk.

No other access to the user's hardware.

No access to user's E-mail, no access to user's browsing history, you're contained.

You can't install applications, you can't change the TextEdit application to put a Trojan in there.

You're pretty tightly contained.

And, in order to really launch a successful attack here, you need to chain multiple vulnerabilities, some of them probably kernel vulnerabilities to really pull off a strong attack.

So that's a tremendous improvement in the safety of TextEdit as an app.

And if that resolved it for very many of you, that is about all the exposure to App Sandbox that you'll need.

You'll be able to go in and look at the Capabilities interface in Xcode 5, tick some boxes, try it, check for violations, and you'll be done.

But, as your apps get more complex, you may also need some advanced functionality and I'd like to show you what else we have on offer.

The first thing I'm going to talk about is a mechanism called Security Scoped Bookmarks.

And, to understand where this comes from, I have to tell you a bit about how files and access given to files are managed as your app runs.

So your app starts, it has access to nothing outside of its container, the user then gives it access to a file or folder through the Powerbox.

And so now, while the app is running, it has access to this new file.

But, as soon as your app quits, it loses that access.

The next time it starts, it no longer has access to the file that the user opened last time.

And this is the only reasonable default because, otherwise, the amount of things that apps can access would just grow without bound, over time, as the apps are used.

So defaulting to losing the access as the app restarts, is the right thing to do.

But it's not, it can't be the only option.

There are apps that really legitimately need to be able to preserve access to files and folders that a user selected across launch.

And, usually, those use cases fall into 2 categories.

There are what we call app-scoped bookmarks where the preservation of access to files and folders comes as part of the app's configuration.

And then there are document-scoped bookmarks which pertain to document formats where the document itself can actually reference files all over the disk and you want to be able to have that continue working as the document is opened and closed potentially across different apps.

So, for app-scoped bookmarks, there is no special Entitlement, it's actually provided the ability to use this is provided if you simply have the user selected files bookmark.

And what I have here is an example from the Mail app where which is Sandboxed by the way.

You can see that you can select the folder to which attachments will get downloaded automatically.

And so, if you think about it, if the user chooses a different folder here and mail loses that access on re-launch, that wouldn't be very helpful.

So, somehow, it needs to be able to say, I'm going to preserve the user selection and always have access to it.

So app-scoped bookmarks allow you to do this and they lock the files or folders that the user selected to your specific app running as that specific user.

So here's what that looks like.

The user is going to pick a file or folder and make access available to your app such as your Powerbox.

Your app is going to turn around and take that file and pass it on to the bookmarkDataWithOptions API.

This is the same API that's been around for years now, actually, just for normal bookmarks.

And this API is going to produce just an NSData, an opaque blob that represents the app-scoped bookmark which your app is free to store anywhere it pleases such as in its container as a file or in user defaults or even in Core Data.

It doesn't matter so long as it's in a place that's accessible to the app later.

Then, on next launch, when the app needs access to this file or folder, it'll simply fish out that NSData from wherever it stored it, pass it into the URLByResolvingBookmarkData API which will check that the blob came from the right app and the API provides access to the file or folder.

If some other app were somehow to get a hold of that same app-scoped bookmark, this simply wouldn't work, the API would say, no, you did not create this bookmark, you cannot resolve it.

The other use case, the document-scoped bookmark use case is useful if you have a document format that needs to be able to link to movies or pictures or other large files that may be all over the disk.

And the restrictions differ for document-scoped and app-scoped bookmarks.

For document-scope, they are openable by other apps, but the target of the bookmark cannot be in a certain restricted set of locations.

So you can't bookmark Contents and things like tilde Library.

And currently you can't document, you can't bookmark folders, it must be individual files.

So here's what the document-scoped case looks like.

The user is going to create the document in your app and they're going to link a movie into that document so you're going to turn around and actually pass both of these into the bookmarkDataWithOptions API and say, I am planning to take this movie that the user gave me access to and I'm planning to insert it into this document.

And the API produces another NSData blob that basically must be inserted in the document you said you were going to put it into.

So that's what your app does.

Then, when the user reopens the document which now has this link that, currently, from your Sandbox, you can't follow to the movie.

You can take that security scoped bookmark out of that document and say, I retrieved it from this document and here's the bookmark.

Pass both of those to the API, the API will resolve the bookmark, provide you access to the movie and now you can recreate this link and follow the reference.

I should mention that, for document-scoped bookmarks, if you think about it, document formats need to generally run between different apps.

So if another app can open the same document, it can actually resolve that very same bookmark.

So, as I mentioned, there's no new API to the security scoped bookmarks, it's the same bookmark API that has been around for several years.

In case any of you are not familiar with bookmark API, it's actually the modern replacement to things like aliases and FSRefs so, basically, an API for being able to, as best as the OS can, track files and folders as they move around the file system or get renamed.

But there's one critical difference between the normal bookmark resolution API and using that same API for security scoped bookmarks.

And that is that when you resolve a security scope bookmark, what you get back is what we call a security scoped NSURL.

It's an NSURL, it tells you where the file is, but you can't immediately go and follow it.

It has not yet been made available inside your Sandbox.

Instead, you are responsible for calling a method on that URL object called startAccessing SecurityScopedResource.

And it's the act of calling that method that makes the file or folder available within your Sandbox.

When you're done with the file or folder, you have to match the call with stopAccessing SecurityScopedResource which tells the operating system to free up resources that it's using on tracking which additional files are available inside your Sandbox.

This is really important because if you don't call StopAccessing and you start accumulating many, many, many Sandbox extensions that were done in this way, eventually your app will, basically, not be able to take in anymore.

And opening files through the Powerbox will start failing.

It's not a good place to be, basically, until your app is restarted.

So balancing these is very important.

One other thing that App Sandbox focuses on is making sure that, by default, applications really can't talk to each other directly.

Generally, communication between Sandbox apps has to happen through some kind of operating system interface and mediation which, again, turns out to be the right default.

But there are totally legitimate use cases where multiple applications want to be able to establish direct communication channels or just share files and folders on disk.

The most common case for this is suites of applications from the same developer where it makes sense that they want to have a scratch base on disk that they all share or that they want to be able to do direct IPC.

And another very common use case is apps that have a helper.

For instance, a login item that runs every time the user logs in, even when the main app is not running, and then when the main app starts running, it wants to be able to somehow establish direct communication to the helper that's been running in the menu.

So, to solve that problem, we have a mechanism called application groups.

The idea is it's just another Entitlement that you can put on multiple apps or an app and its helpers.

And it's prefixed by your Apple Team ID and, after that, it's whatever name you want.

And applications that have the same application group name get to directly communicate and share file system locations.

So here's what that looks like.

Normally we have an app, it gets its own container and it can access that container just fine.

And here we have a helper, maybe as a login item.

Well, our main app can't access the helper's container directly.

The Sandbox prohibits this.

But, if we create an Entitlement, and we say, here we're actually going to put this into myApp application group, and we place that Entitlement on both our app and our helper.

Now a shared location comes into being on the file system that both of these can access directly.

In addition, as I mentioned, certain IPC primitives like mach and posix become available for establishing direct communication channels between the app and the helper or between different apps in a suite where apps share an application group.

We have an API called SMLoginItemSetEnabled that is fully App Sandbox compatible that will allow you to run your helper as a login item every time the user logs in.

Normally the fact that the Powerbox only provides access to the file or the folder that the user selected is exactly what we want both for the security properties of App Sandbox and because that sort of makes sense.

But there are some cases where you want just a little bit more access.

So one example since we used TextEdit as our demo app, TextEdit, as you probably know, when you create a new document creates a Rich Text Format document, an RTF file.

But, if you drag a picture into that file, TextEdit needs to basically turn the file into a directory, change its name from whatever the name was .rtf to whatever the name is .rtfd so that it can basically store these attachments in the directory.

And normally, that wouldn't work because trying to rename blah.rtf into blah.rtfd, the Sandbox would be prohibiting this.

The user did not give you access to blah.rtfd so you can't do it.

So to solve this problem in a specific narrow set of cases, we have a facility called Related Items that lets you express certain relationships between file names and their extensions.

And in this case, you can specify that RTF is related to RTFD so that if the user gives you access to blah.rtf, you can also use NSFilePresenter methods to obtain access to blah.rtfd.

This is how TextEdit does its rename and there are a number of similar use cases like movie players wanting to access subtitles which are normally named the same as a movie file but with a different file extension.

This also requires a declaration of which patterns are allowed in the info plist and we have some documentation that shows you how to do this.

OS X for a long time has been the best platform for automation and rich automation that there is.

And while App Sandbox never imposed any restrictions on how Sandboxed apps can be scripted by the user, it did impose rigorous restrictions on how Sandboxed apps can script other apps.

And the reason for this is pretty obvious if you think about it.

If you have a Sandbox and it's enforcing all these tight restrictions, but the Sandbox allows a Sandboxed app to go and script Finder or Terminal, then there's effectively no Sandbox, right?

You can get those apps to do pretty much anything you want on the system.

What we did is we created a mechanism called Apple Event Access Groups that allows scriptable applications to mark up their scripting definition and say that certain groups of events are safe.

They're safe to be invoked by Sandboxed apps.

And this works for, if you're familiar with scripting definitions, sort of the full richness of that definition mechanism so commands, classes, properties, you name it, all of them can be grouped into access groups.

So this is documented, then you can take a look at how it works.

But it's also used by a number of OS X apps already so, for instance, Mail has an access group called com.apple.mail.compose which means that now, even if you're Sandboxed, you can use scripting to ask mail to pop open a compose window and put some information in there and get ready for the user to send E-mail.

iTunes, similarly, has a number of access groups that you can use to control the playback or access library information.

And so the way this works is there's a new Entitlement called Scripting Targets where you list for every app that you want to be able to script which has access groups, you list which access groups your app wants to be able to use.

For example, here's the Entitlement, if we want to script Mail, we're going to say in this dictionary that mail is the only key and that its value is an array which contains, in this case, just one access group called com.apple.mail.compose.

Now it turns out that there's one other familiar way of doing scripting that a lot of OS X apps want to be able to do which is allowing the user to select scripts that run in reaction to certain things happening inside the app.

Timer app might want to be able to run a script when the timer fires.

Mail actually supports you saying that when a certain mail rule is triggered, a script should run.

Aperture allows you to set that a certain script should run after all your photos have been imported.

And, traditionally, this would mean that the script is actually executed by the application which means, of course, that it's subject to the application Sandbox.

This is really problematic.

If the user is writing scripts and expects to be able to do whatever they want in the context of the script because the Sandbox will simply prohibit those actions.

So we have a mechanism called NSUserScriptTask that now fully supports this.

And the way this works is there's a folder in tilde Library called Application Scripts.

Under that folder, there's a subfolder for every app that wants to use this facility and any scripts that the user drags into this folder, the per app folder, that app is then allowed to ask the operating system to run with no Sandbox restrictions.

So the app can use API to reveal that folder and Finder and tell the user, if you want to be able to run any scripts, just drag them in this window.

Once that happens, those scripts can run uninhibited by the Sandbox.

So this is part of Foundation, the thing to look up in documentation is NSUserScriptTask.

It supports all of the scripting that you might care about so anything from just shell scripts to AppleScript and even Automator Workflows and there are ways to customize exactly how you want this to work.

There's no Entitlement required to use this, you can just simply use it.

Previously it was the case that iTunes maintained an XML file that, basically, described all the information about songs and other items in the user's media library.

And this is still the case, but if a Sandboxed app tried to parse this XML database, it would work fine unless the user had songs and other media outside of their normal media directories.

So if they went into iTunes and said I want to manage my own library and have songs on Network Volumes or different disks and so forth, then Sandbox apps, even though they could find the paths of the songs and the items they cared about, they couldn't follow them because the Sandbox would not allow it.

With iTunes 11, there's a great new framework called iTunesLibrary.framework that actually provides a great Objective C API that you can use to never have to parse a line of XML again.

You can simply ask it for contents of the user's media library.

You can ask it to gain access to those actual files on disk and what comes back from the API, just like with security scoped bookmarks, are security scoped URLs so you can say, I want to play this song, use the API to request access, you'll get the URL, you'll call startAccessing SecurityScopedResource on it and the file is made available within your Sandbox and you can behave like you always have towards that file, regardless of where it is on the file system.

To use the iTunes Library framework from a Sandboxed app, you need the normal music entitlements that have been around since App Sandbox launched.

As I'm sure most of you know, using App Sandbox is now a requirement in the Mac App Store.

And this has been, for the most part, very smooth.

Most of our developers have had no trouble adopting their apps just like I've shown you with very little time spent in Xcode and just finding the right entitlements to enable.

But, as we've been doing this for some time now, we've also picked up a bag of tips and tricks for things to check when you're submitting your app especially if it's for the first time.

And the first of those, and the most important one I'm going to point you to, is a document called "Technical Q&A QA1773."

So if you search for that, you'll find the whole document that actually lists a number of sort of common issues and tips and tricks for when you're submitting your apps to the Mac App Store and need to enable Sandboxing.

But I'm just going to point out a few of them that I think are the most common kinds of things that you might run in to.

So the first is this, when you're submitting your app and you know it must be Sanboxed, that's not just your main app binary, it's actually every executable file that you're submitting.

Now most apps actually just have their main binary, their main executable, but if you're including XPC services or if you're including helper tools that you run through things like NSTask, all of those must also be Sandboxed.

The entitlements you choose must match your app functionality.

Remember that there's a human reviewer that's looking at your app and if it's a timer app that just, you know, lets you set some timers and then they fire and some music plays and it's requesting an entitlement for access to the Address Book, that reviewer is going to say, well, what's going on here?

I see no way that this app needs access to the Address Book, why is the developer requesting this entitlement?

So that can add time to the review process and you'll have to explain why you're doing this.

In general, don't be tempted to enable entitlements that you don't need, really only enable the ones that your app clearly has need for.

And, hand-in-hand with that, I showed you the process of looking for Sandbox violations.

Now, not all Sandbox violations are bad.

And what I mean by that is, if there's no functional impact on your app whatsoever, if you're seeing a violation, everything in your app is working fine, that's fine, you don't have to do anything.

You don't have to go through the list of entitlements trying to, hoping that some random unrelated entitlement will make the Sandbox violation go away.

Because it might, but then, when it comes time to submit to the Mac App Store, it's going to be a raising eyebrows, why do you have this random, unrelated entitlement?

Just the fact that there are violations is not a problem.

It's only when the violations are causing functionality in your app that doesn't work, that's where you go and you try and figure out what entitlements you might be missing.

And so, on a very similar note, when you do request entitlements, try and make sure you understand exactly what they do and why you need them.

There are a few entitlements that lots of you are requesting that we can kind of figure out why, but it doesn't fully match the model so here's an example.

If your app needs to be able to open documents from a USB stick the user has plugged into the machine, you don't need any entitlements for that, right?

The Powerbox will just let you browse there like any other file and that's it.

No entitlements needed.

That would not be reason to specify the USB Device Access Entitlement because that entitlement actually lets you interface with custom USB devices that may be connected to the computer.

It has nothing to do with file access and USB sticks.

Similarly, if your app does any networking, it's really tempting to just check both of the network entitlement boxes.

The one that says, Inbound Connections and Outbound Connections.

But actually, the most, the vast majority of apps only needs to be able to make outbound network requests, meaning it only needs the client network entitlement.

Most of apps are not sitting and being network servers where they bind the port and wait for inbound connections.

That's not what most apps do so, if you're selecting the server networking entitlement, make sure you actually need it rather than just being something that sort of seems like you might need it.

Finally, we have this mechanism we call Temporary Exceptions which are a way to, in certain cases, where the Sandbox is prohibiting functionality for which we want the support, but currently don't have a good mechanism, there's a list of temporary exceptions that you may be able to request that would allow your app to continue working until a better mechanism is available.

And there's a few things I want to say about this.

The first is there's been some trepidation about the name, Temporary Exception, because it sounds like maybe it'll just stop working all of a sudden.

And, if you've distributed your app and a bunch of users have bought it, suddenly one day, maybe it just won't run anymore because the temporary exception has expired.

That's not how it works.

The Temporary Exception, if you are approved, the Temporary Exception, it'll continue working and it's simply that, at some point in the future, as a better mechanism becomes available, you may be asked to no longer submit new versions of the app to the App Store carrying that temporary exception.

But, you don't have to fear temporary exceptions.

Once you request them, once they're approved, they're going to keep working.

There's no issue about this breaking.

The second thing, and this is a really important one, is temporary exceptions are not a way to effectively disable the Sandbox.

So we've seen some very creative use of temporary exceptions including popular ones like asking, you know, for a temporary exception to script Finder and Terminal or for a temporary exception that allows access to slash and everything underneath which, basically, means the entire file system.

So remember, again, that when you do this, it's going to go in front of a human reviewer and they're going to be unhappy.

So these are not a mechanism to work around the Sandbox.

App Sandbox, ever since we introduced it, in Lion has been a strong barrier against exploitation and, even, against pathological coding errors.

It tries to drive security policy by user intent, instead of explicit security UI.

It's a technology for those of you who are looking at Gatekeeper and Developer ID that's complementary to Gatekeeper so you can, even if you're distributing your apps through Developer ID, you can use App Sandbox with it.

We have some really great documentation covering almost everything that I talked about today.

There's sample code where you can look at things like XPC and Sandboxing and XPC services.

But the real takeaway for me is this, probably almost all of you here are iOS users and iOS, as we announced, has asked 50 billion app downloads.

Every single one of those has run in the Sandbox and our users have loved that the carefree experience they have of trying new apps.

They never worry about what's going to happen to their phone, they never worry about, you know, what if it crashes and deletes all my things.

Those are simply not in the vocabulary of our iOS users because the Sandbox, from day one, has imposed strong restrictions on what apps can do.

And we would like to delight our users on OS X with the same carefree app experience.

Thank you.

[ Applause ]

Apple, Inc. AAPL
1 Infinite Loop Cupertino CA 95014 US