SSL/TLS & ACME Integration
Relevant source files
The following files were used as context for generating this wiki page:
Kamal provides a robust system for managing SSL/TLS certificates and automated certificate issuance via the ACME protocol. This integration primarily leverages kamal-proxy to handle HTTPS termination, certificate management, and on-demand TLS issuance for containerized applications.
The architecture supports three primary modes of TLS management: static custom certificates provided via secrets, automated ACME-based issuance (supporting both HTTP-01 and DNS-01 challenges), and on-demand TLS for dynamic environments. The system includes built-in validation to ensure configuration consistency and "doctor" checks to verify DNS and certificate health prior to deployment.
Sources: lib/kamal/configuration/validator/proxy.rb:10-50, lib/kamal/cli/doctor/endpoint_checks.rb:7-15
Architecture and Data Flow
The SSL/TLS configuration is defined within the proxy block of the deployment configuration. Kamal validates these settings locally before generating the appropriate execution flags for the kamal-proxy container running on remote servers.
Certificate Resolution Flow
The following diagram illustrates how Kamal resolves certificate requirements during the configuration and deployment phases.
The diagram shows the decision logic used to determine which TLS mechanism to initialize based on user configuration.
Sources: lib/kamal/configuration/validator/proxy.rb:14-60, test/configuration/proxy/tls_test.rb:15-40
ACME Configuration
Kamal supports automated certificate management through the proxy/run/acme configuration block. This configuration is translated into command-line flags for the kamal-proxy binary.
Key ACME Parameters
| Parameter | Description | Requirement |
|---|---|---|
email | The email address used for ACME registration. | Required if ACME is set |
dns_provider | The DNS provider for DNS-01 challenges (e.g., cloudflare, route53). | Optional (defaults to HTTP-01) |
credentials | Array of secret names containing DNS provider API tokens. | Optional |
prefer_wildcard | Whether to request wildcard certificates. | Optional (Boolean) |
Sources: lib/kamal/configuration/validator/proxy.rb:98-115, test/configuration/proxy/acme_test.rb:17-45
DNS Provider Support
Kamal validates the dns_provider against a supported list to prevent failed boots on the server. Supported providers include cloudflare, digitalocean, route53 (alias r53), and others defined in the Kamal::Configuration::Proxy::Acme class.
Sources: lib/kamal/configuration/validator/proxy.rb:110-113, test/configuration/proxy/acme_test.rb:115-120
TLS Modes and Restrictions
Kamal enforces strict validation rules to ensure that conflicting TLS modes are not enabled simultaneously.
On-Demand TLS
On-demand TLS allows kamal-proxy to issue certificates at the time of the TLS handshake.
- Ask Endpoint: Configured via
ssl/on_demand_url. - Restrictions: Cannot be combined with static
hostorhostsdeclarations, custom certificates, orssl_domainssources. - Logic: A sleeping target cannot answer the ACME "ask" endpoint, so
proxy/sleepis generally restricted when combined with certain on-demand configurations.
Sources: lib/kamal/configuration/validator/proxy.rb:133-155, test/configuration/proxy/tls_test.rb:76-105
Client Certificate Authentication (mTLS)
Kamal supports mutual TLS by allowing the configuration of a Client CA.
- Configuration:
ssl/client_ca_pemrefers to a secret containing the CA bundle. - Path Mapping: Kamal translates the secret name into a specific container path:
/home/kamal-proxy/.apps-config/[service]/tls/client-ca.pem.
Sources: test/configuration/proxy/tls_test.rb:33-55
Validation and Diagnostics
Before deployment, Kamal performs extensive checks to ensure the SSL environment is ready.
Configuration Validation
The Kamal::Configuration::Validator::Proxy class ensures:
- A
hostis set if automatic SSL is enabled (unless using on-demand TLS or custom domain sources). - Custom certificates include both
certificate_pemandprivate_key_pem. - ACME configurations include a valid email.
- IP entries for
allow_ipsortrusted_proxiesare valid CIDR blocks or addresses.
Sources: lib/kamal/configuration/validator/proxy.rb:14-40, lib/kamal/configuration/validator/proxy.rb:125-131
Readiness Checks (Kamal Doctor)
The Kamal::Cli::Doctor::EndpointChecks class performs local (non-SSH) checks to verify the state of domains served by the proxy.
The sequence shows how the doctor command verifies external reachability and certificate health.
Sources: lib/kamal/cli/doctor/endpoint_checks.rb:25-70
Certificate Health Thresholds
| Status | Threshold |
|---|---|
| OK | Certificate is valid and expiry is > 14 days away. |
| WARN | Certificate expires in less than 14 days. |
| FAIL | Certificate is expired or certificate_pem secret is empty. |
Sources: lib/kamal/cli/doctor/endpoint_checks.rb:8-10, lib/kamal/cli/doctor/endpoint_checks.rb:72-85
Implementation Example: ACME Flags
When ACME is configured, Kamal generates specific flags for the kamal-proxy run command.
# Example of generated command based on configuration
# Source: test/configuration/proxy/acme_test.rb:17-25
"kamal-proxy run --recheck-targets-on-restore " \
"--acme-email=\"admin@example.com\" --acme-dns-provider=\"cloudflare\" " \
"--acme-directory=\"https://acme-staging-v02.api.letsencrypt.org/directory\""
Sources: test/configuration/proxy/acme_test.rb:20-25
Summary
The SSL/TLS and ACME integration in Kamal is designed to be "fail-fast," validating configurations and secret availability before any remote commands are executed. By centralizing management in kamal-proxy, the system provides a unified way to handle both static and dynamic certificate lifecycles across multiple servers.