Thanks for all the clarifications.
MusicKit isn’t really my thing but, based on that log message, it seems that MusicKit requires that code be signed with the com.apple.application-identifier
entitlement. This is not common, but it’s also not super rare. The presence of that entitlement allows Apple to securely identify the code calling the API.
On iOS this isn’t an issue. Third-party code on iOS is always an app [1] and the application-identifier
entitlement [2] is required to match your app up with a provisioning profile which authorises its execution. For more background on that process, see TN3125 Inside Code Signing: Provisioning Profiles.
This is more of a challenge on macOS which, for historical reasons, allows you to run third-party code without a profile [3]. The com.apple.application-identifier
entitlement is a restricted entitlement (per the definition in TN3125) and must be authorised by a profile. This presents two problems:
-
You have to create the profile and apply the profile to your code.
-
You’re building a command-line tool, which has no place to store a profile.
The standard workaround for problem 2 is to place your command-line tool in an app-like wrapper. For the details, see Signing a Daemon with a Restricted Entitlement. Note that this article is focused on daemons but the some logic applies to command-line tools.
As discussed in that article, a good way to get started with this is to create an app target rather than command-line tool target. If you do that, Xcode’s automatic code signing will take care of problem 1.
Once you’ve set this up, you’ll have a structure like this:
ToolInAppsClothing.app/
Contents/
Info.plist
MacOS/
ToolInAppsClothing
PkgInfo
_CodeSignature/
CodeResources
embedded.provisionprofile
In Terminal the user will have to run the tool like so:
% ToolInAppsClothing.app/Contents/MacOS/ToolInAppsClothing
That’s obviously a hassle, so the standard practice is for either you or the user to create a symlink to the executable that the user can run directly.
if this is necessary to work, an *.app that install command line tool
To be clear, if you package this within an app you will need a nested bundle:
Container.app
Contents/
Info.plist
MacOS/
Container
ToolInAppsClothing.app/
Contents/
Info.plist
MacOS/
ToolInAppsClothing
embedded.provisionprofile
embedded.provisionprofile [optional]
Resources/
… other stuff …
The container app may or may not have a profile, depending on whether it uses any restricted entitlements. The tool app must have a profile, and it must be placed within the tool app’s bundle. The tool app cannot piggyback on top of the container app’s profile. From the trusted execution system’s perspective, these are two separate apps.
Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
[1] Or an app-like thing, like an appex.
[2] Note that iOS and its child platforms use application-identifier
while macOS uses com.apple.application-identifier
[3] Hell, on Intel you can still run third-party code that’s not signed!