Add deploy script that packages into a signed .app bundle - #4
Open
nanderss wants to merge 1 commit into
Open
Conversation
TCC will not honour an Accessibility grant for the bare Mach-O binary the README installs, so key: actions silently do nothing no matter how many times the permission is granted. Two compounding causes: 1. swift build leaves the binary linker-signed (flags 0x20002), which TCC treats differently from a real ad-hoc signature. 2. Even after codesign --force --sign -, the grant is still ignored. codesign reports the install directory as Format=bundle because of the adjacent Info.plist, but there is no bundle structure behind it and the plist is "not bound" into the signature, so there is no stable identity for TCC to pin a grant to. Running from a real .app bundle fixes it: Format=app bundle, Info.plist sealed into the signature, real CFBundleIdentifier, LaunchAgent pointed at Contents/MacOS/StreamDeckController. Sign with a certificate rather than ad-hoc. An ad-hoc designated requirement is a bare cdhash, so every rebuild is a new identity and voids the grant; a certificate makes the requirement identifier + certificate leaf, independent of the binary's contents. Verified by rebuilding: cdhash changed from 30e7b6c9 to 5f4281b6 with the grant still in effect. Fail if the identity is missing rather than falling back to ad-hoc, since the fallback appears to work and breaks key: actions later with no error in the log. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
nanderss
force-pushed
the
deploy-signed-app-bundle
branch
from
August 18, 2026 04:58
967485e to
648fba4
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
macOS TCC would not honour an Accessibility grant for the bare Mach-O binary the README installs, so
key:actions silently did nothing no matter how many times the permission was granted.Two compounding causes:
swift buildleaves the binary linker-signed (flags=0x20002(adhoc,linker-signed)), which TCC treats differently from a real ad-hoc signature.codesign --force --sign -, the grant was still ignored.codesignreports the install directory asFormat=bundlebecause of the adjacentInfo.plist, but there's no bundle structure behind it and the plist isnot boundinto the signature — so there's no stable identity for TCC to pin a grant to.Running from a real
.appbundle fixed it —Format=app bundle,Info.plist entries=11sealed into the signature, realCFBundleIdentifier, LaunchAgent pointed atContents/MacOS/StreamDeckController. That's the identity shape the Accessibility list is built around, and it's also what users are used to dragging in.Signing identity
The script signs with a certificate rather than ad-hoc, which matters more than it first appears.
An ad-hoc signature's designated requirement is a bare cdhash:
So every rebuild is a new identity and silently voids the Accessibility grant — the app has to be removed and re-added in System Settings after each deploy, and until you do,
key:actions fail with nothing in the log. Signing with a self-signed code-signing certificate gives:which is independent of the binary's contents. Verified by rebuilding: cdhash changed from
30e7b6c9to5f4281b6and the grant remained in effect, withkey:cmd+spaceand a held modifier chord both still working.The script fails if the identity is missing rather than falling back to ad-hoc, because that fallback appears to work and then breaks
key:actions later.Notes
Setting up the certificate is a one-time manual step (Keychain Access → Certificate Assistant, or
openssl+security add-trusted-cert -p codeSign), so it isn't scripted here — the script only checks the identity exists. Happy to add a short README section covering it.This does change the deployment approach in the README (steps 4–6), so it needs a docs update to match — glad to add that here or send it separately, whichever you prefer. Also happy to drop the script and just document the bundle layout if you'd rather not carry a deploy script in the repo; the
.appand the non-ad-hoc signature are the parts that actually matter.Tested on an AJAZZ AKP03, macOS 26.5, Apple Silicon.