Repository navigation
Conversation
…r each one Every operation that needs Apple's developer services performed a full GrandSlam sign-in: the background refresh at launch, View App IDs, and each install, update, or refresh started separately. Apple limits how often an account may sign in, and once the limit is hit it answers with an HTTP 429 page for a while, which AltStore surfaces as a parse error or "Failed to authenticate account". Opening the app and refreshing a few apps individually is enough to trigger it. AuthenticationOperation now keeps the team, certificate, and session from a successful sign-in in an in-memory cache and reuses them for up to fifteen minutes. A reused session gets fresh anisette data, which is the only part that expires quickly and is already refreshed the same way before provisioning profiles are fetched. The token is only reused when the fresh anisette data comes from the same machine identity as the sign-in; after the anisette source changes, such as when Remote AltServer is set up again against a different server, the operation signs in again instead. The database and keychain updates that follow a real sign-in are skipped on reuse because that sign-in already made them. Sign-ins that start while another is in progress now wait for it rather than running concurrently, so they reuse its result. The cache is dropped when a request made with it fails with an ALTAppleAPIError, with an Apple result code AltSign passes through unmapped (such as 1100, "Your session has expired"), or with an Apple response that does not parse as a plist, so the next operation signs in again. It is also dropped when the user signs out.
izaankml
force-pushed
the
fix/reuse-apple-id-session
branch
from
October 24, 2026 18:32
6b6f1cd to
8224477
Compare
Author
|
Rebased onto 2.3.1, keeping the new anisette resync handler. Retested on iOS 27: one sign-in after the 2FA code, then "Reused sign-in for team" for each later refresh. |
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.
Problem
Every operation that talks to Apple does a full GrandSlam sign-in: the refresh at launch, View App IDs, and each install or refresh. Refreshing a few apps one at a time is enough to hit Apple's sign-in rate limit, which comes back as an HTTP 429 page and shows as
NSCocoaErrorDomain 3840. The session itself stays valid far longer, only the anisette data expires quickly.Fix
Cache the team, certificate and session from a sign-in for 15 minutes and reuse them with fresh anisette data. The token is only reused if the anisette machine identifier still matches, since Apple returns error 1100 otherwise. Concurrent operations wait for a sign-in in progress, and the cache is cleared on any Apple API error or sign-out.
Testing
On iOS 26.6.2 the log shows one "Authenticated account for team" then "Reused sign-in for team" for every later operation, including View App IDs and Refresh All. Resetting Remote AltServer with a different anisette server forced a fresh sign-in instead of a 1100 error.
Related: #1776, #1782