The paragraph describing parseCIDRList sat above defaultTrustedProxies
with no separating blank line, so both bound to defaultTrustedProxies as
one doc block and parseCIDRList had none. Move it to immediately precede
func parseCIDRList.
Model: opus-4-8
Update README.md, config.example.yml and the TODO.md completed entry so
they state that an omitted trusted_proxies key defaults to the RFC 1918
private ranges, an explicitly empty list trusts no one, and an explicit
list replaces the default.
Model: opus-4-8
An omitted trusted_proxies key now defaults to 10.0.0.0/8, 172.16.0.0/12
and 192.168.0.0/16 instead of trusting no one, matching the deployment
where pixa sits behind a proxy on a private network. An explicitly empty
list still trusts nothing, and an explicit list replaces the default;
these are distinguished by parseCIDRList returning nil only for an absent
key. Loopback is excluded, as it is not an RFC 1918 range.
Model: opus-4-8
Per the owner ruling, an omitted trusted_proxies key now defaults to the
RFC 1918 private ranges rather than trusting no one. Update the wiring
test to expect that default, and add a case that an explicitly empty list
still trusts no one.
Model: opus-4-8
Describe the trusted_proxies key in README.md and config.example.yml,
including the rightmost-non-proxy selection rule and the safe default of
trusting no one. Record the unit in TODO.md.
Model: opus-4-8
Add a ClientIP middleware that resolves the client address once per
request and stores it in the context, placed ahead of logging in the
route chain. The request-logging middleware and both login-attempt logs
now read the resolved address instead of the raw peer. Behind a trusted
proxy these records show the real client; a direct, untrusted client
still shows its own address and cannot forge one. Removes the local
host:port helper now that the clientip package owns that parsing.
Model: opus-4-8
Assert the ClientIP middleware stores the resolved address in the
request context for trusted and untrusted peers, that the request log
records the forwarded client rather than the proxy peer, and that a
failed-login record carries the resolved address.
Model: opus-4-8
New internal/clientip package. Resolve honors X-Forwarded-For only when
the direct peer falls inside a configured trusted-proxy range; otherwise
it returns the peer address and ignores the header, so a client
connecting directly cannot spoof its address. When the peer is trusted,
the chain is walked right to left and the first entry that is not itself
a trusted proxy is returned. Also provides request-context helpers so the
resolved address can be shared across middleware and handlers.
Tests cover the honored, ignored, and spoofed-chain cases, rightmost
selection across a mixed chain, multi-line headers, IPv6 and
IPv4-mapped peers, and the context round-trip.
Model: opus-4-8
Add a trusted_proxies CIDR-list config key alongside blocked_networks.
Generalize the blocked_networks parser into parseCIDRList and
cidrListEntries, which take the key name as a parameter, so both keys
share one parser rather than a second copy. An invalid entry aborts
startup naming the key and value; an omitted or empty key leaves the
list empty.
Model: opus-4-8
Check that a valid CIDR list lands in TrustedProxies in order, an omitted
key trusts no one, and an invalid or null value aborts startup naming the
key and value. The list parser is shared with blocked_networks, whose
tests exercise the remaining shapes.
Model: opus-4-8