Skip unknown entitlement keys with a warning in SyncBundleID#327
Open
Badlazzor wants to merge 1 commit intoaudit/service-type-by-keyfrom
Open
Skip unknown entitlement keys with a warning in SyncBundleID#327Badlazzor wants to merge 1 commit intoaudit/service-type-by-keyfrom
Badlazzor wants to merge 1 commit intoaudit/service-type-by-keyfrom
Conversation
Apple routinely adds new entitlement keys (most recently
`com.apple.developer.healthkit.access`, `kernel.increased-memory-limit`,
etc.). Any key not present in `ServiceTypeByKey` causes
`Entitlement.Capability()` to hard-error and `SyncBundleID` to abort the
entire code signing phase, which means a single freshly-introduced key
breaks every build that happens to declare it until the allow-list is
extended and a new step release is cut.
This change:
- Introduces `autocodesign.ErrUnknownEntitlementKey` as an exported
sentinel, and wraps it with `fmt.Errorf("%w: %s", …)` in both
`Capability()` and `Equal()`. Callers that have existing
`errors.Is(err, ErrUnknownEntitlementKey)` handling continue to work;
the human-readable message is unchanged (`unknown entitlement key:
<key>`).
- Updates `ProfileClient.SyncBundleID` to catch the sentinel, log a
warning identifying the key, and continue syncing the remaining
entitlements instead of aborting. Other entitlements in the project
still get registered correctly.
Tradeoff: if Apple adds an entitlement that genuinely requires App Store
Connect registration and it is not yet in `ServiceTypeByKey`, the step
will log a warning and move on rather than erroring out. The resulting
provisioning profile will miss that one capability — but every other
capability on the bundle ID is now synced correctly, instead of the
current behavior where *no* capability gets synced. A missing capability
surfaces as a later-stage provisioning error with clearer attribution
than today's opaque `unknown entitlement key` message.
Adds a regression test (`TestCapability_UnknownKeyReturnsSentinel`)
covering sentinel wrapping and key attribution.
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.
Issue
autocodesign.Entitlement.Capability()hard-errors withunknown entitlement key: <key>whenever a project's entitlements file contains a key that is not inappstoreconnect.ServiceTypeByKey.ProfileClient.SyncBundleIDiterates the entire project entitlements map and returns the first such error unwrapped. As a result, one unrecognised key anywhere in the project kills the entire code signing phase, even when every other entitlement is well-known and in sync with App Store Connect:This is the failure mode behind #325 (
com.apple.developer.healthkit.access, iOS 17.5+). Apple adds entitlement keys routinely (see #326 for a recent batch); each addition is a latent, high-blast-radius break.Intent
Decouple the step's stability from Apple's entitlement release cadence. An entitlement key that we have not yet classified should log a warning and be skipped, not abort the entire sync. Other entitlements on the bundle ID still get registered correctly.
Changes
autocodesign.ErrUnknownEntitlementKey) inautocodesign/entitlement.go. BothCapability()andEqual()now wrap it withfmt.Errorf(\"%w: %s\", …). The human-readable error message is unchanged —unknown entitlement key: <key>— so any log-scraping stays compatible, while callers gainerrors.Iswiring for programmatic handling.ProfileClient.SyncBundleIDcatches the sentinel witherrors.Is, logs a warning that identifies the offending key and points at this repo, andcontinues the loop to process the rest of the project's entitlements instead of aborting.TestCapability_UnknownKeyReturnsSentinel) inautocodesign/entitlement_test.goconfirms sentinel wrapping + key attribution in the error message.Equal()(called fromcheckBundleIDEntitlements) is not currently reachable with an unknown key because its caller gates onAppearsOnDeveloperPortal(), which already returnsfalsefor unknown keys. The sentinel is wired there anyway for consistency — so if that gate is ever relaxed, the behavior stays defensive.Risk / tradeoff
Today: an unrecognised entitlement = every affected build fails with an opaque error.
After this PR: an unrecognised entitlement = a warning in the log, the bundle ID is synced with every other capability, the build proceeds. If the unknown key did need ASC registration, the downstream provisioning step will fail with a more targeted error (missing capability on a specific profile) that is easier to attribute than today's "unknown entitlement key".
In other words: we trade a guaranteed hard-break for a soft-break with better attribution. The step becomes resilient to Apple's additions until the allow-list catches up.
Test plan
go test ./autocodesign/...go vet ./autocodesign/...TestCapability_UnknownKeyReturnsSentinelpasses[email protected], confirm warning is logged and other capabilities sync correctly🤖 Generated with Claude Code