Repository navigation
Add a sandboxed build for the Mac App Store - #3
Merged
Merged
Conversation
The store requires the App Sandbox. Add an AppStore build configuration — Release plus an entitlements file granting the sandbox and outbound network access, which is all Cleared needs — and make it what the scheme archives with, so Product → Archive in Xcode builds the right thing. Release stays unsandboxed for direct builds. The App Store team comes from Local.xcconfig and may differ from the team that signs day-to-day builds. Without it the configuration falls back to ad-hoc signing, so it still builds on a fresh clone. The sandbox rules out the gh CLI login: Cleared can neither run `gh` there nor read what it stores. The build detects the sandbox at runtime and makes a pasted token the way in, saying why, instead of showing a disabled button and "gh CLI not found". Both builds gain a link that opens GitHub's new-token page with the scope filled in. The sandboxed build keeps its token under its own Keychain service. It is signed differently from a direct build and could not read that build's entry — and trying would raise a Keychain password prompt at launch. Also for the store: declare that only exempt encryption is used, a real copyright line, and a privacy manifest (no tracking, nothing collected, UserDefaults for the app's own settings). Checked with a throwaway sandboxed probe carrying the same entitlements: HTTPS to api.github.com returns 200, and a Keychain add, read, update and delete round trip succeeds. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`make appstore` archives with the AppStore configuration, exports a package signed for App Store Connect, then unpacks it and refuses to report success unless the app inside is sandboxed, validly signed, and free of the get-task-allow entitlement development builds carry. It uploads nothing. The archive goes where Xcode's Organizer looks, so the same build can be distributed from there. `make appstore-build` builds that configuration without archiving and needs no signing set up. CI runs it and checks for the sandbox entitlement, so the store build cannot quietly stop compiling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
How to archive it from Xcode or with `make appstore`, which team settings it needs, and what differs in the sandboxed build: no gh CLI login, a separate Keychain entry, settings that start fresh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Gets Cleared ready to distribute through the Mac App Store. Tracked on the board as LAB-9.
Why it needs its own build
The store requires the App Sandbox, and the sandbox rules out the one-click Use my gh CLI login: Cleared can neither run
ghthere nor read the login it stores. So this adds a third configuration rather than sandboxing everything. Direct builds keep the gh path; the store build connects with a pasted token and says why.What changed
AppStoreconfiguration — Release plusResources/Cleared.entitlements(the sandbox and outbound network, nothing else). The scheme archives with it, so in Xcode it is Product → Archive, then Distribute App → App Store Connect.Local.xcconfig(CLEARED_APPSTORE_TEAM), and may differ from the team used day to day. With none set it falls back to ad-hoc, so a fresh clone and CI still build it.reposelected.ITSAppUsesNonExemptEncryption = NO, a real copyright line, and a privacy manifest (no tracking, nothing collected, UserDefaults for the app's own settings).make appstore— archives, exports the signed package todist/appstore/, then unpacks it and fails unless the app inside is sandboxed, validly signed, and free ofget-task-allow. Uploads nothing.AppStoreconfiguration and checks for the sandbox entitlement.Verification
make appstorerun end to end on the maintainer's Mac. The package is signed with the 3rd Party Mac Developer Installer certificate; the app inside is signed Apple Distribution, hardened runtime, universal, sandboxed, with Xcode's Mac Team Store provisioning profile.starting (sandboxed), creates its container, and produced no sandbox denials.api.github.comreturns 200, and a Keychain add, read, update and delete round trip succeeds.Local.xcconfigbuilds the configuration ad-hoc and passes the tests (79 in 16 suites).Not exercised: connecting with a real token inside the sandboxed app, and anything on the App Store Connect side — no build has been uploaded.
Still to do outside the repo
🤖 Generated with Claude Code