|# Client IP Address
|
|The **Client IP Address** is the address of the person or program that really made a call, as opposed to the address of whatever passed the call on to OBP-API. OBP-API uses it for per-address [Rate Limiting](http://localhost:5174/glossary#Rate-Limiting) (including the documentation limit for callers who are not logged in), for IP penalties, and for the busiest-callers view.
|
|## The problem
|
|OBP-API only sees the machine that opened the connection to it. When a browser talks to API Explorer II, API Explorer II talks to OBP-API; when a User chats with Opey, Opey asks OBP-MCP, and OBP-MCP calls OBP-API. Without help, every one of those calls would appear to come from the same server, so one busy User could use up everyone's limit, and a penalty would lock out everyone at once.
|
|## How the address is passed on: X-Forwarded-For
|
|Each hop adds the address it received the request from to the `X-Forwarded-For` header before passing the request on. The header therefore reads "client, first hop, second hop, ...". For a chat with Opey behind NGINX, the chain that reaches OBP-API looks like this:
|
|| Hop | Receives the request from | Appends |
||---|---|---|
|| NGINX in front of API Explorer II | the browser | the browser's address |
|| API Explorer II | NGINX | NGINX's address |
|| Opey | API Explorer II | API Explorer II's address |
|| OBP-MCP | Opey | Opey's address |
|| OBP-API | OBP-MCP (the TCP peer) | nothing: it reads the chain |
|
|API Explorer II, Opey and OBP-MCP each append the address of the machine they received the request from, the same way NGINX does. Opey keeps the chain outside the conversation, so it never reaches the language model, and it replaces any address header the model writes into a tool call. On the Berlin Group endpoints, API Explorer II also sends the browser's address as `PSU-IP-Address`.
|
|## How OBP-API stops a false address
|
|Anyone can write anything at the left end of the chain, so OBP-API never simply takes the first entry. It reads the chain **from the right**: it skips every address it trusts, and the first address it does not trust is the client. A caller that OBP-API does not trust cannot name a false address, because the walk stops at that caller's own address. For this to work, every hop (NGINX, API Explorer II, Opey, OBP-MCP) must be on OBP-API's list of trusted addresses, and it must not be possible to reach the services behind NGINX except through the hops in front of them.
|
|OBP-API also accepts an `X-Real-IP` header holding a single address, for a deployment with one proxy that overwrites it.
|
|## Where the address is recorded
|
|Each [API Metrics](http://localhost:5174/glossary#API-Metrics) record keeps the client address OBP-API decided on (`source_ip`) and the whole list of hops (`forwarded_for`), so a call can be traced back through the apps it passed through.
|
|## What the address does and does not tell you
|
|The client address is the address that opened a connection to the outermost trusted proxy. It cannot be faked by writing a false sending address on the network packets, because opening a connection needs the caller to receive the proxy's reply. It may, however, belong to a home router, a company's or mobile network's shared address, a VPN or Tor exit, rather than to the person's own device.
|
|## On this instance
|
|- Client addresses are not taken from any header: the machine that opened the connection is treated as the client.
|- The header is believed from any caller, and for `X-Forwarded-For` the leftmost address is used, which the client itself can write.
|
|Deployment Checks (`GET /obp/v7.0.0/management/system/diagnostics/deployment`, Role CanGetConfig) show whether requests arrive with a forwarding header, which machines send it, and whether any were ignored because they came from an address that is not trusted.
|
|See also: [Rate Limiting](http://localhost:5174/glossary#Rate-Limiting), [API Metrics](http://localhost:5174/glossary#API-Metrics), [OBP-MCP](http://localhost:5174/glossary#OBP-MCP).
|