Organization-level
Applies to all API requests made to your organization, regardless of which API key is used. Acts as a global default.
API key-level
Applies only to requests authenticated with a specific API key. Overrides the organization-level allowlist for that key when present.
- Locking down production API keys to specific server IPs
- Preventing API access from outside your organization’s network
- Enforcing per-key access controls across different environments
Before you begin
- The org-level allowlist must be enabled for API key-level rules to take effect. If the org-level allowlist is disabled, API key-level allowlists are not enforced.
- Dashboard actions are never subject to IP allowlisting. You can always use the Dashboard to manage your configuration, even if you misconfigure your rules.
- Unresolvable source IPs default to fail-open. In rare cases, intermediary infrastructure may prevent Turnkey from resolving a request’s source IP. The
onEvaluationErrorparameter controls whether these requests are allowed (fail-open) or denied (fail-closed). It defaults toALLOW.
**IP Allowlisting **is available to Enterprise clients on the Scale tier or higher. If you would like to access this feature please reach out to your Turnkey representative.
How it works
Define your CIDRs
Submit one or more CIDR blocks (e.g.,
192.168.1.0/24) with optional human-readable labels (e.g., "Office VPN").Enable the allowlist
When you’re ready, set
enabled: true to begin enforcement. Via the Dashboard, you can add rules and enable separately. Via the API, you can define rules and enable in a single set_ip_allowlist call — but we recommend staging rules with enabled: false first to verify your configuration.Requests are validated
Any API request whose source IP does not fall within an allowed CIDR block is rejected automatically.
IP Allowlist operations follow Turnkey’s activity model. Creating or removing an allowlist is an auditable activity that goes through policy evaluation and approval before execution.
Organization-level vs. API key-level
| Aspect | Organization-level | API key-level |
|---|---|---|
| Scope | All API requests for the org | Requests using a specific API key only |
publicKey parameter | Omitted or null | Set to the API key’s public key |
enabled parameter | Required (true or false) | Not applicable — always enforced if present |
| Precedence | Default for all keys | Overrides the org-level allowlist for that key |
| Limit | One per organization | One per API key |
Precedence rules
- The org-level allowlist must be enabled for API key-level allowlists to be evaluated.
- If an API key has its own allowlist, only that key-level allowlist is checked for requests using that key.
- If an API key does not have its own allowlist, the org-level allowlist is checked (if enabled).
- If neither exists, requests are allowed from any IP.
CIDR rules
Format
Both IPv4 and IPv6 are supported. The maximum prefix length is/20 for IPv4 and /48 for IPv6.
| Format | Examples |
|---|---|
| IPv4 | 10.0.0.0/20, 192.168.1.0/24, 203.0.113.42/32 (single IP) |
| IPv6 | 2001:db8::/48, ::1/128 (single IP) |
192.168.1.100/24 becomes 192.168.1.0/24.
Labels
Each rule accepts an optionallabel string for human-readable identification (e.g., "Office VPN", "Production Server"). Labels are stored and returned in responses but have no effect on enforcement.
Limits and validation
- Maximum of 10 IPv4 CIDRs and 10 IPv6 CIDRs per allowlist (20 total)
- Duplicate CIDRs within a single submission are automatically deduplicated — only the first occurrence and its label are kept
- The
rulesarray can be empty (creates an allowlist with no rules) - Invalid CIDRs are rejected with an error indicating the index and value that failed
Replacement semantics
set_ip_allowlist always fully replaces the existing rule set. To add a single rule without losing existing ones, first retrieve the current rules with get_ip_allowlist, append your new rule, then resubmit the complete list.
API reference
All endpoints useHTTP POST and require a signed request body stamped with your API key.
| Endpoint | Description |
|---|---|
POST /public/v1/submit/set_ip_allowlist | Create or update an IP allowlist |
POST /public/v1/submit/remove_ip_allowlist | Remove an IP allowlist |
POST /public/v1/query/get_ip_allowlist | Retrieve the current IP allowlist |
Set IP allowlist
Creates or updates an IP allowlist. If one already exists for the specified scope, it is fully replaced.Request body
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Must be "ACTIVITY_TYPE_SET_IP_ALLOWLIST" |
timestampMs | string | Yes | Current timestamp in milliseconds (epoch) — used for request liveness verification |
organizationId | string | Yes | Your Turnkey organization ID |
parameters.rules | array | Yes | Array of allowlist rules. Can be empty. |
parameters.rules[].cidr | string | Yes | CIDR block (e.g., "192.168.1.0/24", "2001:db8::/48") |
parameters.rules[].label | string | No | Optional human-readable label (e.g., "Office VPN") |
parameters.enabled | boolean | No | Whether the allowlist is enforced. Only meaningful for org-level policies. |
parameters.publicKey | string | No | Public key of an API key. If omitted, the allowlist applies at the org level. |
parameters.onEvaluationError | string | No | "ALLOW" or "DENY" — controls behavior when the source IP cannot be determined |
Response
Remove IP allowlist
Deletes an IP allowlist and all its associated rules. After removal, access falls back to the next applicable allowlist or is allowed from all IPs.Request body
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Must be "ACTIVITY_TYPE_REMOVE_IP_ALLOWLIST" |
timestampMs | string | Yes | Current timestamp in milliseconds (epoch) |
organizationId | string | Yes | Your Turnkey organization ID |
parameters.publicKey | string | No | If omitted, removes the org-level allowlist. If set, removes the allowlist for that specific API key. |
Get IP allowlist
Retrieves the current IP allowlist and rules for an organization or specific API key.Request body
| Field | Type | Required | Description |
|---|---|---|---|
organizationId | string | Yes | Your Turnkey organization ID |
publicKey | string | No | If provided, returns the allowlist for that API key. If omitted, returns the org-level allowlist. |
Response
If the allowlist has been removed,
get_ip_allowlist returns an allowlist object with an empty rules array.Data types
IpAllowlistRule (response)
| Field | Type | Required | Description |
|---|---|---|---|
cidr | string | Yes | CIDR block |
label | string | No | Human-readable label (empty string if not set) |
createdAt | string | No | Creation timestamp as millisecond epoch string |
IpAllowlist (response)
| Field | Type | Required | Description |
|---|---|---|---|
organizationId | string | Yes | The organization this allowlist belongs to |
publicKey | string | No | The API key this applies to. null for org-level policies. |
enabled | boolean | No | Whether the allowlist is active. Only present for org-level policies. |
rules | IpAllowlistRule[] | Yes | Array of allowlist rules |
Code examples
- Set org-level allowlist
- Set API key-level allowlist
- Get allowlist
- Add a rule (fetch + resubmit)
- Remove allowlist