Stop a missing signing profile from shipping a dead app - #192
Merged
Conversation
The app needs a provisioning profile from Apple to use iCloud. Without one it still builds, still gets signed, still passes Apple's checks, and then refuses to open on every machine it lands on. The check meant to catch that was written back when the app used no Apple services, so it said a missing profile was fine and passed the build. That stopped being true this morning. It now reads what the app actually asks for and stops the build when the profile is missing, or when the profile it has does not cover it.
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.
What this does
The app needs a provisioning profile from Apple to use iCloud. Without one it still builds, still gets signed, still passes Apple's notarization, and then refuses to open on every machine it lands on. Nothing in the pipeline noticed.
The check that exists to catch this was written when the app used no Apple services, so it said a missing profile was expected and let the build through. That stopped being true when CloudKit landed this morning, which left the one guard against a dead release asserting the release was fine.
It now reads what the app actually asks for and stops the build if the profile is missing, or if the profile it has does not cover it.
Summary
verify-provision-profile.shnow reads entitlements from the signature viacodesign -d --entitlements, not from the source.entitlementsfile. The two can diverge, and the signature is what AMFI reads at launch.com.apple.developer.*is treated as restricted, withteam-identifierexcluded — codesign injects that into essentially every Developer-ID bundle, so including it failed every build.release.ymlandsign-release-app.shthat still claimed the app ships no restricted entitlements and that a missing profile is harmless.Test plan
Verified against real signed bundles on macOS 26.5.2:
IINA.app(no restricted entitlements, no profile) → exit 01Password.app(associated-domains+authentication-services, with profile) → exit 0, reports "covers all 2 restricted entitlement(s)"Dato.app(usernotifications.time-sensitive, no profile) → exit 1, fail-closedprograma.entitlementsand no profile → exit 1, namingicloud-servicesandicloud-container-identifiers. This is the AMFI-brick case, and it was previously exit 0.Note on the deliberate asymmetry:
aps-environmentandusernotifications.*are not excluded even though Dato and Xcode demonstrably ship them without profiles. Programa uses neither, and an unnecessary failure is a loud one-line fix while a missed one ships an app that will not launch. If either is ever added and this fires, check Apple's capability docs before widening the exclusion.A Debug build cannot exercise this:
CODE_SIGN_ENTITLEMENTSis empty in the project andprograma.entitlementsis applied post-build bysign-release-app.sh, so only release-path bundles carry the restricted keys.