# IP Restrictions for Control Plane

The API7 Control Plane (Dashboard and Admin API) is the highest-privilege interface in your deployment. Restricting which IP addresses can reach it reduces the attack surface for stolen-credential, lateral-movement, and brute-force scenarios.

The Dashboard and the Admin API are served by the same Control Plane process and share a single configuration file. The built-in IP allow list configured there applies to **both** interfaces.

## Configure the built-in IP allow list[​](#configure-the-built-in-ip-allow-list "Direct link to Configure the built-in IP allow list")

The Control Plane reads a `security.ip_restriction` block from its configuration file (`dashboard_conf/conf.yaml` in the Docker Compose layout, or the equivalent ConfigMap in Helm). Add the trusted networks to `allow_list`:

dashboard\_conf/conf.yaml

```
security:

  ip_restriction:

    allow_list:

      - 192.168.1.0/24

      - 10.0.0.5/32

      - 2001:db8::10/128

    deny_list: []

    message: "Access denied"

    response_code: 403
```

Behaviour:

* Both lists accept CIDR notation only. Use `/32` for one IPv4 address and `/128` for one IPv6 address. A bare or malformed entry prevents the Control Plane from starting.
* An empty `allow_list` means **allow all**; an empty `deny_list` means **deny none**. Set `allow_list` to a non-empty list to lock the Control Plane down.
* Requests from a non-allowed IP receive HTTP `403` with `{"error_msg":"Access denied"}` before any authentication runs. This applies to both the Dashboard UI and the Admin API on the same listener (default port `7443`).
* `message` and `response_code` customise the rejection response.

Apply changes by restarting the Control Plane container or pod.

caution

Before enabling `allow_list`, make sure to include the IPs of every operator workstation, CI/CD runner, and monitoring system that needs Control Plane access. Misconfiguring the list can lock you out of the Dashboard and Admin API; recovery requires shell access to the Control Plane host to revert the file.

## What this does NOT cover[​](#what-this-does-not-cover "Direct link to What this does NOT cover")

The `ip-restriction` plugin (configured via the Admin API as a plugin or global rule) executes on the **data plane** and only affects proxied client traffic to your services. It does **not** gate Admin API requests on the Control Plane and is not a substitute for the configuration above.

## Defence in depth[​](#defence-in-depth "Direct link to Defence in depth")

The Control Plane's built-in allow list should be one of several layers:

* **Network firewall or security group**: Restrict inbound traffic to the Control Plane's Admin API/Dashboard port (default `7443`) at the platform level — AWS security groups, Kubernetes `NetworkPolicy`, or a hardware firewall.
* **Reverse proxy in front of the Control Plane**: Terminate Control Plane traffic on an NGINX, HAProxy, or cloud load balancer that enforces an IP allow list independently from the Control Plane's own list.
* **Admin API key authentication**: Every Admin API request must carry a valid `X-API-KEY` header. Rotate keys regularly and scope them per user or service account.
* **SSO for the Dashboard**: Layer [SSO](https://docs.api7.ai/api7-gateway/security-and-compliance/sso-dashboard.md) on top so that being on a permitted network is necessary but not sufficient for access.
* **mTLS between Control Plane and Data Plane**: See [Mutual TLS between CP and DP](https://docs.api7.ai/api7-gateway/security-and-compliance/authenticate/mutual-tls-cp-dp.md) so that even an attacker on the Admin API port cannot impersonate a data plane node.

## Best Practices[​](#best-practices "Direct link to Best Practices")

1. **Default-deny at the network layer**: Allow only known operator subnets, CI/CD runners, and bastion hosts to reach the Control Plane ports.
2. **Audit changes**: Pair IP restrictions with [Audit Logs](https://docs.api7.ai/api7-gateway/security-and-compliance/audit-logs.md) so unauthorized configuration changes are detectable even if an allowed network is compromised.
3. **Test before locking down**: Stage `allow_list` changes in a non-production environment first, and keep an out-of-band recovery path (host shell access) available.

## Next Steps[​](#next-steps "Direct link to Next Steps")

* [Review Audit Logs](https://docs.api7.ai/api7-gateway/security-and-compliance/audit-logs.md) to detect failed login attempts from restricted IPs.
* [Configure SSO](https://docs.api7.ai/api7-gateway/security-and-compliance/sso-dashboard.md) for centralized user authentication.
