Inbound HTTPS with Caddy
Tracecat ships with Caddy as a reverse proxy. Caddy automatically provisions and renews TLS certificates from Let’s Encrypt when configured with a domain name.Update environment variables
In your Mixing HTTP and HTTPS across these values causes CORS failures. Keep the scheme consistent everywhere.
.env file, set BASE_DOMAIN to your domain and switch every public URL and the allowed origins to HTTPS:Expose ports 80 and 443
Update the Port 80 must remain open for the ACME HTTP-01 challenge. Port 443 serves HTTPS traffic.
caddy service ports in your docker-compose.yml:Bring your own certificate
If your domain is internal or cannot use Let’s Encrypt, supply your own certificate and private key with Caddy’stls directive.
Mount the files into the caddy service and reference them in your Caddyfile:
Cloud VMs
If you deploy into a cloud VM (for example an EC2 instance), we recommend placing a managed load balancer such as an AWS Application Load Balancer in front of Caddy. Terminate TLS at the load balancer with an ACM certificate and forward traffic to Caddy, so certificates and public HTTPS are handled by managed infrastructure instead of the VM. With TLS terminated at the load balancer, keep Caddy in HTTP-only mode. Do not setBASE_DOMAIN to a bare domain as in the Let’s Encrypt setup above — that enables Caddy’s automatic HTTPS, which redirects the load balancer’s forwarded HTTP requests back to HTTPS and creates a redirect loop.
Keep the default port-only BASE_DOMAIN and set only the public URLs to HTTPS:
Browsers force HTTPS
If the browser fails withERR_CONNECTION_REFUSED while curl over HTTP works, your deployment is serving plain HTTP but the browser is trying to reach it over HTTPS.
This is expected browser behavior, not a Tracecat or Caddy error: modern browsers automatically upgrade requests to a public hostname to HTTPS (through HSTS, the “Always use secure connections” setting, or a prior HTTPS visit).
Because the default stack exposes only port 80 with no TLS, the HTTPS request is refused.
The Caddy logs confirm HTTP-only mode:
Trust an internal CA for outbound connections
Tracecat containers do not inherit the host’s trust store. If Tracecat calls services with certificates signed by an internal CA — a custom LLM provider, an internal Jira, an on-prem API — those connections fail TLS verification even whencurl on the host succeeds.
Per-action: CA certificate secret
For HTTP actions, create a workspace secret namedca_cert with the key CA_CERTIFICATE set to your CA certificate as PEM text.
core.http picks it up automatically and verifies servers against it without any deployment changes.
HTTP actions also accept verify_ssl: false, but only use this as a temporary workaround — it disables certificate verification entirely.
See HTTP actions.
Deployment-wide: inject the CA into service trust stores
To make every service trust your CA — including custom LLM providers and Python integrations — append it to the certifi bundle with a one-shot init container.Add your CA certificates
Create a
certs/ directory next to your docker-compose.yml and place your CA certificates in it as .crt files in PEM format (not DER).
Include the full chain: root and any intermediate CAs.Create a Compose override
Create The
docker-compose.override.yml next to your docker-compose.yml:cert-init service copies the default certifi bundle into a shared volume and appends your CA certificates.
Docker Compose merges the override with each service’s existing configuration.
Apply the same *custom-ca block to any other service that makes outbound HTTPS calls.The injected bundle does not reach actions running inside the nsjail sandbox (
TRACECAT__EXECUTOR_SANDBOX_ENABLED=true).
The sandbox strips these environment variables and does not mount /custom-ca.
For sandboxed HTTP actions, use the per-action ca_cert secret instead.