# How IPATool Manages App Store Sessions: SAP Authentication and Session Flow

> Discover how IPATool manages App Store sessions using SAP authentication. Learn about its short-lived mlid session for efficient API calls during CLI execution.

- Repository: [Majd/ipatool](https://github.com/majd/ipatool)
- Tags: internals
- Published: 2026-09-06

---

**IPATool authenticates to the Apple App Store using Apple's SAP (Store-Apple-Protocol) and creates a short-lived purchase-history session (mlid) that it reuses for all subsequent API calls during a single CLI execution.**

The majd/ipatool repository implements a sophisticated session management system for interacting with Apple's servers without requiring persistent browser cookies. By leveraging the Store-Apple-Protocol (SAP), IPATool establishes temporary credentials that grant access to purchase history and app downloading capabilities while maintaining a strict ephemeral security model.

## SAP Authentication and Session Initialization

IPATool begins the session lifecycle by configuring the machine identity and establishing a secure channel with Apple's servers. In [`pkg/appstore/appstore_login.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_login.go), the tool obtains the machine's MAC address and builds a GUID before fetching the current *bag*—Apple's configuration bundle containing cryptographic parameters.

The authentication flow in `appstore_login.go:38-62` creates an **ActionSigner** from the bag's `SAPConfig`, which cryptographically signs all subsequent requests. When a user provides their Apple ID credentials, IPATool sends a POST request to the SAP authentication endpoint with the email, password, and optional two-factor code, all signed by the ActionSigner (lines 58-78).

```go
// SAP login establishes the foundation for session creation
loginInput := appstore.LoginInput{
    Email:    "user@apple.com",
    Password: "secret",
}
loginOut, err := store.Login(loginInput) // Returns Account with tokens
if err != nil {
    log.Fatal(err)
}

```

## Extracting the Session ID (mlid) from Login Responses

Upon successful authentication, Apple's servers return a response containing the **mlid** field (machine ID session identifier). IPATool extracts this value in `pkg/appstore/appstore_owned_apps.go:138-144` using the `firstDMAPUint` helper function.

The implementation validates that the mlid fits within a 32-bit unsigned integer before accepting it as the official session identifier. If the field is missing or fails validation, the operation returns an error immediately, preventing unauthorized requests.

## Propagating the Session Across API Calls

Once extracted, the session ID is stored in the `appstore` struct's `sessionID` field (`t.sessionID`) and injected into every subsequent request body targeting the purchase-history service. As implemented in `appstore_owned_apps.go:209-224`, this ensures continuity across multiple API interactions without re-authenticating.

Each request body follows URL-encoded form format, beginning with `session-id=<mlid>`. The helper functions `ownedAppsUpdateRequest` and `ownedAppsItemsRequest` (lines 210-235) automatically embed this identifier:

```go
// Extracting and using the session ID for owned apps requests
sessionID, ok, err := firstDMAPUint(loginResult.Data, "mlid")
if err != nil || !ok {
    log.Fatal("no session id")
}
req := store.ownedAppsUpdateRequest(acc, guid, uint32(sessionID), query, signer)
// Generates request.Body => "session-id=42&revision-number=(null)&query=..."
resp, err := store.ownedAppsClient.Send(req)

```

## Session Lifetime and Ephemeral Security Model

IPATool implements a strict ephemeral session policy. The **mlid** session is valid only for the duration of the current command execution and exists solely in memory within the `appstore` instance. After the command completes, the `appstore` object is discarded, forcing the next CLI invocation to establish a fresh session.

No long-term cookies or session tokens are stored on disk. The only persistent authentication data is the **Account** record saved in the system keychain (containing login tokens), while the short-lived mlid session must be regenerated for every operation. This design ensures that compromising the local file system does not grant access to active App Store sessions.

## Implementation Files and Code Structure

| File | Role in Session Management |
|------|---------------------------|
| [`pkg/appstore/appstore_login.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_login.go) | Implements SAP login flow, creates the ActionSigner, and handles the initial authentication handshake with Apple servers. |
| [`pkg/appstore/appstore_owned_apps.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_owned_apps.go) | Extracts the mlid (session-id) from login responses and constructs request bodies with embedded session identifiers. |
| [`pkg/appstore/appstore.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore.go) | Defines the `appstore` struct that carries the `sessionID` between method calls within a single CLI execution. |
| [`pkg/http/request.go`](https://github.com/majd/ipatool/blob/main/pkg/http/request.go) | Provides the HTTP request infrastructure for sending signed SAP payloads including the session-id parameter. |

## Summary

- IPATool uses **SAP (Store-Apple-Protocol)** for initial authentication, creating an ActionSigner from Apple's configuration bag.
- The **mlid** (machine ID) serves as the temporary session identifier extracted from login responses using `firstDMAPUint`.
- Session IDs are validated as 32-bit unsigned integers and stored in memory within the `appstore` struct.
- Every API request includes the session ID in a URL-encoded form body starting with `session-id=<mlid>`.
- Sessions are **ephemeral**—they exist only during a single command execution and are never cached between CLI runs.
- Only the **Account** credentials are persisted in the system keychain; active sessions must be re-established for each operation.

## Frequently Asked Questions

### What is the mlid in IPATool's session management?

The **mlid** (machine ID) is a temporary session identifier returned by Apple's servers after successful SAP authentication. IPATool extracts this value from the login response and uses it as the `session-id` parameter for all subsequent App Store API calls during a single command execution.

### Does IPATool store App Store sessions between commands?

No. IPATool does not persist session cookies or the mlid identifier between CLI invocations. While the **Account** credentials are stored in the system keychain for convenience, the actual App Store session must be re-established fresh for each command, ensuring no long-lived session tokens remain on disk.

### How does IPATool authenticate with Apple servers?

IPATool uses the **Store-Apple-Protocol (SAP)**, an internal Apple authentication protocol. The tool creates an ActionSigner from cryptographic parameters in Apple's configuration bag and sends signed requests containing the user's Apple ID credentials. Upon validation, Apple returns the temporary session identifier (mlid) used for subsequent requests.

### Why does IPATool validate the session ID as a 32-bit unsigned integer?

The validation in `appstore_owned_apps.go:138-144` ensures data integrity and type safety when extracting the mlid from Apple's response. By confirming the session ID fits within a 32-bit unsigned integer using `firstDMAPUint`, IPATool prevents malformed responses from causing integer overflow errors and ensures compatibility with the downstream API requirements.