Skip to main content
Connection policies govern the establishment of TLS connections. They control cipher suites, protocol versions, client authentication, and other handshake parameters.

Connection Policy

Connection policies are evaluated in order; the first matching policy will be used to configure the TLS connection.
An empty policy is valid. Safe and sensible defaults will be used.

Policy Matching

match
object
How to match this policy with a TLS ClientHello.If this policy is the first to match, it will be used. Available matchers:
  • sni - Server Name Indication
  • remote_ip - Client IP address
  • Other custom connection matchers

TLS Protocol Settings

cipher_suites
array
The list of cipher suites to support.
Caddy’s defaults are modern and secure. Only customize if you have specific requirements.
Supported cipher suites:
  • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
  • TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
  • TLS_AES_128_GCM_SHA256 (TLS 1.3)
  • TLS_AES_256_GCM_SHA384 (TLS 1.3)
  • TLS_CHACHA20_POLY1305_SHA256 (TLS 1.3)
curves
array
The list of elliptic curves to support.Caddy’s defaults are modern and secure.Supported curves:
  • x25519
  • secp256r1 (P-256)
  • secp384r1 (P-384)
  • secp521r1 (P-521)
protocol_min
string
default:"tls1.2"
Minimum TLS protocol version to allow.Values: tls1.2, tls1.3
TLS 1.0 and 1.1 are deprecated and insecure. Caddy only supports TLS 1.2 and 1.3.
protocol_max
string
default:"tls1.3"
Maximum TLS protocol version to allow.Values: tls1.2, tls1.3
alpn
array
Protocols to use for Application-Layer Protocol Negotiation (ALPN) during the handshake.Default: ["h2", "http/1.1"] (enables HTTP/2 and HTTP/1.1)

Certificate Selection

certificate_selection
object
How to choose a certificate if more than one matches the given ServerName (SNI) value.Can specify criteria like public key algorithm, serial number, subject organization, etc.
default_sni
string
DefaultSNI becomes the ServerName in a ClientHello if there is no policy configured for the empty SNI value.
fallback_sni
string
FallbackSNI becomes the ServerName in a ClientHello if the original ServerName doesn’t match any certificates in the cache.
EXPERIMENTAL: Subject to change or removal.
Use cases are very niche. Typically useful if a client (like a CDN) passes through the ServerName of the downstream handshake but can accept a certificate with the origin’s hostname instead.

Client Authentication

client_authentication
object
Enables and configures TLS client authentication (mutual TLS).
client_authentication.mode
string
The mode for authenticating the client.
ModeDescription
requestAsk clients for a certificate, but allow even if there isn’t one; do not verify it
requireRequire clients to present a certificate, but do not verify it
verify_if_givenAsk clients for a certificate; allow even if there isn’t one, but verify it if there is
require_and_verifyRequire clients to present a valid certificate that is verified
Default is require_and_verify if trust pool is provided; otherwise require.
client_authentication.trust_pool
object
Certificate authority module which provides the certificate pool of trusted certificates.Available providers:
  • inline - Base64 DER-encoded CA certificates
  • file - Load CA certificates from PEM files
  • pki - Use CA from Caddy’s PKI app
client_authentication.verifiers
array
Client certificate verification modules.These can perform custom client authentication checks, such as ensuring the certificate is not revoked.Available verifiers:
  • leaf - Verify against specific leaf certificates

Advanced Settings

drop
boolean
default:"false"
Reject TLS connections that match this policy.
EXPERIMENTAL: May change.
insecure_secrets_log
string
Also known as “SSLKEYLOGFILE”. TLS secrets will be written to this file in NSS key log format.
ENABLING THIS LOG COMPROMISES SECURITY! This allows other programs or tools to decrypt TLS connections. Only use for debugging and troubleshooting.
EXPERIMENTAL: Subject to change or removal.

Configuration Examples

Basic Connection Policy

{
  "apps": {
    "http": {
      "servers": {
        "srv0": {
          "tls_connection_policies": [
            {
              "match": {
                "sni": ["example.com", "*.example.com"]
              },
              "protocol_min": "tls1.2",
              "protocol_max": "tls1.3"
            }
          ]
        }
      }
    }
  }
}

