Update 22 Feb 2012: Apple have now extended the deadline to June 1st. Hopefully they’re realising the difficulties they’re creating for developers and will address some of the remaining concerns in this time.

On March 1st, Apple will change the rules of the Mac App Store to require all applications to run inside of a ‘sandbox’. Unfortunately, this will disallow important SourceTree functionality that was previously acceptable under store rules. Complying with the sandboxing rules would force us to change SourceTree in ways that would remove features, damage the usability of the app, and hurt our users; therefore, we will no longer submit SourceTree updates to the Mac App Store after March 1st, 2012. New updates will be available, for free, directly from sourcetreeapp.com (and via the in-app update). We will continue to monitor the situation in case Apple improve their sandboxing implementation or revise their rules. Note that we will still be signing SourceTree with our Apple developer certificate so SourceTree should work fine with the default settings of Mac OS X 10.8 Mountain Lion when it’s released.

For the full story of what forced us to take this disappointing decision, keep reading.

Background

From 1st March 2012, the Mac App Store will require all submitted applications to have application sandboxing enabled. Sandboxing runs the application in a controlled VM with little or no access to file, network or other resources unless they are specifically granted by the OS, which may be done by request of the application (if that’s provided), or via a privileged action dynamically granting permission, such as the Open File system dialog. The main aspects which impact SourceTree are as follows:

Sandboxed applications…

  1. only have automatic file access to their ‘Container’, which is a chroot-like setup for just that single application, with local versions of the user home directory, preferences folders, and so on
  2. can only access other file locations if the user gives explicit access via an ‘Open File’ dialog, a recently-used file list, the restoration of windows in Lion, or drag/drop
  3. cannot even necessarily have knowledge of the path to the ‘real’ user home directory, only to the container version
  4. cannot send Apple events to communicate with other applications

SourceTree impact

Sandboxing has a significant effect on SourceTree – the sandbox was designed mainly with a simple ‘document editing’ model in mind – ie that access to files would be granted by users explicitly opening them (thus granting explicit access via a user interaction, with the open file dialog being a privileged system component which cannot be altered by the application), and that the functional process is self-contained. However, not all applications work this way, SourceTree included.

Apple have notionally asked for developer feedback on this, and I and other developers have been raising ‘Radar’ issues on this for months. However, of the many issues I’ve raised since mid-2011, only a couple have been actually addressed (see the ‘Good News’ section below). The others sat in the queue for many months before finally receiving a dismissive ‘boilerplate’ response simply said ‘this is a known issue and we’re tracking it internally, please keep an eye on the release notes of future releases of OS X’. Obviously, this is not ideal. We’ve been hoping that this situation would be resolved before the deadline, but this is looking increasingly unlikely, and as such we feel it’s a good time to let you know what the position is for SourceTree.

Firstly, let’s talk about what the sandbox prevents us from doing in future.

File access issues

Users can’t type paths anymore

The only way that access can be granted to files & folders now is if the user browses to them, or drag/drops them. SourceTree currently offers the ability to type or copy/paste paths directly into text boxes, and also has the ability to derive sensible defaults which make the users life far easier.

For example, in the current direct-download version of SourceTree, if you drag/drop, paste or type a URL into SourceTree, it automatically derives a default clone destination for you (and bookmark name), based on the default project folder you’ve selected in your Preferences and the trailing part of the clone URL. This is really convenient and is often what you want – all you have to do is press ‘OK’.

Under the sandbox, you’re not allowed to default these values, nor can you allow the user to type a destination path into the text box. The user is forced to use the File Open panel, even if they would have been quite happy with a default, or have a path or prefix in their clipboard that they wanted to use. I know from experience that many users prefer this approach, but Apple’s sandbox says we have to take it away. In practice, this means redesigning the dialog because it feels very forced to do it this way. This is a total backwards step in UX in my opinion, but required by the model.

Losing File Access on Restart

Edit: literally just after this post was released, Apple officially added documentation for a new API to restore access to previously bookmarked file resources. They’re sure cutting it fine, less than 2 weeks before the sandbox becomes mandatory! This doesn’t change our decision yet, but if they continue to improve things we may be able to revisit this.

Under the sandbox, the file access an application was previously granted based on user behaviour is reset every time it starts up. Only documents that were open in document windows, and which are restored by Lion, are available automatically.

