The Ansible base-directory loop created /opt/scrabble/certs at mode 0750
(deploy:deploy), like config/dumps/images. The gateway (and backend) run as
the distroless nonroot UID 65532 — not the deploy user — so the container
cannot traverse a 0750 certs dir and fails at startup with
"mtls: load server keypair: ... permission denied", crash-looping.
This is latent: a long-running container holds the keypair in memory and
never re-reads the file, so the misconfig only bites when a container
restarts (a host reboot / redeploy). A hoster maintenance reboot exposed it
on prod — the gateway came back crash-looping while the deploy could not SSH
in mid-reboot.
Split certs out of the 0750 loop and create it 0755 (traversable). The keys
stay 0644 by design (the gateway compose relies on it); the host is
single-tenant + SSH-access-controlled, so a traversable certs dir adds no
meaningful exposure. The live prod host was already chmod-fixed by hand; this
keeps the next provisioning run from re-tightening it.