BLACK LABELAcademy
← Our Failures

Adhoc cdhash-only signing orphans TCC/entitlement grants on every rebuild and SIGKILLs sandboxed apps

advanced6 min read · updated 2026-06-20

Market & numbers — every figure sourced

tcc_regrants_per_rebuild1 permission prompt per protected resource per rebuildest: Observed behavior: each adhoc rebuild produces a new code identity, so every TCC-protected resource (mic, screen, camera) re-prompts once on next launch
voice_supervisor_restarts_per_day22 restarts/dayest: Internal Black Label voice supervisor log count on a day when adhoc rebuild orphaned the microphone TCC grant, causing a deaf-loop restart storm

Adhoc cdhash-only signing orphans TCC/entitlement grants on every rebuild and SIGKILLs sandboxed apps

This is one of the most expensive failure modes we hit shipping native macOS apps: a fix that was correct in source did nothing live, and an app that ran yesterday got instantly killed today. Both traced back to the same root cause: ad hoc code signing has no stable identity, and macOS uses that identity to remember who you are.

What we tried

We built five SwiftUI apps and a voice supervisor, signing every rebuild ad hoc (`codesign -s -`). Ad hoc signing uses no certificate — it only stamps the binary's code directory hash (cdhash) and identifies exactly one instance of that code "identifies exactly one instance of code". That was convenient: no Apple account, no provisioning, instant local builds. We assumed a rebuilt app was "the same app" as far as macOS was concerned.

It is not.

What broke

1. TCC grants orphaned on every rebuild. macOS tracks code identity using the code's designated requirement (DR). Ad hoc signed code carries no stable DR, so the system cannot tell that version N+1 is the same code as version N "macOS is unable to tell that version N+1 ... is the same code as version N". Every rebuild changed the cdhash, every cdhash looked like a brand-new app, and so every TCC-protected permission (microphone, screen recording, camera, accessibility) had to be re-granted. Our "hey ace" voice loop went deaf after a rebuild because the freshly-built binary no longer matched the microphone grant tied to the old cdhash. The supervisor saw silence, declared the loop dead, and restarted it — roughly 22 times in a day. The source code was perfect. The signature wasn't.

2. Entitlement grants and Keychain access scoped to the old identity also evaporated for the same reason — anything macOS keyed to "this exact app" was keyed to a cdhash we threw away on the next build.

3. Adhoc + app-sandbox = SIGKILL on launch. When we added `com.apple.security.app-sandbox` to an app and signed it ad hoc, the app was killed instantly on launch with `EXC_CRASH (SIGKILL (Code Signature Invalid))` and no usable crash report — the kernel rejected the code signature against the sandbox requirement before `main()` ran "Code Signature Invalid". Same story with a non-native `applesignin` entitlement on an adhoc build: immediate SIGKILL. The Apple "Sign in with Apple" button looked free; it was a landmine.

The fix

Three rules, all of which we now enforce:

Apply it

Sources

© 2026 Black Label · Education, not financial or legal advice. Every number is sourced or labeled an estimate. Subscribe for $30/month