Llim.run

Apple Account authentication

Limrun's Apple Account authentication lets users connect their Apple Developer account from within your application. Users enter their Apple Account credentials and complete any required two-factor verification. This sign-in step gives your platform an authenticated session for workflows such as signing and publishing iOS apps.

Password authentication with SRP

Secure Remote Password, or SRP, lets a client prove knowledge of a password without transmitting the password. The client and server exchange public values and compute a shared secret, which they use to generate authentication proofs. Thomas Wu's original SRP research paper explains the protocol and its security properties.

Apple's GrandSlam Authentication, or GSA, uses an adapted SRP protocol, including PBKDF2 password derivation. Alex Ionescu's Blackwood-4NT research documents these adaptations for Apple's native authentication service. Limrun's web integration uses the Apple-compatible Mode.GSA in its SRP library and sends authentication requests to Apple's idmsa.apple.com web endpoints.

@limrun/apple-auth performs password derivation and SRP proof generation in the user's browser. It sends the proofs through Limrun's WebSocket relay for Apple to verify. The password and derived password key stay in the browser; the SDK never sends either to the relay. The relay does receive the Apple Account username, protocol messages, and any six-digit verification code, and holds Apple's session cookies and authentication headers in memory for the connection.

When Apple requires two-factor authentication, the user also enters a six-digit one-time passcode, which Apple calls a verification code. Apple verifies both the password proof and this second factor.

Traffic flow

The browser opens a secure WebSocket connection to wss://registry.limrun.com/ios/appstoreconnect/ws. Your backend supplies a short-lived access token with applerelay:*:connect to authorize that connection. This Limrun token controls access to the relay; Apple authenticates the user through the SRP and verification-code exchanges carried over it.

Authentication traffic follows this path in both directions:

Browser with @limrun/apple-auth
             |
       WebSocket over TLS (WSS)
             |
       Limrun Apple relay
             |
         HTTPS (TLS)
             |
      Apple authentication
        idmsa.apple.com

The relay acts as an application-layer proxy. It translates WebSocket messages into HTTPS requests to Apple and returns Apple's status and response body over the same WebSocket. Each request has an ID that correlates it with its response. The relay reuses the connection's cookies and authentication headers so successive requests belong to the same Apple authentication session.

These are separate TLS connections. TLS encrypts traffic on each hop, and the relay can read the messages it forwards.

Username and password

When the user submits their Apple Account username and password, startLogin({ accountName, password }) performs the following exchange:

  1. The browser creates an ephemeral SRP key pair. It sends the account name, client public value A, and supported Apple password-derivation protocols in a srpInit WebSocket message. The wire field for A is a.
  2. The relay forwards the message to Apple's sign-in initialization endpoint. Apple returns its public value B, a salt, an iteration count, the selected protocol, and a challenge value c. The relay returns those values to the browser.
  3. The browser processes the password with SHA-256 and derives a key with PBKDF2-HMAC-SHA-256, using Apple's salt and iteration count. It computes the SRP proof values locally and sends accountName, m1, m2, and c in a srpComplete message.
  4. The relay submits the proof to Apple. In this flow, HTTP 409 means Apple requires two-factor authentication. The SDK then requests a verification code and returns requiresTwoFactor: true to the application. A successful response without that challenge completes password authentication without a code prompt.

The relay also obtains Apple's public sign-in widget key from an App Store Connect redirect. Before submitting the SRP proof, it fetches Apple's Hashcash challenge and computes the proof of work if Apple supplies one. Hashcash is separate from the password proof and the verification code.

Six-digit verification code

The SDK first requests verification through a trusted Apple device. Apple delivers the code to the user's device outside the WebSocket connection. If Apple reports that phone verification is required or no trusted devices are available, the SDK requests a code for the trusted phone number returned by Apple, using SMS by default.

When the user enters the code, submitTwoFactorCode(code) sends it through the existing WebSocket. The relay forwards it to Apple's verification endpoint for the selected method. Apple validates the code, and the relay returns the result. On a successful response, the React hook sets its status to authenticated; on failure, it exposes the error.

The authentication messages map to these Apple HTTPS requests. All paths below are relative to https://idmsa.apple.com/appleauth/auth.

WebSocket messageApple request
srpInitPOST /signin/init
srpCompletePOST /signin/complete?isRememberMeEnabled=false
triggerTrustedDevice2FAGET /verify/trusteddevice
triggerPhone2FAPUT /verify/phone
submitTrustedDevice2FAPOST /verify/trusteddevice/securitycode
submitPhone2FAPOST /verify/phone/securitycode

For trusted-device verification, the WebSocket payload contains { code }. Phone verification also includes the selected phoneNumberId and delivery mode. The relay places the code in Apple's securityCode.code field. The code travels inside TLS on both hops and is readable by the relay.

The SDK's login flow, SRP implementation, and WebSocket client define the browser-side exchange.

Data access inventory

The table describes data handled during the standard SDK authentication flow. "Not sent" means this flow does not transmit the value to that entity; it makes no claim about Apple's account storage.

InformationBrowserYour backendLimrun relayApple
Apple Account usernameUser enters itNot sentForwards itReceives it
Apple Account passwordUser enters itNot sentNot sentNot sent
Derived password keyComputes it locallyNot sentNot sentNot sent
SRP public values, salt, challenge, and proofsSends or receives themNot sentForwards themSends or receives them
Six-digit verification codeUser enters itNot sentForwards itValidates it
Apple session cookies from Set-CookieNot forwardedNot sentHolds them in memoryIssues them
Apple authentication headersReceives selected headersNot sentHolds and forwards selected headersIssues or receives them
Limrun relay access tokenReceives it from your backendRequests and returns itValidates itNot sent

The selected Apple headers include scnt, x-apple-id-session-id, x-apple-auth-attributes, csrf, and csrf_ts. The relay returns these to the browser and uses them for subsequent Apple requests. It keeps the session cookies in its own cookie jar.

"Browser" includes your application's JavaScript, which handles the password input and runs the SDK. Your backend's role in this flow is to obtain the Limrun relay access token. Any additional data collection by your application falls outside this table.