> For the complete documentation index, see [llms.txt](https://mercure-technologies.gitbook.io/expo-open-ota/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mercure-technologies.gitbook.io/expo-open-ota/security/ip-whitelisting.md).

# IP whitelisting

{% hint style="warning" %}
IP whitelisting is an Enterprise feature and requires [control-plane mode](/expo-open-ota/controle-plane-mode/overview.md). Editing a token's allowlist requires an active Enterprise license. (See [Open core and licensing](/expo-open-ota/open-core-and-licensing.md))
{% endhint %}

IP whitelisting ties an API token to a set of source addresses, so the token only works when the request comes from a network you trust. It turns a token from a credential that works anywhere into one that works only from, say, your CI provider or your office network.

## How it works

On an **API token**, an admin lists the addresses that are allowed to use it. Each entry is a single IP address or a CIDR range, and both IPv4 and IPv6 are supported (for example `203.0.113.7`, `203.0.113.0/24` or `2001:db8::/32`). An empty list means the token has no IP restriction and works from anywhere.

On every request that presents the token, the server compares the caller's source address against the list and rejects anything that falls outside it.

## Behind a proxy or load balancer

By default the server uses the address of the network connection it received, which is the correct source IP when clients reach the server directly. When Expo Open OTA runs behind a proxy or load balancer, that address is the proxy's, so you need to tell the server to trust the forwarded address instead.

Set `TRUST_PROXY_HEADERS=true` and the server reads the client address from the `X-Forwarded-For` header instead of the connection. That header is a comma-separated list to which each proxy appends the address it received the connection from, so the entries a client can forge always sit to the left of the one your outermost trusted proxy added.

Use `TRUST_PROXY_DEPTH` to tell the server how many trusted proxies sit in front of it. The client address is then read that many entries from the right of the list: a single ingress or load balancer uses `1` (the default), a CDN in front of a load balancer uses `2`, and so on. Set it to the exact number of proxies you control, because a value that is too low reads an intermediate proxy address, while one that is too high would trust an entry the client can supply.

Only enable `TRUST_PROXY_HEADERS` when the server is reachable exclusively through your trusted proxies, since a client that can reach the server directly could otherwise forge the header.

## Set it up

{% stepper %}
{% step %}

#### Open the token restrictions

In the dashboard, go to **API tokens** and open the restrictions of the token you want to lock down.
{% endstep %}

{% step %}

#### List the allowed addresses

Add one IP address or CIDR range per line, then save. From now on the token only works from those networks.
{% endstep %}
{% endstepper %}

## See also

[Branch protection](/expo-open-ota/security/branch-protection.md) restricts which branches a token is allowed to publish to.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://mercure-technologies.gitbook.io/expo-open-ota/security/ip-whitelisting.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
