Skip to content

Read the Apple service key from the sign out redirect (fixes #161) - #162

Merged
sebsto merged 1 commit into
mainfrom
fix/service-key-from-signout-redirect
Sep 14, 2026
Merged

sebsto merged 1 commit into
mainfrom
fix/service-key-from-signout-redirect

Conversation

@sebsto

@sebsto sebsto commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Fixes #161.

Problem

xcodeinstall authenticate fails at the very first step with unableToRetrieveAppleServiceKey. Apple removed the olympus config endpoint in September 2026:

GET https://appstoreconnect.apple.com/olympus/v1/app/config?hostname=itunesconnect.apple.com
-> 404 Not Found

getAppleServicekey() relied on that endpoint to fetch the widget key (authServiceKey) required by every subsequent auth call, so login dies before it can start. Same break as fastlane/fastlane#30199; the upstream fix is fastlane/fastlane#30206.

Fix

The widget key is a public, static front-end identifier, not a credential. Apple's own App Store Connect front end now reads it from the sign-out redirect:

GET https://appstoreconnect.apple.com/logout
-> 302  Location: https://idmsa.apple.com/appleauth/signout?widgetKey=<key>&asop=destroy-session&...

getAppleServicekey() now tries that source first and falls back to the olympus endpoint (kept in case Apple restores it):

  • fetchServiceKeyFromSignout() reads widgetKey out of the /logout 302 Location header, returning nil on any expected miss so the caller falls through to olympus rather than making this a new single point of failure.
  • signoutRedirectLocation() issues the request over a dedicated ephemeral URLSession with a redirect-suppressing delegate and no cookie storage. This is deliberate: the redirect target carries asop=destroy-session, so following it (or sending the session cookies) would actually sign the session out. We stop at the 302 and read only the header.
  • fetchServiceKeyFromOlympus() is the previous behaviour, unchanged, now the fallback.

NoRedirectDelegate is a stateless, Sendable delegate returning nil from willPerformHTTPRedirection.

Tests

New cases mirror the upstream fix; the seam is stubbed via a StubbedSignoutAuthenticator test subclass so no live network is hit:

  • reads the key out of the sign-out Location redirect;
  • falls back to olympus when the redirect carries no widgetKey;
  • falls back to olympus when the sign-out request fails outright;
  • the existing olympus 200/500 and no-service-key flow tests still pass (olympus is the fallback path now).

Built and tested locally on macOS with Xcode 26.6: swift build clean, swift test green (207 tests, 19 suites).

Apple removed the olympus config endpoint in September 2026; it now
returns 404, so getAppleServicekey() could no longer fetch the widget
key and authenticate failed before it started (see fastlane#30199).

Read the key from where App Store Connect keeps it now: the /logout
route answers with a 302 whose Location carries widgetKey=<key>. The
request must not follow the redirect and must send no cookies, since
the target is a real signout (asop=destroy-session). The olympus call
is kept as a fallback in case Apple restores it.
@sebsto
sebsto merged commit 66da3b0 into main Sep 14, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

authenticate fails: Apple removed the service-key endpoint (404)

1 participant