Pillar: trust (umbrella #586). One run, from today's main.
Outcome. Limits keyed on "who sent this" (reports from outside, OAuth client registration) see each outside client separately, not as one.
Today.clientAddress (src/http/peer.ts) uses the socket peer, which in production is the ingress in front of the forge, so every outside client shares one bucket. A forwarded header is only consulted when the peer is loopback.
Acceptance.
[ ] The real client address is taken from forwarded headers only when the socket peer is a configured trusted proxy (an explicit setting, e.g. a CIDR list), using the hop that trusted proxy appended, never a client-supplied value. With no setting, behaviour is as today.
[ ] Both limiters (reports, OAuth registration) use it; the whole-forge caps stay.
[ ] Tests: a trusted proxy's header separates two clients; the same header from an untrusted peer is ignored; a client-written leading hop cannot choose its bucket.
[ ] The deploy notes say what to set for the production ingress.
Done means reachable: setting documented, test, and a note in the pull of two outside clients seen apart.
Pillar: trust (umbrella #586). One run, from today's
main.Outcome. Limits keyed on "who sent this" (reports from outside, OAuth client registration) see each outside client separately, not as one.
Today.
clientAddress(src/http/peer.ts) uses the socket peer, which in production is the ingress in front of the forge, so every outside client shares one bucket. A forwarded header is only consulted when the peer is loopback.Acceptance.
Done means reachable: setting documented, test, and a note in the pull of two outside clients seen apart.