ShazamKit under the App Sandbox on macOS — sanctioned way to reach com.apple.shazamd? (error 202)

I'm building a music-recognition app for the Mac App Store that uses ShazamKit (SHSession / SHManagedSession) against the default Shazam catalog. In a sandboxed build, SHSession.match(_:) fails with:

com.apple.ShazamKit error 202 — "The connection to service named com.apple.shazamd was invalidated"

The root cause is a sandbox denial of the mach-lookup to the ShazamKit matching daemon:

kernel (Sandbox): deny(1) mach-lookup com.apple.shazamd

What I've established:

  1. Enabling the ShazamKit App Service on the App ID does not add com.apple.shazamd to the sandbox mach-lookup allow-list on macOS — the denial persists and matching returns error 202.

  2. The iOS entitlement com.apple.developer.shazamkit is rejected by the macOS validator at upload ("not supported on macOS"), so it isn't an option here.

  3. Adding com.apple.security.temporary-exception.mach-lookup.global-name = [com.apple.shazamd] to the app's entitlements removes the denial, and ShazamKit then matches correctly under the sandbox (verified end-to-end: real api.shazam.apple.com/v1/catalog/.../match requests complete and tracks are identified). Removing that exception reproduces error 202 on every probe.

So the temporary-exception appears to be the only way to make ShazamKit's default-catalog matching work inside the macOS App Sandbox today.

Questions:

  1. Is there a sanctioned, non-temporary-exception way to use ShazamKit default-catalog matching in a sandboxed macOS app (a proper entitlement, an App Service configuration, or a supported API usage)? If not, is the com.apple.shazamd mach-lookup temporary-exception the intended approach on macOS?

  2. My actual SHSession.match runs in a nested helper that inherits the app's sandbox (com.apple.security.inherit). Is it correct to place the exception on the main app (which the inherited helper then picks up), rather than on the helper itself?

Environment: macOS 26.1, ShazamKit App Service enabled on the App ID, signed App Sandbox build installed via TestFlight (valid _MASReceipt present). Happy to share entitlement plists and a focused sample on request. Thanks!

Answered by DTS Engineer in 896952022
I ran a set of controls to answer your question

Nice!

I’m not 100% sure why this is failing, but I want to explain a little bit about how App Sandbox works, so that you can understand why I’m asking my next question.

When it comes to Mach service lookup, App Sandbox applies a clever trick to ensure that your app can only access its expected services. Let’s look at ShazamKit as example of this. Normally an app can’t access the com.apple.shazamd Mach service because the App Sandbox blocks such lookups by default. However, if the app links to the ShazamKit framework, App Sandbox extends its sandbox to allow that lookup.

Your tests indicate that this extension isn’t working for a spawn subprocess. Before I send you off to file a bug, I’d like to confirm one thing. You wrote:

2- The same binary … spawned as a child of that same sandboxed parent …

So, just to be clear, this executable includes a static import of ShazamKit. That is, if your run this command over the executable:

% otool -L /path/to/your/executable

then ShazamKit shows up as an imported framework. Right?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

The iOS entitlement com.apple.developer.shazamkit is rejected by the macOS validator at upload

My undestanding is that this entitlement isn’t valid on iOS either. See here.

Is it correct to place the exception on the main app … rather than on the helper itself?

That depends on how you run the helper. If you spawn it as a child process then it inherits your app’s static sandbox and thus adding entitlement to the parent app is the right choice.

As to your main issue, am I right in assuming that this nested helper stuff isn’t a factor there? That is, the behaviour you’ve described applies regardless whether you run the code in your helper or in your main app?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks for the reply, Quinn — and good instinct: the helper turns out to be exactly the factor. I ran a set of controls to answer your question, and I have to correct my original post in the process.

