Skip to content

Commit 36e30a2

Browse files
pseudobunclaude
andauthored
fix(macos): drop iOS-shaped aps-environment from signed entitlements (#19)
## Summary v1.3.1 is dead on arrival: every launch SIGKILLs with \`Termination Reason: Namespace CODESIGNING, Code 1, Taskgated Invalid Signature\`. Diagnosed via side-by-side of the shipped binary's signed entitlements vs. its embedded provisioning profile: | Signed in v1.3.1 binary | Authorized by profile | |---|---| | \`aps-environment: production\` | **NOT PRESENT** | | \`com.apple.developer.aps-environment: production\` | ✅ present | The bare \`aps-environment\` key is the iOS convention. macOS uses only the \`com.apple.developer.*\` namespace for developer entitlements, and the Developer ID provisioning profile authorizes \`com.apple.developer.aps-environment\` but not the bare iOS-shaped key. amfi enforces "every restricted entitlement must be profile-backed" at load time, so the bare key — which #17 started adding alongside the correct one — causes amfi to SIGKILL the binary on exec. \`codesign --verify --strict\` in CI didn't catch this because it only validates structural integrity, not profile subset. That's amfi's job and it only runs at load time on the end-user's machine. ## Changes **\`.github/workflows/release.yml\`** — in the \`Prepare sanitized entitlements\` step, **delete** the bare \`aps-environment\` key on macOS releases instead of substituting it. Keep the \`Set :com.apple.developer.aps-environment production\` line — that's the macOS runtime key for CloudKit silent push delivery, and it IS in the profile's authorized list. ## Test plan - [ ] Merge this PR and let release-please open the v1.3.2 PR - [ ] Merge v1.3.2 release PR - [ ] Re-verify the \`Prepare sanitized entitlements\` log in the v1.3.2 release workflow — the dumped plist should show \`com.apple.developer.aps-environment: production\` and NO bare \`aps-environment\` key - [ ] After release ships: \`brew upgrade --cask tossinger\` on both Mac mini and MacBook - [ ] Launch the app — should no longer crash with SIGKILL - [ ] Add a toss on one machine, wait ~30s, verify it appears on the other (cross-machine CloudKit push sync should work since \`com.apple.developer.aps-environment\` is present) - [ ] Run \`toss ls\` — should exit cleanly (CLI opt-out from #17 still applies) ## Notes - This PR reverses **only the iOS-shaped half** of the APNs entitlement work from #17. The CLI CloudKit opt-out and the iOS cert-spam fix from #16 are untouched. - #17's \`toss/toss.entitlements\` source file still declares both keys with value \`development\` — that's fine for local Debug Xcode builds (Xcode automatic signing handles the iOS/macOS key split per-platform). The release workflow is the only place we need to strip the iOS shape for macOS distribution. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 504456d commit 36e30a2

1 file changed

Lines changed: 19 additions & 9 deletions

File tree

.github/workflows/release.yml

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -171,15 +171,25 @@ jobs:
171171
cp toss/toss.entitlements "${SANITIZED}"
172172
173173
# CloudKit silent push delivery on macOS goes over APNs, so the
174-
# signed entitlements MUST declare aps-environment for the released
175-
# build to receive remote-change notifications and pull tosses from
176-
# iCloud into the local store. The source file carries "development"
177-
# for local Debug builds (APNs sandbox), but the Developer ID
178-
# provisioning profile only authorizes "production" — substitute the
179-
# value here so signing succeeds and runtime sync actually works.
180-
# Stripping these (the previous behavior) silently broke cross-device
181-
# sync: each Mac became a write-only island.
182-
/usr/libexec/PlistBuddy -c "Set :aps-environment production" "${SANITIZED}"
174+
# signed entitlements must declare the APNs entitlement for the
175+
# released build to receive remote-change notifications and pull
176+
# tosses from iCloud into the local store.
177+
#
178+
# On macOS the runtime key is `com.apple.developer.aps-environment`
179+
# (all developer entitlements live under the com.apple.developer.*
180+
# namespace). The bare `aps-environment` key is the iOS convention
181+
# and is NOT authorized by the macOS Developer ID provisioning
182+
# profile — if you leave it in, amfi kills the binary at exec with
183+
# "Code Signature Invalid" because a restricted entitlement isn't
184+
# profile-backed. codesign --verify doesn't catch this since it
185+
# only checks structural validity; amfi is the one that enforces
186+
# the profile subset at runtime.
187+
#
188+
# The source file declares both keys with value "development" for
189+
# local Debug builds (iOS/macOS multiplatform target). Here we
190+
# strip the iOS-shaped bare key and substitute the macOS key to
191+
# "production" since the Developer ID profile authorizes that.
192+
/usr/libexec/PlistBuddy -c "Delete :aps-environment" "${SANITIZED}" 2>/dev/null || true
183193
/usr/libexec/PlistBuddy -c "Set :com.apple.developer.aps-environment production" "${SANITIZED}"
184194
185195
# Substitute $(CFBundleIdentifier) which xcodebuild expands at build

0 commit comments

Comments
 (0)