# How to Authenticate with Private Container Registries Using Apple Container

> Streamline private container registry access with Apple Container. Learn how to authenticate using `container registry login` for seamless pull and push operations.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-07-10

---

**Apple Container authenticates with private registries by storing credentials in the macOS or iOS Keychain via the `container registry login` command, which creates a `BasicAuthentication` record that subsequent pull and push operations reuse automatically.**

The `apple/container` repository provides a Swift-based container management tool that handles registry authentication through the system Keychain. When working with private container registries, you must establish authenticated sessions before pushing or pulling images. This guide explains the authentication flow implemented in the source code, including how credentials are stored, verified, and managed.

## How Registry Authentication Works

Apple Container persists registry credentials using the **KeychainHelper** utility, making them available across tool invocations without requiring repeated prompts. The authentication mechanism relies on **HTTP Basic Authentication** (`BasicAuthentication`), where usernames and passwords are securely stored against specific registry hostnames.

When you execute a login command, the tool resolves the registry domain, determines the appropriate HTTP scheme, and verifies credentials before persisting them. This process ensures that subsequent `container image pull` or `container image push` commands can retrieve credentials automatically from the Keychain.

## The container registry login Command

The `container registry login` command, implemented in [`Sources/ContainerCommands/Registry/RegistryLogin.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Registry/RegistryLogin.swift), performs a six-step authentication workflow:

1. **Loads system configuration** (`ContainerSystemConfig`) to resolve the DNS domain for the target registry host (line 50).
2. **Determines the HTTP scheme** (`http`, `https`, or `auto`) based on the registry domain and internal DNS settings (line 73).
3. **Prompts for username** if the `--username` flag is omitted, checking the Keychain for existing entries (lines 64-66).
4. **Accepts password input** either interactively or via `--password-stdin` for automated scripts (lines 37-62).
5. **Instantiates a `RegistryClient`** with `BasicAuthentication` credentials and performs a ping to verify connectivity and permissions (lines 82-96).
6. **Stores validated credentials** in the Keychain under the resolved hostname for future reuse (line 96).

```bash

# Interactive login (prompts for username and password)

container registry login my.private.registry.com

# Automated login for CI/CD pipelines

echo "my-secret-token" | container registry login \
    --username myuser --password-stdin my.private.registry.com

```

## Authenticating in Interactive and Scripted Environments

For interactive development, running `container registry login <hostname>` without flags triggers a secure prompt for your username and password. The tool checks existing Keychain entries to suggest previously used usernames for the same host.

For automation and CI/CD environments, use the `--password-stdin` flag to pipe credentials securely without exposing them in shell history. This method reads the password from standard input, making it compatible with secret management systems and environment variables.

```bash

# Example with environment variable

echo "$REGISTRY_TOKEN" | container registry login \
    --username "$REGISTRY_USER" \
    --password-stdin \
    registry.example.com

```

## Managing Stored Credentials

After authentication, you can audit and maintain your stored credentials using the registry management commands.

**Listing credentials:** The `container registry list` command, implemented in [`Sources/ContainerCommands/Registry/RegistryList.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Registry/RegistryList.swift), displays all saved registry logins including hostnames, usernames, and timestamps.

**Removing credentials:** To delete stored authentication data, use `container registry logout <hostname>`. This command, found in [`Sources/ContainerCommands/Registry/RegistryLogout.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Registry/RegistryLogout.swift), removes the specific entry from the Keychain, preventing future automatic authentication to that registry.

```bash

# View all saved registry credentials

container registry list

# Remove credentials for a specific registry

container registry logout my.private.registry.com

```

## Configuration and Default Domains

The authentication system references [`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift) to load the system-wide [`config.toml`](https://github.com/apple/container/blob/main/config.toml) file. This configuration provides the default DNS domain (typically `docker.io`) when an image name omits an explicit registry host.

The `[registry]` section in [`config.toml`](https://github.com/apple/container/blob/main/config.toml) defines the `domain` key, which serves as a fallback during login operations. If you frequently work with a specific private registry, configuring this default domain streamlines the authentication process by reducing the need to specify full hostnames.

## Summary

- **Apple Container** stores registry credentials in the macOS/iOS Keychain using the `KeychainHelper` utility, enabling seamless reuse across commands.
- The **`container registry login`** command creates a `BasicAuthentication` record, verifies it via a registry ping, and persists it securely.
- Authentication supports both **interactive prompts** and **scripted workflows** via `--username` and `--password-stdin` flags.
- Use **`container registry list`** to audit stored credentials and **`container registry logout`** to remove them.
- Default registry domains are resolved through `ContainerSystemConfig` and the [`config.toml`](https://github.com/apple/container/blob/main/config.toml) file, defaulting to `docker.io` when unspecified.

## Frequently Asked Questions

### Where does Apple Container store registry credentials?

Apple Container stores credentials in the **macOS or iOS Keychain** using the internal `KeychainHelper` utility. When you run `container registry login`, the tool creates a `BasicAuthentication` record containing your username and password, then persists it under the resolved registry hostname. This allows subsequent `container image pull` and `container image push` operations to retrieve credentials automatically without additional prompts.

### How do I automate registry login in CI/CD pipelines?

For automated environments, pipe your password or token to the command using the **`--password-stdin`** flag combined with the **`--username`** flag. This avoids interactive prompts and prevents credentials from appearing in shell history. For example: `echo "$TOKEN" | container registry login --username "$USER" --password-stdin registry.example.com`. This pattern is implemented in [`Sources/ContainerCommands/Registry/RegistryLogin.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Registry/RegistryLogin.swift) (lines 37-62).

### How do I remove stored registry credentials?

Use the **`container registry logout <hostname>`** command to delete a specific credential entry from the Keychain. This command is implemented in [`Sources/ContainerCommands/Registry/RegistryLogout.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Registry/RegistryLogout.swift). After logout, subsequent pull or push operations to that registry will require re-authentication, as the `BasicAuthentication` record will no longer exist in the Keychain.

### What happens if I don't specify a registry domain when logging in?

If you omit the registry domain in certain contexts, Apple Container falls back to the **`registry.domain`** value defined in the system [`config.toml`](https://github.com/apple/container/blob/main/config.toml) file, which defaults to `docker.io`. This behavior is handled by `ContainerSystemConfig` in [`Sources/ContainerPersistence/ContainerSystemConfig.swift`](https://github.com/apple/container/blob/main/Sources/ContainerPersistence/ContainerSystemConfig.swift). However, for explicit login operations, you should always specify the full registry hostname to ensure credentials are stored under the correct key.