Can an iOS app read its own entitlements at runtime?
Asked Answered
M

3

32

Can an iOS app discover, inspect, or otherwise read its own entitlements at runtime?

Ideally, I could read the whole (processed) contents of my .entitlements file as a plist. Getting just the app identifier prefix would be an acceptable second-best.

Goals here include: allowing the app to be signed with various app identifier prefixes, without needing to make a matching change in code; and to act differently in the presence or absence of shared keychain access groups. This is library code, so the less I impose on the client app's configuration, the better.

Marcimarcia answered 23/9, 2013 at 22:41 Comment(5)
Is this what you are looking for? [[NSBundle mainBundle] bundleIdentifier]Globetrotter
@rgeorge. did you find the right answer of your question?Public
Nope! The closest answer involves copying the build .entitlements file, which doesn't capture the actual entitlements compiled into the executable, which is what I really needed. A radar is long since filed but I'm not holding my breath.Marcimarcia
did you find any solution @MarcimarciaJardena
You might be interested in SecTaskLoadEntitlementsAtp
N
9

In short, no. The entitlements file is only used at compile-time and is not copied into the app bundle.

Clarification: During development, the entitlements are written into the embedded.mobileprovision file in the app bundle. When your app is released as an IPA on the App Store, it will not contain a embedded.mobileprovision.

Navicular answered 24/9, 2013 at 11:40 Comment(3)
Is this true? I think codesign bakes them into the app's executable. When you do codesign -d --entitlements :- MyApp.app it will display the embedded entitlements.Savino
@MartijnThé That's because you're running it on the desktop, so it's not at runtime like the question asked. During development, the entitlements are written into the embedded.mobileprovision file in the app bundle. When your app is released as an IPA in the App Store, it will not contain a embedded.mobileprovision. You can check this yourself. Just open any IPA you find in your iTunes folder using the Archive Utility, go the Payload folder, Show Package Contents on the app bundle and inspect its contents.Navicular
I think the codesign tool looks at the binary file and not the embedded.mobileprovision. 1) If you remove the embedded.mobileprovision file codesign still works 2) If you run codesign against a build downloaded from the App Store it still works 3) if you look in the binary file you can find the entitlements. With it in the binary I sure wish there was a way to access it at runtime too.Briar
G
5

As others mentioned in comments, the signed executable of your app contains an embedded entitlements plist, which suggests it should be possible.

You will need to use some non-ios-public (but documented) APIs. Try the following code:

// Declare the private SecTask functions in your header file
void* (SecTaskCopyValueForEntitlement)(void* task, CFStringRef entitlement, CFErrorRef  _Nullable *error);
void* (SecTaskCreateFromSelf)(CFAllocatorRef allocator);


// And call it in your code like this:
CFErrorRef err = nil;
NSArray* groups = SecTaskCopyValueForEntitlement(SecTaskCreateFromSelf(NULL), CFSTR("com.apple.security.application-groups"), &err);
Germanophile answered 19/11, 2018 at 15:38 Comment(2)
They're documented for OSX, not for iOS. If you use them your app gets rejected.Crump
I needed to change the NSArray * to CFTypeRef in order for it to work...Flyblown
H
4

AFAIK, you can do it. For example, In order to read YourFileName.entitlements and get AppGroup ID, please follow below steps:

Step 1: Add your .entitlements to your target by "Copy Bundle Resources"

Step 2: Using below source code:

NSString *path = [[NSBundle mainBundle] pathForResource:@"YourFileName"
                                                 ofType:@"entitlements"];
NSDictionary *dict = [[NSDictionary alloc]initWithContentsOfFile:path];
NSString *suiteName =  [[dict objectForKey:@"com.apple.security.application-groups"] firstObject]; // It's your data
Halfdan answered 23/8, 2016 at 10:27 Comment(3)
This isn't really valid... you're copying the entitlements file into your application bundle, but it may not reflect the actual entitlements of your application at runtime.Wanigan
Who needs run-time; one may simply need Merchant-ID and similar (which are forced to be listed in Entitlements file).Avowal
However, adding to copy bundle produces a warning, hence, use following approach instead: https://mcmap.net/q/470112/-is-it-possible-to-read-entitlements-files-in-swiftAvowal

© 2022 - 2024 — McMap. All rights reserved.