The production gateway does not face the internet: nginx-proxy-manager owns
80/443 on the host and proxies to it. So $remote_addr inside the gateway is that
proxy, and overwriting X-Forwarded-For with it discarded the customer address
the proxy had already recorded. Every request would have been attributed to one
internal address, which is exactly the fault 2.1 set out to fix, reintroduced in
production only.
Use real_ip to take the customer address from the proxy's header, trusting only
private networks. A request that reaches the published port directly from the
internet is not trusted, so its header is ignored and $remote_addr stays the
real peer: the anti-spoofing property is kept.
Also downgrade 2.9. TLS is not missing, it is terminated by that proxy. The gap
is that the repository never says so, which would break every session cookie if
the stack moved to a host without one.
Validated with nginx -t against the rendered production configuration.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Findings from the 2026-09-18 audit, ordered by block, each with its acceptance
criterion and audit id. Block 0 is closed; the remaining blocks record security,
architecture, scale and maintenance work, including the decisions that need a
product answer before any code.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>