Are user-initiated changes to entitlements supported?

Is it possible to provide a sandboxed application with minimal permissions by default, but extend these with additional permissions that enable extended functionality when the user chooses and confirms this?


More specifically, I would like to give a file-utility application file-read permissions by default. However, I would like the application to obtain additional write-permissions when the user wants this. For example, the user could initiate such a change from the application's user preferences, e.g. by ticking the application-specific "Enable file deletion" option. The application would then forward this request to the OS, which lets the user confirm this, e.g. via a confirmation dialog "Do you want to grant file write-access to the 'FooFileUtility' application?". When the user confirms, the OS adapts the entitlements accordingly, and the application can offer the user the requested delete functionality.


Context: I am developer of a file-utility application whose main function is to give the user a visual overview of the disk usage. For this the application requires read access. Optionally, the application allows the user to delete selected files and folders to free up space, which requires write access. Managing deletion via the application has several advantages to the user. It's convenient for the user and enables the application to track and show how much space has been freed up while the user is cleaning up. However, granting write-access is obviously a potential security risk, so not all users may want this.

Replies

More specifically, I would like to give a file-utility application file-read permissions by default. However, I would like the application to obtain additional write-permissions when the user wants this. For example, the user could initiate such a change from the application's user preferences, e.g. by ticking the application-specific "Enable file deletion" option.

The current sandbox architecture does not support anything like this. As always, if you'd like to see such support added in the future, I encourage you to file an enhancement request describing your requirements.

Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for your reply. It confirms what I thought, but I thought I'd double check. I have submitted an enhancement request: 26032724


This gives me a follow-up question. Is there an API to let an application dynamically query what its entitlements are? I could use this to distribute two versions of the app, one with only read-access, another with additional write-permissions. The only difference would be the contents of the entitlements file. The rest of the app would be fully identical. The app would simply query the entitlements to determine if the functionalty requiring write-permissions can be enabled.


Or if there is no such API, how to best support these two variants? Is there a common pattern for this? Should I try reading the entitlements file, or should I create two different build targets and introduce a custom define to control the optional functionality, or...?

Is there an API to let an application dynamically query what its entitlements are?

You can get your entitlements using the code signing API. Something like this:

OSStatus        err;
SecCodeRef      me;
CFDictionaryRef dynamicInfo;

err = SecCodeCopySelf(kSecCSDefaultFlags, &me);
assert(err == errSecSuccess);

err = SecCodeCopySigningInformation(me, (SecCSFlags) kSecCSDynamicInformation, &dynamicInfo);
assert(err == errSecSuccess);

NSLog(@"%@", CFDictionaryGetValue(dynamicInfo, kSecCodeInfoEntitlementsDict));

WARNING This code was copied from a test project. If you want to do this in a production app you should modify the code accordingly. For example:

  • you’ll need to do the right thing with memory management

  • asserting that you get no errors would be unwise

To handle this last point I recommend you think clearly about how your high-level code should fail safely if you get an error from this low-level code.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for providing this pointer and sample code. I will shortly give it a try. It's also clear that this code is not production-ready so I will make sure to make the necessary changes.