From 8a8bf653fe992dcfa891aaf976f985df30cd2de4 Mon Sep 17 00:00:00 2001 From: James Coleman Date: Mon, 28 Sep 2026 15:12:13 -0500 Subject: [PATCH] fix(macos): strip extended attributes from the App Store app before signing - App Store Connect refused the package with error 91109 because the embedded provisioning profile kept the com.apple.quarantine attribute the browser set when it was downloaded. - Every extended attribute is now cleared from the app before it is signed, so no file copied into the bundle can carry quarantine into the package; com.apple.provenance, which macOS sets on every file and which cannot be cleared, remains. --- packaging/macos/bundle.sh | 4 +++- specs/016-app-store-submission/research.md | 10 +++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packaging/macos/bundle.sh b/packaging/macos/bundle.sh index c5e10a3..7269b72 100755 --- a/packaging/macos/bundle.sh +++ b/packaging/macos/bundle.sh @@ -102,7 +102,9 @@ if [ -n "$helper" ]; then identity=${MIDI_HARBOR_SIGNING_IDENTITY:--} fi - # Sign. + # Sign, with no extended attributes: App Store Connect refuses a package holding a file + # marked with com.apple.quarantine, as a downloaded profile is (research R-103). + xattr -cr "$app" plutil -lint "$app/Contents/Info.plist" >/dev/null codesign --force --options runtime --sign "$identity" \ --entitlements packaging/macos/helper.entitlements \ diff --git a/specs/016-app-store-submission/research.md b/specs/016-app-store-submission/research.md index 0ab22e6..b7ada4a 100644 --- a/specs/016-app-store-submission/research.md +++ b/specs/016-app-store-submission/research.md @@ -36,6 +36,13 @@ owner rewrites history before publishing and the count would fall. used for hashing and random numbers, which are exempt. `ITSAppUsesNonExemptEncryption` is false, so App Store Connect does not ask at every upload. +**Extended attributes are stripped before signing.** The first upload was refused with error +91109: `Contents/embedded.provisionprofile` carried `com.apple.quarantine`, which the browser set +on the downloaded profile and `cp` kept. `xattr -cr` on the app before signing removes it and +anything else a copied file brings. `com.apple.provenance` stays on every file, since macOS +sets it on whatever an app writes and it cannot be cleared; App Store Connect's check names only +quarantine. + **Evidence**, `make appstore` on the development Mac: - `lipo -archs`: `x86_64 arm64` for both executables, once `x86_64-apple-darwin` was installed. @@ -48,4 +55,5 @@ so App Store Connect does not ask at every upload. (8XMLMKNPUT)", which it reports as a development certificate, as it does every App Store installer certificate. -**Not checked**: App Store Connect's own validation, which runs on upload. +**Not checked**: an upload after the quarantine fix; the expanded package carries no attribute but +`com.apple.provenance`.