Skip to content

Session-minted upload key: nobody types an app-specific password (v1.64.18.0)#48

Merged
time-attack merged 3 commits into
mainfrom
time-attack/upload-key-mint
Jul 24, 2026
Merged

Session-minted upload key: nobody types an app-specific password (v1.64.18.0)#48
time-attack merged 3 commits into
mainfrom
time-attack/upload-key-mint

Conversation

@time-attack

@time-attack time-attack commented Jul 24, 2026

Copy link
Copy Markdown
Owner

What

Apple's binary-upload tool (iTMSTransporter behind deliver/pilot) never accepts the spaceauth web session — it takes only an ASC API key or an app-specific password (live error -22938, confirmed by fastlane's auth docs). The previous contract claimed the session alone covered uploads; that claim was wrong for this one leg.

The fix is broad, not a patch: the web session mints the API key itself, through the same iris endpoints the App Store Connect web UI uses. Proven live end to end on a real account:

  1. POST /iris/v1/apiKeys (JSON:API, APP_MANAGER, PUBLIC_API) → 201
  2. GET /iris/v1/apiKeys/<id>?fields[apiKeys]=privateKey → base64-of-PEM, decode once (one-time download)
  3. Issuer ID = provider.publicProviderId from GET /olympus/v1/session
  4. JWT from the minted key → official API lists the team's apps ✅

Stored at ~/.appstoreconnect/private_keys/AuthKey_<id>.p8 + fastlane api-key JSON ~/.gstack/apple/api-key.json (0600). The key never expires → repeat releases skip sign-in entirely. New escalation ladder: mint → re-sign-in + re-mint → self-service ASP only on a team-permissions refusal (non-admin member).

Testing

  • bun run test:gstack2 green; parity 4,359 checks pass, all 3 Apple pins survive
  • bun test (full free gate) exit 0
  • Live probe: key minted, JWT validated against api.appstoreconnect.apple.com

🤖 Generated with Claude Code


Summary by cubic

Uploads now use an App Store Connect API key minted from your web session. No app-specific password prompts, and repeat releases skip sign-in.

  • New Features
    • Mint the upload key via iris after the first fastlane spaceauth, then store it at ~/.appstoreconnect/private_keys/AuthKey_<id>.p8 and ~/.gstack/apple/api-key.json (0600). The key does not expire.
    • Run deliver/pilot with api_key_path; the session remains only for produce and re-minting if the key is revoked. Escalation: mint → re-sign-in + re-mint → app-specific password only on team-permissions refusal.
    • Updated skills/ship/references/APPLE-RELEASE.md; bumped version to 1.64.18.0.

Written for commit a0caef5. Summary will update on new commits.

Review in cubic

Sinabina and others added 3 commits July 24, 2026 11:21
…kes the session

Apple's binary-upload tool (iTMSTransporter behind deliver/pilot) accepts only
an ASC API key or app-specific password; the spaceauth web session is not valid
there (live error -22938 + fastlane auth docs). Corrected the contract: the
session's job on the upload leg is to MINT the key via the iris endpoints the
ASC web UI uses (POST /iris/v1/apiKeys, privateKey = base64-of-PEM downloadable
once, issuer = olympus publicProviderId). Key stored at
~/.appstoreconnect/private_keys + ~/.gstack/apple/api-key.json; never expires,
so repeat releases skip sign-in. Escalation ladder now: mint → re-sign-in +
re-mint → ASP self-service only on a team-permissions refusal. Proven live
end to end (mint + JWT lists team apps).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@cursor

cursor Bot commented Jul 24, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@time-attack
time-attack merged commit ba82dc0 into main Jul 24, 2026
6 of 17 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.

1 participant