Client Authentication (Mutual TLS)

{
  "tls_connection_policies": [
    {
      "client_authentication": {
        "mode": "require_and_verify",
        "trust_pool": {
          "provider": "file",
          "pem_files": ["/path/to/client-ca.pem"]
        }
      }
    }
  ]
}

Inline CA Certificates

{
  "client_authentication": {
    "mode": "require_and_verify",
    "trust_pool": {
      "provider": "inline",
      "trusted_ca_certs": [
        "base64-encoded-der-certificate-1",
        "base64-encoded-der-certificate-2"
      ]
    }
  }
}

Leaf Certificate Verification

{
  "client_authentication": {
    "mode": "require_and_verify",
    "verifiers": [
      {
        "verifier": "leaf",
        "leaf_certs_loaders": [
          {
            "loader": "file",
            "files": ["/path/to/client-cert.pem"]
          }
        ]
      }
    ]
  }
}

Custom Cipher Suites

{
  "tls_connection_policies": [
    {
      "cipher_suites": [
        "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
      ],
      "curves": ["x25519", "secp256r1"]
    }
  ]
}

SNI-Based Policy Matching

{
  "tls_connection_policies": [
    {
      "match": {
        "sni": ["api.example.com"]
      },
      "client_authentication": {
        "mode": "require_and_verify",
        "trust_pool": {
          "provider": "file",
          "pem_files": ["/etc/caddy/api-clients-ca.pem"]
        }
      }
    },
    {
      "match": {
        "sni": ["example.com", "www.example.com"]
      }
    }
  ]
}

Caddyfile Configuration

Basic TLS Settings

example.com {
  tls {
    protocols tls1.2 tls1.3
    ciphers TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  }
}

Client Authentication

example.com {
  tls {
    client_auth {
      mode require_and_verify
      trust_pool file {
        pem_file /path/to/client-ca.pem
      }
    }
  }
}

Multiple Policies

{
  servers {
    srv0 {
      tls_connection_policy {
        match {
          sni api.example.com
        }
        client_auth {
          mode require_and_verify
          trust_pool file {
            pem_file /etc/caddy/api-ca.pem
          }
        }
      }
      
      tls_connection_policy {
        match {
          sni example.com
        }
      }
    }
  }
}

api.example.com {
  respond "API Server"
}

example.com {
  respond "Web Server"
}

Session Tickets

Caddy automatically manages session tickets for resumption unless disabled:
{
  "apps": {
    "tls": {
      "session_tickets": {
        "disabled": false
      }
    }
  }
}
Session tickets are automatically disabled when client authentication is enabled to prevent privilege escalation across virtual hosts.

Best Practices

Default Settings: Caddy’s default cipher suites and protocols are carefully selected for security and compatibility. Only customize if you have specific requirements.
Client Authentication: When using mutual TLS, ensure proper certificate validation. Use the appropriate mode for your security requirements.
Protocol Versions: TLS 1.3 offers better performance and security. Only allow TLS 1.2 if you need to support older clients.
Cipher Suites: Weak cipher suites are not supported by Caddy. The available suites are all considered secure for modern use.

Common Use Cases

API with Client Certificates

{
  "tls_connection_policies": [
    {
      "match": {
        "sni": ["api.example.com"]
      },
      "client_authentication": {
        "mode": "require_and_verify",
        "trust_pool": {
          "provider": "file",
          "pem_files": ["/etc/caddy/client-ca.pem"]
        }
      },
      "alpn": ["h2"]
    }
  ]
}

Internal Services (TLS 1.3 only)

{
  "tls_connection_policies": [
    {
      "protocol_min": "tls1.3",
      "protocol_max": "tls1.3"
    }
  ]
}

Legacy Client Support

If you must support very old clients (not recommended):
{
  "tls_connection_policies": [
    {
      "protocol_min": "tls1.2",
      "cipher_suites": [
        "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
        "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
        "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
      ]
    }
  ]
}

Build docs developers (and LLMs) love