Serve Murmur API over HTTPS with Caddy
Put the Murmur control-plane API behind Caddy automatic HTTPS at `murmur.kaukus.tv`. Scope: - Run a digest-pinned official Caddy container in the Murmur Compose project. - Publish only ports 80 and 443; keep the control-plane service reachable only on the internal Compose network. - Allow public ACME traffic needed for automatic certificate issuance and renewal. - Keep `/health` reachable for deployment/monitoring checks, restrict all authenticated API routes at Caddy to the Kaukus production source IP, and retain Murmur JWT authorization behind that edge check. - Persist Caddy certificate/config state and add hardened response headers and request limits where appropriate. - Make Ansible wait for the public HTTPS health endpoint and document the DNS prerequisite. Acceptance criteria: - `murmur.kaukus.tv` resolves to the control server before deployment. - Caddy obtains and renews a publicly trusted certificate without manual credentials. - Port 8080 is not published from the control-plane container or allowed through host/Docker firewalls. - Requests from the Kaukus production host reach Murmur over HTTPS; other sources cannot reach `/v1/*`. - HTTP redirects to HTTPS, `/health` succeeds over HTTPS, and Caddy/Murmur containers restart safely with persisted state. - Rendered Compose/Caddy configuration, Ansible syntax/lint, and a local proxy test pass before deployment. Verified implementation: - The digest-pinned official Caddy 2.10.2 Alpine image is the only service publishing TCP 80/443; control-plane port 8080 is internal-only. - Caddy state is persisted, the root filesystem is read-only, temporary paths are tmpfs-backed, capabilities are reduced to `NET_BIND_SERVICE`, and privilege escalation is disabled. - `/health` is public; `/v1/*` is limited to `49.12.203.23/32`, capped at a 1 MiB request body, and proxied to Murmur for JWT validation. Other paths/sources return 403. - Public 80/443 firewall rules support ACME; the Ansible health gate verifies the trusted HTTPS endpoint. DNS/ACME prerequisites are documented. - YAML and Ansible lint, playbook syntax, inventory variables, rendered TOML/Compose, Caddy formatting/validation, reduced-capability port binding, security headers, public health, allowed API routing and denied source/path behavior pass locally. Verified live deployment: - Public resolvers return only the intended A record `151.115.147.97`; no AAAA or restrictive CAA record is present. - Caddy is live on the converged replacement server, and Let's Encrypt issued a trusted certificate for `murmur.kaukus.tv` valid through 2027-01-12. - HTTPS `/health` returns 204 with HSTS, nosniff and no-referrer headers; HTTP redirects permanently to HTTPS. - External sources receive 403 for `/v1/*`; the Kaukus production host passes the source gate and receives Murmur's expected 401 JWT challenge. - Control-plane port 8080 is internal-only, certificate/config/PostgreSQL volumes persist, reduced Caddy capabilities are active, and an Ansible rerun is idempotent. - Do not add an AAAA record until IPv6 firewall and routing are configured.
Checklist
4 of 4 complete- Add digest-pinned Caddy service, persisted state, and internal-only control-plane networking
- Configure automatic HTTPS, public health, Kaukus-only API routing, and security headers
- Update firewall, deployment health check, and DNS/runbook documentation
- Validate rendered Ansible/Compose/Caddy configuration and local proxy behavior
- Area
- Kaukus
- Project
- Deploy Murmur to production
- Kind
- Feature
- Priority
- High
- Task ID
tsk_fx7ghyz4aa- Updated