TLS Imports & On-Demand Configuration
Relevant source files
The following files were used as context for generating this wiki page:
TLS Imports and On-Demand Configuration provide mechanisms for kamal-proxy to manage SSL/TLS certificates dynamically and facilitate transitions from other proxy solutions like Traefik. The system supports offline importation of existing ACME certificates to ensure immediate TLS availability during migration, while on-demand TLS allows the proxy to provision certificates for arbitrary hostnames by consulting a validation endpoint during the TLS handshake.
These features integrate with the SANCertManager to handle Subject Alternative Name (SAN) batching and the autocert manager for individual certificate fulfillment. The configuration also enforces minimum security standards by defining acceptable TLS versions for the HTTPS listener.
Sources: internal/server/traefik_import.go:48-55, internal/server/tls_on_demand.go:12-20, internal/server/san_cert_manager.go:61-70
Traefik Certificate Import
The Traefik import system is designed to seed the SAN certificate store from a Traefik acme.json file. This offline process occurs before the proxy boots, allowing the fleet to serve TLS immediately upon cutover, thereby avoiding ACME issuance rate limits.
Import Logic and Conflict Resolution
The import process reads resolver blocks from the source file. If a domain is present in multiple resolvers, the last writer (based on sorted resolver names) wins the certificate. For domains already mapped in an existing kamal-proxy state file, the proxy keeps the existing certificate if it outlives the imported one.
Key Import Components
| Component | Description |
|---|---|
TraefikImportOptions | Configuration for paths (acme.json, cert store, state file) and resolver selection. |
ImportTraefikCertificates | The entry point function for the offline import process. |
traefikImport | Internal struct maintaining merge state and domain claims during a run. |
sanCertID | Generates collision-resistant IDs from domain lists for the SAN store. |
Sources: internal/server/traefik_import.go:20-35, internal/server/traefik_import.go:431-438
TLS On-Demand Configuration
On-demand TLS enables the proxy to issue certificates during the handshake for hostnames not explicitly registered at deploy time. This is managed via a per-handshake gate that consults an "ask" endpoint to authorize certificate issuance.
The On-Demand Workflow
When a TLS request arrives for an unknown host, the TLSOnDemandChecker intercepts the process. It first checks if a certificate already exists in the cache. If not, it queries the configured TLSOnDemandURL.
Authorization Endpoint Contract
The authorization endpoint must return a 2xx status code to approve issuance. The proxy provides the hostname via a host query parameter. To prevent SSRF (Server-Side Request Forgery), the proxy does not follow redirects from this endpoint and truncates large response bodies.
Sources: internal/server/tls_on_demand.go:102-115, internal/server/tls_on_demand.go:134-142
TLS Version Enforcement
kamal-proxy allows administrators to define the minimum TLS version supported by the HTTPS listener. This is primarily used for compliance and security hardening.
Supported Versions
The proxy supports TLS 1.2 and TLS 1.3. Attempts to configure versions lower than 1.2 (e.g., TLS 1.0 or 1.1) are explicitly refused to prevent security downgrades.
| Configuration Value | Internal Constant | Description |
|---|---|---|
1.2 (Default) | tls.VersionTLS12 | Standard minimum for modern web traffic. |
1.3 | tls.VersionTLS13 | Stricter security with faster handshakes. |
Sources: internal/server/tls_version.go:11-30
Normalization
The proxy normalizes various string formats to ensure compatibility with different configuration styles, such as converting TLSv1.3 or tls1_3 to the standard 1.3 format.
Sources: internal/server/tls_version.go:36-47
Service-Level Configuration
TLS settings are defined within ServiceOptions and applied during service initialization.
type ServiceOptions struct {
Hosts []string `json:"hosts"`
TLSEnabled bool `json:"tls_enabled"`
TLSCertificatePath string `json:"tls_certificate_path"`
TLSPrivateKeyPath string `json:"tls_private_key_path"`
TLSOnDemandURL string `json:"tls_on_demand_url"`
TLSRedirect bool `json:"tls_redirect"`
ACMEDirectory string `json:"acme_directory"`
ACMECachePath string `json:"acme_cache_path"`
}
Sources: internal/server/service.go:82-95
Validation Rules
- Host Requirement: TLS requires a non-empty host unless
TLSOnDemandURLorTLSDomainsSourceis provided. - Root Path: TLS settings must be specified on the root path (
/) service. - Mutual Exclusivity: Custom TLS certificates cannot be used simultaneously with a TLS on-demand URL.
Sources: internal/server/service.go:167-185
TLS Imports and On-Demand Configuration ensure that kamal-proxy remains flexible for both static deployments and dynamic, multi-tenant environments while maintaining a secure default posture through version enforcement and robust import logic.