By server

All Security Headers for Caddy (One Caddyfile Block)

2 min read

Caddy v2 already gives you automatic HTTPS; add the security headers with a header block inside your site definition.

yourdomain.com {
    root * /var/www/yourdomain
    file_server

    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "SAMEORIGIN"
        Referrer-Policy "strict-origin-when-cross-origin"
        Permissions-Policy "geolocation=(), camera=(), microphone=()"
        Cross-Origin-Opener-Policy "same-origin"
        # Tune CSP per site — start report-only (see the CSP recipe):
        Content-Security-Policy "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"
        # Remove Caddy's Server header:
        -Server
    }
}

Reload

sudo systemctl reload caddy
# or, if running manually:
caddy reload --config /etc/caddy/Caddyfile

Verify

curl -sI https://yourdomain.com

Note: a leading - before a header name (e.g. -Server) removes it; a + adds without replacing. Caddy applies these to all responses by default, so there’s no always-style flag to remember. Validate the file first with caddy validate --config /etc/caddy/Caddyfile.

Open the full version (with copy buttons) ↗

← All recipes