Same machine (macOS 26.1 / 25B78), same binary, same Apple Development signing:

  1. When the sandboxed app calls SHSession.match directly (entitlements: just com.apple.security.app-sandbox + com.apple.security.network.client — no exception, no ShazamKit-related entitlement at all), it matches successfully. No shazamd denial. So point 1 of my original post was wrong: a directly-sandboxed process can reach com.apple.shazamd out of the box.
  2. The same binary signed app-sandbox + com.apple.security.inherit and spawned as a child of that same sandboxed parent (parent has no exception) fails with error 202 ("connection to com.apple.shazamd was invalidated"). Same result one level deeper (parent → inherit child → inherit grandchild, which is my production shape).
  3. The same nested chain with com.apple.security.temporary-exception.mach-lookup.global-name = [com.apple.shazamd] on the parent matches fine.

So: ShazamKit works under the sandbox in the main process with no special entitlements, but a com.apple.security.inherit child loses access to com.apple.shazamd unless the parent carries the temporary-exception.

What should I do here? Is this expected behaviour for inherit children — and if so, is the parent-level temporary-exception the supported way to use ShazamKit from a spawned helper (my architecture needs the match to run in one)? Or is this a gap in how the ShazamKit allowance is granted, in which case I'm happy to file a Feedback with the reproduction (it's a ~40-line fork/exec launcher plus the entitlement plists) and keep using the exception in the meantime — whichever you advise.

Accepted Answer
I ran a set of controls to answer your question

Nice!

I’m not 100% sure why this is failing, but I want to explain a little bit about how App Sandbox works, so that you can understand why I’m asking my next question.

When it comes to Mach service lookup, App Sandbox applies a clever trick to ensure that your app can only access its expected services. Let’s look at ShazamKit as example of this. Normally an app can’t access the com.apple.shazamd Mach service because the App Sandbox blocks such lookups by default. However, if the app links to the ShazamKit framework, App Sandbox extends its sandbox to allow that lookup.

Your tests indicate that this extension isn’t working for a spawn subprocess. Before I send you off to file a bug, I’d like to confirm one thing. You wrote:

2- The same binary … spawned as a child of that same sandboxed parent …

So, just to be clear, this executable includes a static import of ShazamKit. That is, if your run this command over the executable:

% otool -L /path/to/your/executable

then ShazamKit shows up as an imported framework. Right?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks Quinn — your explanation of the framework-linkage trick was exactly the pointer we needed. To answer your question first: no, ShazamKit didn't appear in otool -L on that executable — it's an Xcode Debug build, so the executable only imports the debug-dylib stub, and ShazamKit is imported one hop down by that dylib.

That prompted two more controls, and they solved it:

  1. Rebuilding the helper with a direct static ShazamKit import (confirmed via otool -L) and spawning it as an inherit child: still error 202, same shazamd deny. The child's own linkage doesn't matter.
  2. Linking ShazamKit into the parent executable instead (a tiny sandboxed fork/exec launcher, no exception anywhere): the unmodified inherit child now matches — including through two levels of nesting.

So the sandbox extension appears to be derived from the profile owner's linkage and flows down to inherit children. That explains my app exactly: my main executable never linked ShazamKit (only the spawned helper does), hence the denial, hence the temporary-exception having been load-bearing.

My path forward is clear — link ShazamKit in the main app and drop the temporary-exception. Thanks for steering me to the mechanism; I wouldn't have found it without that hint. One last thing, purely for completeness: if "a child's own static import doesn't extend an inherited sandbox" is something you'd consider a gap rather than intended behaviour, say the word and I'll file Feedback with the reproduction — otherwise I'm all set.

it's an Xcode Debug build, so the executable only imports the debug-dylib stub

Oh, that’s an interesting wrinkle!

if "a child's own static import doesn't extend an inherited sandbox" is something you'd consider a gap rather than intended behaviour

I can see arguments either way. But I think you should file a bug about it so that the sandbox engineering team can have a proper think about this case.

Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

ShazamKit under the App Sandbox on macOS — sanctioned way to reach com.apple.shazamd? (error 202)
 
 
Q