IP Allowlisting¶
ARX supports per-organization IP allowlisting to restrict API access to known network ranges. When enabled, requests from IP addresses outside the allowlist are rejected before reaching any endpoint handler.
How It Works¶
IP allowlisting is an opt-in security control. When an organization has one or more entries in its IP allowlist, the middleware enforces access restrictions:
- No entries: All IP addresses are allowed (allowlisting is disabled).
- One or more entries: Only requests from IP addresses that match at least one CIDR entry are permitted. All other requests receive a
403 Forbiddenresponse.
This opt-in model means organizations can adopt allowlisting at their own pace without affecting other tenants.
CIDR Format¶
Entries use standard CIDR notation. Both individual addresses and ranges are supported:
| Example | Description |
|---|---|
203.0.113.45/32 |
Single IP address |
10.0.0.0/8 |
Private class A range |
192.168.1.0/24 |
/24 subnet |
2001:db8::/32 |
IPv6 range |
ARX validates and normalizes all CIDR inputs. Invalid notation is rejected with 422 Unprocessable Entity.
API Endpoints¶
All IP allowlist endpoints require the admin role.
List Entries¶
GET /v1/settings/ip-allowlist
Returns all allowlist entries for the authenticated user's organization, ordered by creation date (newest first).
Add an Entry¶
POST /v1/settings/ip-allowlist
{
"cidr": "10.0.0.0/8",
"description": "Corporate VPN"
}
Returns 201 Created with the new entry. The allowlist cache is cleared immediately so the new entry takes effect on the next request.
Update an Entry¶
PUT /v1/settings/ip-allowlist/{entry_id}
{
"cidr": "10.0.0.0/16",
"description": "Updated corporate VPN range"
}
Delete an Entry¶
DELETE /v1/settings/ip-allowlist/{entry_id}
Returns 204 No Content. If this was the last entry, IP allowlisting is effectively disabled for the organization.
Middleware Behavior¶
The IP allowlist middleware evaluates every incoming request:
- Determines the organization from the authenticated user context.
- Fetches the allowlist entries (from cache if available).
- If entries exist, checks the client IP against each CIDR range.
- If no entry matches, the request is rejected with
403 Forbidden. - If no entries exist, the request proceeds normally.
Cache¶
Allowlist entries are cached to minimize database lookups. The cache has a configurable TTL and is invalidated immediately when entries are added, updated, or deleted via the API (the clear_allowlist_cache function is called after every mutation).
Bypassed Paths¶
Certain paths are excluded from IP allowlist enforcement to ensure platform availability:
/health-- health check endpoint/docs-- API documentation/redoc-- alternative API documentation/openapi.json-- OpenAPI schema
Audit Logging¶
All IP allowlist changes are recorded in the audit log:
| Event | Description |
|---|---|
ip_allowlist.entry_added |
A new CIDR entry was added |
ip_allowlist.entry_updated |
An existing entry was modified |
ip_allowlist.entry_removed |
An entry was deleted |
Each audit event includes the CIDR value, entry ID, and the user who made the change.
Best Practices¶
- Start with broad ranges (e.g., your corporate IP range) before narrowing down.
- Always include your current IP before enabling allowlisting to avoid locking yourself out.
- Add VPN and CI/CD egress IPs if your team or pipelines use them.
- Test with a secondary admin account from a known-good IP before removing broad ranges.
- Use descriptions on every entry to document the purpose of each range.
Troubleshooting¶
| Symptom | Cause | Resolution |
|---|---|---|
403 Forbidden on all requests |
Your IP is not in the allowlist | Add your IP via direct database access or remove all entries to disable allowlisting. |
| Entry not taking effect | Stale cache | The cache is cleared on mutations; if the issue persists, restart the API service. |
422 Invalid IP address or CIDR notation |
Malformed CIDR string | Use standard notation (e.g., 10.0.0.0/8). |