A key function of SourceTree is to keep track of all your repositories in one place, and to instantly show you what the status is. This works fine with the sandbox when you first add the repositories, but when you restart the application all that access is lost, unless the repositories were open in full document windows (on Lion). Clearly, because SourceTree allows users to bookmark an unlimited number of repositories, which the user doesn’t want to have permanently open in full document windows, this is not acceptable – chances are we’ll be denied access to 90% of repositories in the bookmarks at restart, making the bookmarks view – a major differentiating feature of SourceTree – completely useless.

Many other developers do this sort of thing in their applications, and this has been acknowledged by Apple in response to bug reports raised by myself and others, but has now disappeared into the impenetrable blackness of their internal tracking system. The consensus right now is that apps should claim the temporary exception to the file access rule, effectively asking for full permission to any file. I’ll talk about the implications of using temporary exceptions later on.

Home directory issues

Shared tool configuration will stop working

Currently when you use SourceTree, your SSH keys and agent configuration are automatically picked up, so access to remotes over SSH ‘just works’.

However, under the sandbox, the user home directory is ‘jailed’ inside the container, meaning that the standard SSH configuration is not available. All SSH access will fail unless the configuration is duplicated inside the container, and the SSH key loaded into the agent separately. Since the user home directory inside the container is only ever accessible when running SourceTree, none of the command-line tutorials for configuring SSH will work with SourceTree anymore, it will need its own, separate SSH configuration tool – another case of an unnecessary step being forced on the user.

You can’t even automate the initial process, say for example trying to copy the users existing setup (even though it would get out of sync if they changed it). This is because although a ‘migration’ option is made available for the sandbox, its only option is to move files into the container, it cannot copy them. So when I tried to use this for example, SSH configuration would work properly in SourceTree but it had deleted the original files in the real user home directory, something that would be extremely unpopular (understatement!).

The only real option is to force the user to import their keys. Helping them out with this is a bit tricky in itself, since all the standard Cocoa calls like NSHomeDirectory() point at the container, so we don’t know from there what their real home directory is, although some lower-level system calls seem to (currently) still expose this – I suspect this may be an oversight that will be corrected later.

The same issues exist with Mercurial, Git and Subversion. Configuration that the user has already performed won’t be automatically brought across, we’d have to prompt the user to configure everything manually, regardless of whether they’ve already configured the command line.

The short of it is that we can work around this, but the experience for the user is clunkier because they need to get involved more directly, and if they change their central configuration later they have to sync it up manually. The bottom line is that competing products that aren’t in the Mac App Store will give a better experience – if a user asks ‘how come <insert other DVCS client not on the Mac App Store> just picks up my configuration automatically but SourceTree doesn’t?’ – and I have no good answer to that other than ‘Apple made me do it’.

Apple Event Issues

Integration with Terminal etc prohibited

Sandboxed applications aren’t allowed to send Apple Events – this is because by doing so they could perform actions that they themselves are not permitted to do. However since Apple Events are the primary way to provide application integration – it’s how SourceTree launches Terminal / iTerm and navigates to the project folder for example – disallowing it removes some very useful functionality.

Right now, you can ask for a temporary exception for specified applications so there is a workaround. However, see the section later on regarding the implications of using temporary exceptions.

I have raised a bug with Apple to ask them to consider prompting the user to give permission for sending Apple Events between apps, in the same way that access to the Keychain is granted. Again, this has been closed as ‘yeah we know’, with no indication of whether it will actually be resolved or not.

Miscellaneous Issues

‘Open With’ is no longer allowed

When editing some files, such as the git/hg config files, SourceTree explicitly opens them with TextEdit rather than allowing the users file association. This is because I discovered that many users had weird associations on these files (presumably because they have no extension), so they might be opened in a Terminal instead for example.

Under the sandbox, you cannot ‘Open With’ anymore, it’s disallowed. You can only open files with their associated editor. This has other implications over and above the config files, it also means I can’t implement an explicit ‘Open With’ feature on the file list, which has been requested by users in the past.

Transfer of settings / licenses between App Store & Direct versions will fail

Currently if you downloaded SourceTree from the App Store, the license applies to the direct version and your settings are automatically kept in sync between the two, meaning it’s seamless to go back and forth between them. This is very useful if an App Store user wants to try out a beta version, or in the case where a hotfix is required.

