# Security - Wagtail admin uses Django authentication, authorization, sessions, CSRF protection, and password hashing. The public site does not add accounts or write endpoints. - The aggregate API is intentionally unauthenticated and returns published editorial content only; secrets and unpublished drafts must never be serialized. - PostgreSQL has no host-published port. NGINX and diagnostic application ports bind to loopback for local use. Unknown NGINX virtual hosts are rejected with 404. - Containers are unprivileged at the Compose level: no privileged mode, host network, Docker socket, or added capabilities are used. `no-new-privileges` is enabled and the application images run as non-root users. - `.env` is ignored. `.env.example` contains replaceable development placeholders, never production credentials. Use a deployment secret manager outside local use. - `DJANGO_DEBUG` must be false and allowed hosts explicit outside development. Public traffic must use either the optional direct TLS mode or TLS at a load balancer. - Database and uploaded media backups may contain personal data. Restrict, encrypt, retain, and delete them according to the operator's privacy policy. - Avoid placing personal phone numbers or private contact details in logs. The API legitimately exposes only contact details approved for publication. - Dependency and image versions are explicit. Operators remain responsible for patch upgrades, vulnerability scans, and production digest pinning. - NGINX forwards the original host and standard client/protocol headers. Django trusts `X-Forwarded-Proto: https`; therefore direct proxy access must be limited to trusted networks when a load balancer supplies that header. The NGINX mapping accepts only the literal `https` value as secure. - Optional Certbot uses a pinned image, a read-only root filesystem, no Docker socket, and only the certificate/challenge volumes. NGINX reads private keys from the certificate volume but cannot modify them. Restrict and back up that volume as sensitive material. - The Playwright image is pinned and enabled only through the test Compose profile. It receives no credentials, publishes no host ports, and tests only the local portal. The override uses a separate PostgreSQL volume so its seed cannot overwrite normal CMS content. Manual production hardening remains required for proxy trust boundaries, media storage, backup retention, monitoring, firewalling, and admin network policy.