# How to Specify a Passphrase for the IPATool Keychain

> Learn how to specify a passphrase for the IPATool keychain with the global --keychain-passphrase flag. Unlock Apple ID credentials securely in non-interactive mode.

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

---

**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`](https://github.com/majd/ipatool/blob/main/cmd/root.go) at line 46, meaning it is available to all subcommands (`download`, `search`, `list-purchases`, etc.):

```go
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`](https://github.com/majd/ipatool/blob/main/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`](https://github.com/majd/ipatool/blob/main/cmd/common.go) lines 74-80), the code enforces strict validation rules:

```go
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:

```bash
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:

```bash
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`:

```bash
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:

```bash
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`](https://github.com/majd/ipatool/blob/main/pkg/keychain/keychain.go).

## Summary

- The `--keychain-passphrase` flag is defined in [`cmd/root.go`](https://github.com/majd/ipatool/blob/main/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`](https://github.com/majd/ipatool/blob/main/cmd/common.go) (lines 74-80).
- The variable `keychainPassphrase` in [`cmd/common.go`](https://github.com/majd/ipatool/blob/main/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`](https://github.com/majd/ipatool/blob/main/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`](https://github.com/majd/ipatool/blob/main/pkg/keychain/keychain.go).