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.

rgeorge
  • 7,385
  • 2
  • 31
  • 41

3 Answers3

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.

neilco
  • 7,964
  • 2
  • 36
  • 41
  • 6
    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. – Martijn Thé Dec 16 '13 at 20:06
  • 1
    @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. – neilco Dec 16 '13 at 21:20
  • 6
    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. – Mike Vosseller Aug 27 '14 at 20:22
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);
Elist
  • 5,313
  • 3
  • 35
  • 73
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
Nam Vu
  • 5,669
  • 7
  • 58
  • 90
  • 5
    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. – levigroker Sep 21 '18 at 17:01
  • Who needs run-time; one may simply need Merchant-ID and similar (which are forced to be listed in Entitlements file). – Top-Master Jun 19 '23 at 11:10
  • However, adding to copy bundle produces a warning, hence, use following approach instead: https://stackoverflow.com/a/56044915/8740349 – Top-Master Jun 19 '23 at 11:13