SecTrustedApplicationCreateFromPath returns errSecCoreFoundationUnknown depending on app path

Hello,


I'm facing a particularly weird issue where I'm trying to share access to a keychain item for two of my apps. More precisely my app includes a helper app that creates a keychain item it wants to share with the main app.


I've boiled it down to the call to SecTrustedApplicationCreateFromPath(appPath, &trustedAppRef);


If my app (and helper app) are running from the DerivedData folder (when I'm running in Xcode) this call will return errSecCoreFoundationUnknown (-4960) but If I move the app to be inside "/Applications/" everything works correctly. If I move the app to "/User/<username>/Applications/" it fails again with errSecCoreFoundationUnknown...


I tried creating another executable to test this with just the following code:


int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSURL *appURL = [NSURL fileURLWithPath:@"/Users/dev/Applications/Secrets.app"];
        SecTrustedApplicationRef trustedAppRef = NULL;
        char pathBuffer[MAXPATHLEN];
        char *finalPath = NULL;
        if( CFURLGetFileSystemRepresentation((__bridge CFURLRef)appURL, TRUE, (UInt8 *)pathBuffer, sizeof(pathBuffer)) ){
            finalPath = pathBuffer;
        }
        OSStatus status = SecTrustedApplicationCreateFromPath(finalPath, &trustedAppRef);
        
        NSLog(@"%d", status);
    }
    return 0;
}

And it works irrespective of where the app is located...


So why is it that my helper app cannot create a SecTrustedApplicationRef when passed a path outside of "/Applications/"?


Thanks,

Paulo

Accepted Reply

Is the code making this call sandboxed? The normal reason why folks see this issue is that

SecTrustedApplicationCreateFromPath
actually needs access to the supplied path, and the App Sandbox prevents that. This isn’t a problem for most users, who tend to install apps in
/Applications/
, but is a pain during development.

A good way around this is to use the iOS-style keychain and hence share items via a keychain access group. This works best for App Store apps, which is OK because most sandboxed apps are App Store apps.

Share and Enjoy

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

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

Replies

Is the code making this call sandboxed? The normal reason why folks see this issue is that

SecTrustedApplicationCreateFromPath
actually needs access to the supplied path, and the App Sandbox prevents that. This isn’t a problem for most users, who tend to install apps in
/Applications/
, but is a pain during development.

A good way around this is to use the iOS-style keychain and hence share items via a keychain access group. This works best for App Store apps, which is OK because most sandboxed apps are App Store apps.

Share and Enjoy

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

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

Hello Quinn,


Indeed the apps (main and helper) are sandboxed. You may be right indeed. The container always succeeds when it creates a SecTrustedApplicationRef for the contained (helper) app, but not the other way around, which corroborates your theory.


Regarding the keychain access group I'd love to that since it would make my code much simpler but my understanding is that, on the Mac, this requires kSecAttrSynchronizable to be true. Which for the keychain items I'm creating doesn't make sense, they should be local only. I've actually tried passing false to kSecAttrSynchronizable to see if I could get the iOS access groups but no dice.


I'd really prefer the helper app be able to create these keychain items instead of the main app. I wonded if passing a security scoped bookmark to the helper app would allow me to get around this?

I wonded if passing a security scoped bookmark to the helper app would allow me to get around this?

While I can’t guarantee that it won’t work, I don’t think it’s a good idea. It seems like a step in the wrong direction to me.

this requires

kSecAttrSynchronizable
to be true.

Correct.

Which for the keychain items I'm creating doesn't make sense, they should be local only.

What type of keychain items are we talking about here? Password items? Or other credentials, like digital identities?

Share and Enjoy

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

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

The items I'm storing are shared keys to authenticate these apps, they are generated locally and only used locally. I did not actually try to go the bookmark route, I thought of another solution.


I already had an item in the keychain with the ACL I wanted (created by the main app). The helper app can simply copy that ACL when creating its items. That appears to be working just fine.

The helper app can simply copy that ACL when creating its items.

Oh, that’s sneaky. Now that you mention it it’s obvious that you can copy an ACL, but I would have never thought of it.

Share and Enjoy

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

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