midi-harbor/specs/016-app-store-submission/research.md
James Coleman b70ac24cc4 build(macos): build the App Store Connect package with make appstore
- The App Store variant was only signed ad hoc to run locally, so nothing it produced could be submitted; with a Mac App Store Connect provisioning profile in .signing/app-store.provisionprofile it now embeds the profile, adds the profile's App ID and team to the app's entitlements, signs both executables with the keychain's Apple Distribution identity, and wraps the app in an installer package signed with Mac Installer Distribution.
- A profile whose App ID is not the bundle's is refused, and a missing distribution or installer certificate stops the build rather than producing an unsubmittable package.
- CFBundleVersion becomes the build's UTC time to the minute, since App Store Connect rejects a build number it has seen, while CFBundleShortVersionString stays VERSION; ITSAppUsesNonExemptEncryption is false, as the build's only cryptography is hashing and random numbers.
- The bundled daemon keeps only the sandbox and inherit entitlements, which a helper inheriting its parent's sandbox requires.
- Without a profile the variant builds as before, ad hoc or with MIDI_HARBOR_SIGNING_IDENTITY, to run on the building Mac.
2026-09-28 14:38:49 -05:00

51 lines
3 KiB
Markdown

# Research: App Store Submission
The investigation behind this spec, under its number in the project-wide research log.
---
## R-103: What App Store Connect needs beyond the sandboxed app
**Status**: **VERIFIED** (2026-09-28) locally; not yet uploaded. Built as T245.
**The App ID needs no capabilities.** Every entitlement the build uses (the sandbox, network
client and server, Bluetooth, USB, and the helper's inherit) is a sandbox entitlement that
signing grants. The login item uses `SMAppService`, and the helper shares the app's container by
inheriting its sandbox, so App Groups are not needed either. The profile Apple generated for the
bare App ID carries `com.apple.application-identifier`, `com.apple.developer.team-identifier` and
`keychain-access-groups` (`<team>.*`). The first two must be in the app's signed entitlements to
match the profile; keychain access groups are not used, so they are left out.
**The certificates came untrusted.** Xcode created the Apple Distribution and Mac Installer
Distribution certificates, but `security find-identity` called both `CSSMERR_TP_NOT_TRUSTED`:
they are issued by Apple's WWDR G3 intermediate, which this Mac lacked. The Developer ID
certificate, issued by another intermediate, was unaffected. Installing
`AppleWWDRCAG3.cer` made both valid. The keychain names the installer certificate
"3rd Party Mac Developer Installer", its older name, which is what the build looks for.
**The helper keeps only the sandbox and inherit.** A helper signed to inherit its parent's
sandbox must carry exactly those two entitlements, so the profile's identifiers go on the app
alone.
**The build number is the build's time.** App Store Connect refuses a build number it has seen
for the app, so `CFBundleVersion` is the time in UTC, `%Y%m%d%H%M`, twelve digits. The version
shown, `CFBundleShortVersionString`, stays `VERSION`. A count of commits was rejected, since the
owner rewrites history before publishing and the count would fall.
**Encryption.** The macOS build links no TLS; `cargo tree` finds only `sha2` and `chacha20`,
used for hashing and random numbers, which are exempt. `ITSAppUsesNonExemptEncryption` is false,
so App Store Connect does not ask at every upload.
**Evidence**, `make appstore` on the development Mac:
- `lipo -archs`: `x86_64 arm64` for both executables, once `x86_64-apple-darwin` was installed.
- `codesign -dvv`: both signed by "Apple Distribution: James Coleman (8XMLMKNPUT)" with the
hardened runtime. The app's entitlements are the sandbox list plus
`8XMLMKNPUT.com.mrgeckosmedia.MidiHarbor` and `8XMLMKNPUT`. The helper's are the sandbox and
inherit.
- `Contents/embedded.provisionprofile` present; `codesign --verify --deep --strict` passes.
- `pkgutil --check-signature`: signed by "3rd Party Mac Developer Installer: James Coleman
(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.