How to Configure Registry Authentication and Manage Multiple Registry Credentials in Apple Container
Apple Container stores default registry settings in a config.toml file and securely manages multiple credentials using the macOS Keychain, enabling seamless authentication across different container registries without exposing sensitive data.
The apple/container project provides a robust authentication system that separates configuration from credentials. Developers can configure registry authentication for various environments while the system handles credential storage securely through native macOS APIs.
Configure Default Registry Settings
Apple Container uses a TOML configuration file to define default registry behavior. The system parses these settings through Sources/ContainerPersistence/ContainerSystemConfig.swift.
Understanding the config.toml Structure
The [registry] table in config.toml defines the default domain assumed when an image reference lacks an explicit registry host. By default, this value is "docker.io":
[registry]
domain = "docker.io"
Setting a Custom Default Domain
To change the default registry for all commands, modify the domain key in your configuration file:
cat >> ~/.config/container/config.toml <<EOF
[registry]
domain = "my-registry.example.com"
EOF
This setting applies globally, allowing you to use shorthand image names without specifying the registry host each time.
Authenticate with Container Registries
The container registry login command handles authentication with container registries, storing credentials securely in the macOS Keychain rather than plaintext files.
Interactive Login
To authenticate interactively, run the login command with the server hostname:
container registry login my-registry.example.com
The CLI prompts for username and password, then stores the credentials in the Keychain via RegistryResource.swift.
Non-Interactive Login for CI/CD
For automated pipelines, pass credentials via flags to avoid interactive prompts:
echo "$REGISTRY_TOKEN" | container registry login \
--username "$REGISTRY_USER" \
--password-stdin \
my-registry.example.com
This approach stores the credentials securely without exposing them in shell history or process lists.
Connection Scheme Configuration
The --scheme flag controls whether the client uses HTTP or HTTPS. The default value auto intelligently selects the protocol based on the registry address:
- Internal registries: Loopback addresses, RFC1918 private networks, or the host's default DNS domain use HTTP
- External registries: All other addresses use HTTPS
container push \
--scheme http \
my-internal-registry.local/myrepo/app:latest
Explicitly set --scheme https to force encrypted connections, or --scheme http for insecure internal testing.
Manage Multiple Registry Credentials
Apple Container supports unlimited registry credentials simultaneously, automatically selecting the appropriate set based on the image reference hostname.
Storing Credentials per Registry
Each call to container registry login creates a separate Keychain entry keyed by the server name. The system stores credentials for docker.io, my-registry.example.com, and ghcr.io concurrently without conflicts:
container registry login docker.io
container registry login ghcr.io
container registry login my-registry.example.com
When you reference an image, the CLI retrieves the matching credentials automatically based on the registry host in the image path.
Listing Stored Credentials
The container registry list command displays hostnames with stored credentials without exposing secret values:
# Human-readable output
container registry list
# Quiet mode - hostnames only
container registry list -q
# Machine-readable JSON
container registry list --format json
Removing Registry Credentials
To revoke authentication for a specific registry, use the logout command:
container registry logout my-registry.example.com
This removes the associated Keychain entry entirely, requiring re-authentication on subsequent access attempts.
Implementation Details
The authentication system relies on two primary components in the codebase:
Configuration Parsing: Sources/ContainerPersistence/ContainerSystemConfig.swift parses the config.toml file and exposes the default registry configuration to the rest of the application.
Credential Management: Sources/ContainerPersistence/RegistryResource.swift handles all Keychain interactions, implementing secure storage and retrieval of username-password pairs keyed by registry hostname.
The test suite in Tests/ContainerResourceTests/RegistryResourceTests.swift validates hostname parsing and credential selection logic, ensuring reliable matching between image references and stored credentials.
Summary
- Default registry: Configure the
[registry]table inconfig.tomlto set a custom domain for shorthand image references - Secure storage: Credentials are encrypted in the macOS Keychain via
RegistryResource.swift, never stored in configuration files - Multiple registries: Store unlimited credentials keyed by hostname; the system automatically selects the correct set based on the image reference
- Connection control: Use
--scheme autofor intelligent HTTP/HTTPS selection, or override with explicithttporhttpsvalues - Credential lifecycle: Use
container registry loginto add,container registry listto view, andcontainer registry logoutto remove authentication data
Frequently Asked Questions
Where does Apple Container store registry passwords?
Apple Container stores registry passwords in the macOS Keychain, not in the config.toml file or environment variables. The RegistryResource.swift module handles all credential storage and retrieval through native Security framework APIs, ensuring passwords remain encrypted and accessible only to the application.
How do I switch between different registry credentials?
You do not need to manually switch credentials. Apple Container automatically selects the appropriate credential set based on the registry hostname extracted from the image reference. When you run container pull ghcr.io/user/app, the system retrieves the ghcr.io credentials; for docker.io/library/nginx, it uses the Docker Hub credentials.
Can I use HTTP instead of HTTPS for internal registries?
Yes. Use the --scheme http flag when pushing or pulling images to force unencrypted connections. Alternatively, use --scheme auto (the default), which automatically detects internal addresses—including loopback interfaces, RFC1918 private networks, and the host's default DNS domain—and uses HTTP for these while maintaining HTTPS for external registries.
How do I configure a default registry for all operations?
Set the domain key in the [registry] section of your config.toml file. This value, parsed by ContainerSystemConfig.swift, defines the assumed registry when an image reference does not contain an explicit host. Change this from the default "docker.io" to your private registry to enable shorthand image names across all commands.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →