# How IPATool Handles Apple Private API Authentication: A Technical Deep Dive into SAP

> Discover how IPATool handles Apple private API authentication using SAP, including machine ID generation, cryptographic signing, and session token management for secure App Store interactions.

- Repository: [Majd/ipatool](https://github.com/majd/ipatool)
- Tags: deep-dive
- Published: 2026-08-31

---

**IPATool authenticates with Apple’s private App Store API by generating a unique machine ID, cryptographically signing each request with Apple’s embedded private key using the Secure Authentication Protocol (SAP), and maintaining a signed session token for all subsequent private API calls.**

IPATool is an open-source command-line interface for interacting with the iOS App Store. To access Apple’s undocumented endpoints for searching and downloading apps, the tool implements **Apple private API authentication** through a reverse-engineered flow that mirrors official Apple services, using cryptographic signatures to satisfy Apple’s server-side security requirements.

## Device Fingerprinting and Machine ID Generation

Every authentication session begins with device identification. In [`pkg/appstore/machine_id.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/machine_id.go), IPATool derives a unique **machine ID** from local hardware characteristics to simulate a legitimate Apple device.

The tool loads **SAPConfig** from the environment, which contains critical authentication parameters including the auth endpoint URL and device description. This configuration establishes the foundation for the Secure Authentication Protocol handshake.

## Initializing the Action Signer

The cryptographic core of IPATool resides in the `ActionSigner` interface defined in [`pkg/appstore/action_signer.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/action_signer.go). The `ActionSignerFactory` creates an implementation via `defaultActionSignerFactory`, which instantiates a local SAP signer from [`internal/sap/signer_local.go`](https://github.com/majd/ipatool/blob/main/internal/sap/signer_local.go).

This signer holds a private key that Apple bundles within its official tools. The `Sign(data []byte)` method produces cryptographic signatures that Apple’s servers require to validate request authenticity.

## Constructing and Signing the Login Request

In [`pkg/appstore/appstore_login.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_login.go), the tool builds an `http.Request` containing:

- User credentials (email and password)
- Optional two-factor authentication code (`authCode`)
- Client-generated **GUID** and **machine ID**

The request body is marshaled into Apple’s proprietary plist (Property List) format. When executing the request, [`pkg/http/client.go`](https://github.com/majd/ipatool/blob/main/pkg/http/client.go) checks for the presence of `req.ActionSigner`. If present, the client calls the signer’s `Sign()` method on the serialized payload and injects the resulting signature into the `X-Apple-ActionSignature` header.

This header satisfies Apple’s strict requirement that every private API request must carry a valid cryptographic signature proving the client possesses the private key.

## Session Establishment and Reuse

The signed request is POSTed to the SAP endpoint (typically `/login`). IPATool uses a custom HTTP transport that handles cookies and redirects identically to Apple’s native applications.

Upon receiving the response, `parseLoginResponse` in [`appstore_login.go`](https://github.com/majd/ipatool/blob/main/appstore_login.go) unmarshals the plist-formatted body into an `Account` structure. The extractor pulls the **session ID** (`mlid`) from the response, which serves as the authentication token for subsequent operations.

All later private API calls—whether searching apps, viewing purchase history, or downloading IPAs through methods in [`pkg/appstore/appstore.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore.go)—include this session ID and reuse the same `ActionSigner` instance, ensuring every request remains cryptographically signed.

## Code Examples

The following example demonstrates authenticating through IPATool’s high-level API:

```go
loginResult, err := dependencies.AppStore.Login(appstore.LoginInput{
    Email:    "user@example.com",
    Password: "••••••••",
    AuthCode: "",        // optional 2‑FA code
})
if err != nil {
    log.Fatalf("login failed: %v", err)
}
fmt.Printf("Authenticated as %s (session %d)\n", loginResult.Account.Address.Email, loginResult.Account.SessionID)

```

For advanced use cases, you can manually construct and sign requests:

```go
// 1. Prepare a signer (the default factory pulls the embedded private key)
signer, _ := internalsap.NewSigner(context.Background(), internalsap.Config{
    AuthEndpoint: "https://albert.apple.com/auth",
})

// 2. Build a request payload (Apple expects a plist)
payload := []byte(`<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict>…</dict></plist>`)

// 3. Sign the payload
sig, _ := signer.Sign(payload)

// 4. Attach the signature and send
req, _ := http.NewRequest("POST", "https://albert.apple.com/auth/login", bytes.NewReader(payload))
req.Header.Set("X-Apple-ActionSignature", base64.StdEncoding.EncodeToString(sig))
resp, _ := http.DefaultClient.Do(req)

```

## Summary

- IPATool implements **Apple private API authentication** by reverse-engineering the Secure Authentication Protocol (SAP) used by official Apple tools.
- The [`machine_id.go`](https://github.com/majd/ipatool/blob/main/machine_id.go) file generates hardware-derived identifiers, while [`action_signer.go`](https://github.com/majd/ipatool/blob/main/action_signer.go) and [`signer_local.go`](https://github.com/majd/ipatool/blob/main/signer_local.go) handle cryptographic signing using Apple’s embedded private keys.
- Every request requires an `X-Apple-ActionSignature` header generated by the `ActionSigner` to satisfy Apple’s server-side validation.
- The authentication flow in [`appstore_login.go`](https://github.com/majd/ipatool/blob/main/appstore_login.go) handles credential submission, two-factor authentication, and session token extraction.
- Once authenticated, the session ID (`mlid`) is reused across all subsequent private API calls in [`appstore.go`](https://github.com/majd/ipatool/blob/main/appstore.go), maintaining persistent access without re-authentication.

## Frequently Asked Questions

### What is the Secure Authentication Protocol (SAP) in Apple’s private API?

The Secure Authentication Protocol is Apple’s proprietary authentication mechanism for internal App Store services. It requires clients to cryptographically sign each request using a private key bundled with Apple’s official software, preventing unauthorized third-party access to private API endpoints.

### How does IPATool obtain the private key for signing requests?

IPATool extracts and utilizes the private key that Apple embeds within its official tools. The [`internal/sap/signer_local.go`](https://github.com/majd/ipatool/blob/main/internal/sap/signer_local.go) implementation loads this key to create valid signatures that Apple’s servers accept as legitimate, allowing IPATool to satisfy the SAP requirements without exposing user credentials.

### Does IPATool support two-factor authentication?

Yes. The `LoginInput` struct in [`pkg/appstore/appstore_login.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_login.go) accepts an optional `AuthCode` parameter. When Apple’s API returns a 2FA challenge, users can provide their current authentication code to complete the login process and obtain a valid session token for subsequent API calls.

### Where is the session token stored between IPATool commands?

The session ID (`mlid`) extracted during login is maintained within the `Account` structure and passed to subsequent method calls in [`pkg/appstore/appstore.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore.go). The tool handles session persistence internally, reusing the established session for search, download, and other private API operations without requiring repeated authentication.