How to Download Encrypted .ipa Packages with IPATool

IPATool downloads encrypted iOS app packages by authenticating with Apple's private App Store API, constructing a device-specific download request, and patching the resulting ZIP with metadata to produce a valid .ipa file.

IPATool is an open-source command-line utility that enables developers to retrieve encrypted iOS, iPadOS, tvOS, and visionOS app packages directly from Apple's servers. Understanding how to download encrypted .ipa packages with IPATool requires insight into its multi-stage architecture, which handles authentication, license acquisition, resumable file transfers, and post-download metadata injection. The implementation spans several packages in the majd/ipatool repository, with the core orchestration logic residing in cmd/download.go and the download mechanics implemented in pkg/appstore/appstore_download.go.

Prerequisites and Authentication Flow

Before any download begins, IPATool establishes a valid authenticated session with Apple's services. The download command in cmd/download.go initiates this flow by invoking AppStore.AccountInfo() to retrieve stored credentials from the system keychain.

If the session token has expired, the tool automatically re-authenticates using AppStore.Login() with the stored Apple ID credentials. This ensures that the subsequent download request includes a valid authentication token without requiring manual re-entry of passwords.

Handling License Requirements

When an application requires a purchase that the Apple ID has not previously acquired, IPATool returns ErrLicenseRequired. If the user supplies the --purchase flag, the command automatically invokes AppStore.Purchase() from pkg/appstore/appstore_purchase.go to acquire the license before proceeding with the download.

Locating the Target Application

IPATool accepts either a numeric App ID or a Bundle Identifier to locate the target package. When a bundle identifier is provided via the --bundle-identifier flag, the command calls AppStore.Lookup() from pkg/appstore/appstore_lookup.go to resolve the corresponding numeric App ID. This lookup occurs in cmd/download.go before the download request is constructed, ensuring the correct asset is targeted.

Constructing and Executing the Download Request

The core download logic resides in pkg/appstore/appstore_download.go. The AppStore.Download() method builds a POST request containing the device GUID, the numeric App ID, and optionally an external version ID (required for tvOS and visionOS platforms). This request is sent to Apple's private download endpoint.

Handling API Errors

The response handler monitors for specific failure conditions defined in the App Store package. If the server returns ErrPasswordTokenExpired, the command bubbles this error up to the retry logic in cmd/download.go, triggering a re-authentication cycle. Similarly, ErrLicenseRequired prompts an automatic purchase attempt when the appropriate flag is set.

Streaming and Resumable Downloads

IPATool implements robust file handling to support large packages and interrupted connections. The downloadFile() function in pkg/appstore/appstore_download.go manages this process through the following steps:

  1. Creates a temporary file named <destination>.tmp to store incoming data.
  2. Checks the existing file size to support resumption.
  3. Issues an HTTP GET request with a Range header specifying the byte offset to continue from.
  4. Streams the response body to both the temporary file and an optional progress bar.

If a download is interrupted, rerunning the same command detects the partial file and resumes from the last received byte rather than starting over.

Post-Processing and Platform Validation

After the raw encrypted ZIP downloads successfully, IPATool performs critical post-processing to ensure the package is usable with iTunes or Xcode.

Metadata Injection

The applyPatches() function in pkg/appstore/appstore_download.go rewrites the downloaded ZIP archive while replicating all original entries. During this process, it injects an iTunesMetadata.plist file containing the Apple ID of the downloader. This metadata is essential for the resulting .ipa file to be recognized by Apple's deployment tools.

Platform-Specific Verification

For tvOS and visionOS packages, the tool performs additional validation through validatePackagePlatform(). This function extracts the top-level Info.plist from the downloaded archive and inspects the CFBundleSupportedPlatforms array to verify that the binary explicitly declares support for the requested platform (e.g., AppleTVOS or visionOS). If the platform check fails, the download is rejected and the temporary file is removed.

Command-Line Usage Examples

The following examples demonstrate practical usage of the download subcommand:


# Basic download using the numeric App ID

ipatool download --app-id 1234567890 --output MyApp.ipa

# Download by bundle identifier (overrides App ID)

ipatool download --bundle-identifier com.example.myapp --output MyApp.ipa

# Download a specific tvOS version (requires external version ID)

ipatool download \
  --app-id 1234567890 \
  --platform appletv \
  --external-version-id 2.3.4 \
  --output MyApp_tvOS.ipa

# Automatically purchase the app if a license is missing

ipatool download --app-id 1234567890 --purchase --output MyApp.ipa

Key Flags Reference

  • --app-id / -i: Numeric App Store identifier (required if --bundle-identifier is not supplied).
  • --bundle-identifier / -b: Bundle ID string that overrides the App ID.
  • --output / -o: Destination path for the downloaded .ipa.
  • --external-version-id: Specific version identifier for tvOS/visionOS packages.
  • --platform: Target platform (iphone, ipad, appletv, or visionos).
  • --purchase: Automatically acquires the license if the app is not already owned.

Summary

  • Authentication is automatic: IPATool retrieves stored credentials via AppStore.AccountInfo() and refreshes sessions using AppStore.Login() before initiating downloads.
  • Resumable downloads supported: The downloadFile() function uses HTTP Range headers to resume interrupted transfers, writing to temporary .tmp files before finalizing.
  • Metadata injection is mandatory: The applyPatches() function ensures downloaded packages contain a valid iTunesMetadata.plist with the downloader's Apple ID.
  • Platform validation built-in: For tvOS and visionOS, validatePackagePlatform() verifies CFBundleSupportedPlatforms in Info.plist before accepting the download.
  • License handling is integrated: The tool can automatically purchase apps via AppStore.Purchase() when the --purchase flag is provided.

Frequently Asked Questions

What authentication methods does IPATool use to download encrypted .ipa files?

IPATool authenticates using Apple ID credentials stored securely in the operating system keychain. The tool retrieves these credentials through AppStore.AccountInfo() and validates or refreshes the session token via AppStore.Login() as implemented in pkg/appstore/appstore_login.go. This process occurs automatically before any download request is sent to Apple's servers.

Can IPATool resume interrupted downloads?

Yes. IPATool supports resumable downloads through HTTP Range requests. The downloadFile() implementation in pkg/appstore/appstore_download.go checks the size of the existing temporary file and sends a Range header with the appropriate byte offset. This allows the download to continue from where it left off rather than restarting, which is essential for large iOS packages.

Why does IPATool inject iTunesMetadata.plist into downloaded packages?

The applyPatches() function injects iTunesMetadata.plist because the raw encrypted ZIP returned by Apple's download endpoint lacks the metadata required by iTunes and Xcode to recognize and process the package. This plist file contains the downloader's Apple ID and other purchase information, making the .ipa file valid for sideloading and archival purposes.

How does IPATool handle platform-specific packages like tvOS or visionOS?

For tvOS and visionOS downloads, IPATool requires the --platform flag (set to appletv or visionos) and optionally the --external-version-id flag. After downloading, validatePackagePlatform() extracts the Info.plist and verifies that the CFBundleSupportedPlatforms array includes the target platform. This prevents downloading iOS versions of apps when a specific tvOS or visionOS binary is required.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →