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.comThe 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:
- The browser creates an ephemeral SRP key pair. It sends the account name, client public value
A, and supported Apple password-derivation protocols in asrpInitWebSocket message. The wire field forAisa. - 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 valuec. The relay returns those values to the browser. - 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, andcin asrpCompletemessage. - The relay submits the proof to Apple. In this flow, HTTP
409means Apple requires two-factor authentication. The SDK then requests a verification code and returnsrequiresTwoFactor: trueto 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 message | Apple request |
|---|---|
srpInit | POST /signin/init |
srpComplete | POST /signin/complete?isRememberMeEnabled=false |
triggerTrustedDevice2FA | GET /verify/trusteddevice |
triggerPhone2FA | PUT /verify/phone |
submitTrustedDevice2FA | POST /verify/trusteddevice/securitycode |
submitPhone2FA | POST /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.
| Information | Browser | Your backend | Limrun relay | Apple |
|---|---|---|---|---|
| Apple Account username | User enters it | Not sent | Forwards it | Receives it |
| Apple Account password | User enters it | Not sent | Not sent | Not sent |
| Derived password key | Computes it locally | Not sent | Not sent | Not sent |
| SRP public values, salt, challenge, and proofs | Sends or receives them | Not sent | Forwards them | Sends or receives them |
| Six-digit verification code | User enters it | Not sent | Forwards it | Validates it |
Apple session cookies from Set-Cookie | Not forwarded | Not sent | Holds them in memory | Issues them |
| Apple authentication headers | Receives selected headers | Not sent | Holds and forwards selected headers | Issues or receives them |
| Limrun relay access token | Receives it from your backend | Requests and returns it | Validates it | Not 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.
How password authentication and two-factor verification travel between the browser, Limrun's WebSocket relay, and Apple.
Was this guide helpful?