How to Specify a Passphrase for the IPATool Keychain

You can specify a passphrase for the IPATool keychain using the global --keychain-passphrase flag, which is required when running in non-interactive mode to unlock stored Apple ID credentials.

The open-source tool majd/ipatool stores Apple ID credentials in a local encrypted keychain using the github.com/byteness/keyring library. When automating downloads in CI pipelines or scripts, the tool cannot prompt for interactive input, making the passphrase flag essential for authentication. According to the source code, this flag is defined as a persistent global option available across all subcommands.

Understanding the --keychain-passphrase Flag

The --keychain-passphrase flag is registered as a persistent flag in cmd/root.go at line 46, meaning it is available to all subcommands (download, search, list-purchases, etc.):

cmd.PersistentFlags().
    StringVar(&keychainPassphrase, "keychain-passphrase", "", "passphrase for unlocking keychain")

The flag value is stored in the package-level variable keychainPassphrase declared in cmd/common.go at line 26. This variable holds the user-supplied string for the duration of the command execution.

How Passphrase Validation Works

During keychain initialization in the newKeychain function (located in cmd/common.go lines 74-80), the code enforces strict validation rules:

if keychainPassphrase == "" && !interactive {
    return "", errors.New("keychain passphrase is required when not running in interactive mode; use the \"--keychain-passphrase\" flag")
}
if keychainPassphrase != "" {
    return keychainPassphrase, nil
}

This logic implements two distinct behaviors:

  • Interactive mode: If the interactive boolean is true and no passphrase is provided, the underlying keyring library prompts the user to enter the passphrase manually.
  • Non-interactive mode: If interactive is false and keychainPassphrase is empty, the tool immediately returns an error and exits.

Usage Examples

Interactive Mode

When running IPATool manually in a terminal, omit the flag to receive an interactive prompt:

ipatool download -i 123456789 --purchase

The tool will pause and request the passphrase via the secure keyring interface provided by the operating system.

Non-Interactive Mode (CI/CD)

For automated scripts, pipelines, or scheduled tasks, you must provide the passphrase explicitly:

ipatool download -i 123456789 --purchase \
    --non-interactive \
    --keychain-passphrase "mySecretPassphrase"

Without the --keychain-passphrase flag in non-interactive mode, the execution fails with the error: "keychain passphrase is required when not running in interactive mode; use the '--keychain-passphrase' flag".

Combining with Other Flags

The global flag works alongside other persistent options such as --format and --verbose:

ipatool list-purchases --format json --non-interactive \
    --keychain-passphrase "mySecretPassphrase"

Security Considerations

Command-line visibility: The flag value appears in the process list (ps) while the command executes, which may expose the passphrase to other users on shared systems.

Alternative approaches: For highly sensitive environments, avoid passing the passphrase directly in the command. Instead, use a secret-management tool that injects the value via a temporary file or environment variable, then reference it within a wrapper script:

ipatool download -i 123456789 --non-interactive \
    --keychain-passphrase "$(cat /run/secrets/keychain_pass)"

The actual encryption and decryption operations are handled by the underlying github.com/byteness/keyring implementation defined in pkg/keychain/keychain.go.

Summary

  • The --keychain-passphrase flag is defined in cmd/root.go (line 46) as a persistent global flag available to all IPATool subcommands.
  • In non-interactive mode, the flag is mandatory; omitting it triggers an error from the validation logic in cmd/common.go (lines 74-80).
  • The variable keychainPassphrase in cmd/common.go (line 26) stores the flag value for use by the keyring backend.
  • Interactive sessions can omit the flag and enter the passphrase when prompted by the operating system's keyring dialog.

Frequently Asked Questions

What happens if I don't provide a passphrase in non-interactive mode?

The tool aborts immediately with the error message: "keychain passphrase is required when not running in interactive mode; use the '--keychain-passphrase' flag". This check occurs in cmd/common.go during the initialization of the keychain backend before any network requests are made.

Is the --keychain-passphrase flag secure?

The flag itself provides the necessary functionality for automation, but the passphrase value is visible in process listings while the command runs. For production environments, inject the passphrase via a file or environment variable rather than hardcoding it in scripts or CI configuration files.

Can I use environment variables instead of the flag?

IPATool does not natively read from a specific environment variable for the keychain passphrase. However, you can map an environment variable to the flag using shell substitution: --keychain-passphrase "$IPATOOL_PASSPHRASE". This keeps secrets out of shell history while still satisfying the non-interactive requirement.

Where does IPATool store the encrypted credentials?

The credentials are stored using the github.com/byteness/keyring library, which delegates to the host operating system's native secure storage (macOS Keychain, Windows Credential Manager, or Linux Secret Service). The specific storage location depends on the OS and the configuration in pkg/keychain/keychain.go.

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 →