Sandboxing does not allow this because access to the settings outside the container is prohibited. If a user tried to switch between the two systems, the settings/bookmarks would have to be recreated and they’d need to apply for a license separately. Not a major issue but it just feels a little shoddy.

First run of sandboxed application deletes previous configuration

The first time a user runs the sandboxed version from the app store, all the preferences are moved into the container and deleted from their original locations. This means the user can never go back to a previous build. Probably not serious, but worth noting.

Implications of Using Temporary Exceptions

Some of the above issues can be temporarily avoided by using exceptions that Apple make available – these are declarative entries in the applications property list which open up the sandbox more than the default. While this overcomes some issues in the short term, it has the following issues:

  1. They don’t address the core issue, they just avoid it.
  2. Apple have explicitly said they will take these exceptions away at some undefined point in the future. Whether they will create fully-fledged techniques to address the issue the exception was used to overcome, and whether those techniques will be appropriate or not, is a complete unknown.
  3. Using the exceptions has to be justified at every application review. If you use an exception, the reviewers will pick it out and judge whether your rationale for defying the sandbox model is justified. In my experience, reviewers are not very consistent and I’ve had to lodge appeals several times (all successful luckily) because a reviewer has decided that a behaviour that has been approved in the past is now unacceptable. We can probably expect some delays and some conflict over our use of sandbox exceptions.

Therefore, even if we can ‘get by’ with the exceptions, having made all the sacrifices in usability terms as well, we may still find ourselves having difficulty getting updates through the App Store, and the landscape will continue to evolve.

Good news

Despite most of the issues I’ve raised with the sandboxing being closed without any satisfactory resolution, I did have one issue resolved that was a major problem for me – previously the sandbox would block termination of processes, even those that you’d launched from your application. This was a major problem for people clicking ‘Cancel’ in a clone window, because you couldn’t interrupt the clone task and it would continue running forever. Luckily, this has been fixed in 10.7.3.

Conclusion

Fundamentally, sandboxing is a good idea. Asking applications to be specific about what they need to do, and exposing that to the system and users for validation is a good idea for security.

The trouble is, the sandboxing implementation currently in place on Mac OS X Lion doesn’t allow for all the behaviours that real Mac applications do right now, behaviours which are not at all contentious, are approved in the Mac App Store already, and indeed are very much appreciated by users. Applications designed a certain way (mainly, those which edit documents on demand and don’t do much else) won’t have a problem since their behaviours are adequately catered for in the rights that can be applied for, but tools which perform more complex behaviour, particularly when that involves integrating with other apps and tools, do many things that simply aren’t catalogued in the sandbox. Also, forcing users to use a browse dialog for absolutely every file path is extremely clunky outside of the simplistic single document  editing use case – it might provide a nice way for the sandbox to grant file permission, but from a UX perspective it’s incredibly constraining.

Being on the Mac App Store has always required a bit of extra effort and some inconvenience for developers, but it’s been worth it – the Mac App Store is a great distribution platform which users love, and any difficulty and inconvenience with the platform has been limited to us, the developers, barring making people wait a bit longer for updates. To comply with the sandbox as it’s currently specified, however, requires making SourceTree a worse experience for users – there are some temporary exceptions which mitigate this to a degree, but they’re still incomplete and liable to be taken away, with no indication of what the replacement might be (if anything).

We’ve agonised over this decision for months, but the bottom line is that the current sandboxing implementation is simply not compatible with a version of SourceTree that we’d be happy to release. We care a great deal about the experience our users have, and being forced to release what would be, in our view, a downgrade of the app is just not something we want to do.  For this reason, we are not currently planning on submitting any more updates to the Mac App Store after 1st March. Our understanding is that the latest version at that time will remain in the Mac App Store for people who still wish to use it, but beyond that updates will be made only through direct download from the website, at least until something changes.

Our sincere hope is that Apple will address the shortcomings of the sandboxing implementation in the future, and allow us to request the kind of behaviours we need to maintain the features that SourceTree users know & love. Above all, we’d love Apple to talk to developers more openly about this, and give clearer guidance on how these issues are going to be dealt with.  Judging by talk in the community, we’re far from the only developers wrestling with these kinds of problems.

Related reading: