# How IPATool Injects iTunesMetadata.plist During App Store Downloads

> Discover how IPATool injects iTunesMetadata.plist during app downloads. Learn about streaming encrypted IPAs and appending user metadata via the writeMetadata function.

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

---

**IPATool injects the iTunesMetadata.plist file by streaming the encrypted IPA into a new ZIP archive while appending a binary plist containing the user's Apple ID and App Store metadata through the `writeMetadata` function.**

When you download an app using `ipatool download`, the tool doesn't simply save the raw encrypted payload from Apple's servers. Instead, it processes the archive to inject a valid **iTunesMetadata.plist** file, ensuring the resulting IPA package appears as a legitimate App Store download to iOS and macOS systems. This injection happens seamlessly during the download workflow implemented in the `majd/ipatool` repository.

## The Three-Step Injection Pipeline

The injection process is orchestrated by the `applyPatches` function in [`pkg/appstore/appstore_download.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download.go). This pipeline preserves the original encrypted app while seamlessly appending the required metadata file.

### Step 1: Downloading the Raw Encrypted IPA

The process begins when `appstore.Download` retrieves the encrypted package from Apple's servers and writes it to a temporary file location. At this stage, the archive contains the app payload but lacks the metadata file required for proper identification on Apple devices. The download operation establishes the source reader that will be used in the replication phase.

### Step 2: Replicating the Original ZIP Structure

Before injection occurs, `applyPatches` creates a new destination ZIP writer and invokes `replicateZip` (defined in [`pkg/appstore/appstore_replicate_sinf.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_replicate_sinf.go)) to perform a raw byte-for-byte copy of every entry from the source archive. This method preserves cryptographic signatures, resource files, and the original directory structure without modification. By replicating the entire payload first, IPATool ensures the integrity of the encrypted app data remains intact before the new metadata entry is added.

### Step 3: Creating and Injecting iTunesMetadata.plist

After the replication completes, `applyPatches` calls `writeMetadata` to inject the **iTunesMetadata.plist** file. This function:

- Enriches the App Store metadata map with the user's **Apple ID** (`apple-id`) and **username** (`userName`)
- Creates a new ZIP entry named `iTunesMetadata.plist` using `zip.Create()`
- Marshals the metadata into Apple's binary plist format using the `howett.net/plist` library with `plist.BinaryFormat`
- Writes the binary data directly into the new archive entry

## Core Implementation: The writeMetadata Function

The actual injection logic resides in the `writeMetadata` method inside [`pkg/appstore/appstore_download.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download.go). This function handles the binary encoding and file creation:

```go
func (t *appstore) writeMetadata(metadata map[string]interface{}, acc Account, zip *zip.Writer) error {
    // Insert required Apple-ID fields
    metadata["apple-id"] = acc.Email
    metadata["userName"]  = acc.Email

    // Create the plist entry inside the zip
    metadataFile, err := zip.Create("iTunesMetadata.plist")
    if err != nil { 
        return fmt.Errorf("failed to create file: %w", err) 
    }

    // Encode the map as a binary plist
    data, err := plist.Marshal(metadata, plist.BinaryFormat)
    if err != nil { 
        return fmt.Errorf("failed to marshal data: %w", err) 
    }

    // Write the binary plist to the zip entry
    _, err = metadataFile.Write(data)
    if err != nil { 
        return fmt.Errorf("failed to write data: %w", err) 
    }

    return nil
}

```

This implementation ensures the metadata file uses Apple's native binary plist format rather than XML, which is essential for compatibility with iTunes and Configurator.

## CLI Integration: Triggering the Download Flow

The injection pipeline is triggered from [`cmd/download.go`](https://github.com/majd/ipatool/blob/main/cmd/download.go) through the `downloadCmd` implementation. When a user executes the download command, the CLI invokes the `Download` method with the required account and app parameters:

```go
out, err := dependencies.AppStore.Download(appstore.DownloadInput{
    Account:    acc,
    App:        app,
    OutputPath: outputPath,
    Progress:   progressBar,
})
if err != nil { 
    return err 
}

// After download, the IPA now contains iTunesMetadata.plist
fmt.Println("Saved to:", out.DestinationPath)

```

The `Download` method returns a path to the final IPA, which now contains the injected metadata file alongside the original encrypted application payload.

## Summary

- **IPATool** injects **iTunesMetadata.plist** during the download process to create valid App Store archives.
- The `applyPatches` function in [`pkg/appstore/appstore_download.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download.go) orchestrates the three-phase injection pipeline.
- **`replicateZip`** preserves the original encrypted content by copying entries before metadata injection.
- **`writeMetadata`** creates the plist file, adds the user's **Apple ID** and **username**, and encodes the data using the **howett.net/plist** library in binary format.
- The resulting IPA file contains both the original encrypted app and the metadata required for device recognition.

## Frequently Asked Questions

### What is the purpose of iTunesMetadata.plist in an IPA file?

The **iTunesMetadata.plist** file contains App Store purchase information, including the buyer's Apple ID, purchase date, and app metadata. iOS and macOS use this file to verify the app originated from the App Store and to associate the installation with the correct user account. Without this file, systems may reject the IPA or fail to install it properly.

### Which Go library does IPATool use to generate the binary plist?

IPATool uses the **`howett.net/plist`** library to marshal the metadata map into Apple's binary plist format. Specifically, the code calls `plist.Marshal(metadata, plist.BinaryFormat)` to ensure the output matches the format expected by iTunes and Apple Configurator, rather than using the XML plist format.

### Does IPATool modify existing files inside the IPA during injection?

No, IPATool does not modify existing files inside the original archive. The **`replicateZip`** function performs a raw byte-for-byte copy of every existing entry into the new ZIP writer before `writeMetadata` adds the new metadata file. This preservation approach maintains the cryptographic integrity of the encrypted app payload and ensures no corruption occurs during the injection process.

### Where in the source code is the injection logic implemented?

The core injection logic is implemented in **[`pkg/appstore/appstore_download.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_download.go)**, specifically within the `applyPatches` and `writeMetadata` functions. The `applyPatches` function coordinates the workflow, while `writeMetadata` handles the specific task of creating and writing the **iTunesMetadata.plist** entry. The low-level ZIP replication helper, `replicateZip`, is defined in **[`pkg/appstore/appstore_replicate_sinf.go`](https://github.com/majd/ipatool/blob/main/pkg/appstore/appstore_replicate_sinf.go)**.