How OCI Image Scheme Auto-Detection Chooses HTTP vs HTTPS in Apple Container
When configured with auto, the Apple Container CLI automatically selects HTTP for internal registries (localhost, private IPs, or internal DNS domains) and HTTPS for external hosts by evaluating the target host in RequestScheme.swift.
The apple/container repository provides a Swift-based container runtime that simplifies registry interactions by automatically selecting the appropriate transport protocol. When users specify --scheme auto or rely on the default configuration, the tooling inspects the target registry host to determine whether to use plain HTTP or encrypted HTTPS. This OCI image scheme auto-detection mechanism balances security for public registries with convenience for private, intra-cluster deployments.
How the Auto-Detection Algorithm Classifies Registry Hosts
The decision logic resides in Sources/Services/ContainerAPIService/Client/RequestScheme.swift and evaluates three specific criteria to identify internal hosts.
Internal Hosts Trigger HTTP Mode
When isInternalHost(host:internalDnsDomain:) returns true, the system selects plain HTTP. A host qualifies as internal if it meets any of the following conditions:
- Localhost: The hostname is
localhost. - Internal DNS Suffix: The hostname ends with a configured internal DNS domain (e.g.,
mycorp.local). - Private IPv4 Ranges: The address parses as an IPv4 address within these CIDR blocks:
10.0.0.0/8127.0.0.0/8(loopback)172.16.0.0/12192.168.0.0/16
External Hosts Require HTTPS
If the host fails all internal checks, the schemeFor(host:internalDnsDomain:) method returns .https, ensuring encrypted connections to public registries like Docker Hub or Amazon ECR.
Implementation Details in RequestScheme.swift
The RequestScheme type in RequestScheme.swift encapsulates the scheme selection logic. Initialization accepts http, https, or auto strings, storing them as enumerated values.
The schemeFor(host:internalDnsDomain:) method acts as the primary entry point. When the stored scheme is .auto, it delegates to isInternalHost(host:internalDnsDomain:) to perform the classification. For explicit http or https values, the method returns the corresponding scheme without host inspection.
This implementation aligns with the OCI Distribution Specification's recommendation to use HTTP for private registries where TLS termination may be unnecessary, while mandating HTTPS for external endpoints to guarantee confidentiality and integrity.
Configuring the Scheme via CLI Flags
Users control this behavior through the --scheme flag defined in Sources/Services/ContainerAPIService/Client/Flags.swift. Valid options include:
http: Force plain text (insecure)https: Force TLS encryptionauto: Enable automatic detection based on host analysis
Practical Code Examples
The following Swift examples demonstrate how RequestScheme resolves different host scenarios:
import ContainerAPIClient
// Explicit HTTP scheme
let scheme1 = try RequestScheme("http")
let result1 = try scheme1.schemeFor(host: "registry.local", internalDnsDomain: nil)
// result1 == .http
// Explicit HTTPS scheme
let scheme2 = try RequestScheme("https")
let result2 = try scheme2.schemeFor(host: "docker.io", internalDnsDomain: nil)
// result2 == .https
// Auto-detect: Private IP address (10.x.x.x)
let scheme3 = try RequestScheme("auto")
let result3 = try scheme3.schemeFor(host: "10.42.0.5", internalDnsDomain: nil)
// result3 == .http
// Auto-detect: Public registry
let scheme4 = try RequestScheme("auto")
let result4 = try scheme4.schemeFor(host: "registry-1.docker.io", internalDnsDomain: nil)
// result4 == .https
// Auto-detect: Internal DNS suffix match
let scheme5 = try RequestScheme("auto")
let result5 = try scheme5.schemeFor(host: "myregistry.mycorp.local", internalDnsDomain: "mycorp.local")
// result5 == .http
Summary
- OCI image scheme auto-detection in
RequestScheme.swiftautomatically chooses HTTP for internal registries and HTTPS for external ones. - Internal hosts include
localhost, addresses in private IPv4 ranges (10.0.0.0/8,127.0.0.0/8,172.16.0.0/12,192.168.0.0/16), or hostnames matching a configured internal DNS suffix. - External hosts automatically default to HTTPS to ensure secure communication with public registries.
- The logic is exposed through
schemeFor(host:internalDnsDomain:)andisInternalHost(host:internalDnsDomain:)methods. - Configuration is controlled via the
--schemeflag inFlags.swift.
Frequently Asked Questions
How does the auto-detection distinguish between internal and external registries?
The isInternalHost function in RequestScheme.swift checks three criteria: whether the hostname is localhost, whether it matches a configured internal DNS domain suffix, or whether it parses as a private IPv4 address within the RFC 1918 ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) or loopback (127.0.0.0/8). If any check passes, the registry is considered internal.
Can I force HTTPS for a private IP address or localhost?
Yes. While auto mode would select HTTP for private IPs, you can override this by explicitly setting the scheme to https via the --scheme https CLI flag defined in Flags.swift, or by initializing RequestScheme with the string "https" in code.
What happens if I specify an invalid scheme value?
The RequestScheme initializer throws an error if provided with a value other than http, https, or auto. This validation ensures that the scheme selection remains strictly controlled and prevents accidental misconfiguration.
Where is the auto-detection logic tested?
Comprehensive unit tests covering the auto behavior for both HTTP and HTTPS scenarios are located in Tests/ContainerAPIClientTests/RequestSchemeTests.swift. These tests verify the correct classification of localhost, private IP ranges, internal DNS domains, and public hostnames.
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 →