Cloud Client IP Restrictions
Client IP Restrictions restrict access to your Teleport Cloud cluster, allowing
traffic only from the network ranges (CIDR blocks) you specify. You manage the
allowlist with the client_ip_restriction resource, using tctl, the Teleport
Terraform provider, or the Teleport Web UI.
Managing the allowlist with tctl and the Teleport Terraform provider is
available starting with Teleport 18.12, as are draft mode and test runs. Managing the allowlist via the
Web UI is available in earlier versions, but using this approach enforces the
allowlist immediately: there is no draft stage or expiry safety net.
This guide covers how to:
- Configure a Teleport role that can manage Client IP Restrictions.
- Set the list of CIDR blocks allowed to connect to your Teleport Cloud cluster.
- Test an allowlist in draft mode and enforce it with an expiry, so that a misconfigured allowlist cannot lock you out permanently.
- Check whether the restrictions are enforced.
- Disable the restrictions.
How it works
The following example shows a client_ip_restriction resource retrieved from a
cluster with an enforced allowlist:
kind: client_ip_restriction
version: v1
metadata:
name: client-ip-restriction
spec:
allowed_cidrs:
- "203.0.113.0/24"
- "198.51.100.10/32"
mode: enforced
expires: "2026-09-30T22:00:00Z"
status:
state: active
client_ip_restriction is a singleton resource: each Teleport Cloud cluster has
exactly one, and its name is always client-ip-restriction. Its
spec.allowed_cidrs field holds the list of CIDR blocks permitted to connect to
the cluster. An empty list disables restrictions and allows all traffic.
Two more spec fields control how and when the allowlist is enforced:
modesets your intent.enforced(the default whenmodeis empty or unset) tells Teleport Cloud to enforce the allowlist.draftsaves the allowlist without enforcing it. Usedraftto review a new allowlist without affecting live traffic, or to keep a vetted allowlist on standby so you can enforce it the moment you need to — for example, to lock the cluster down to trusted networks during a security incident.expiresis an optional RFC 3339 timestamp that bounds enforcement. Setting it together withmode: enforcedstarts a test run, in which Teleport Cloud enforces the allowlist until the timestamp and not after it. Use it as a safety net so that an allowlist that locks you out stops being enforced on its own instead of requiring a support ticket. An unset value never expires. Do not setexpirestogether withmode: draft. Draft mode never enforces the allowlist, so the timestamp has no effect.
When expires passes, Teleport Cloud starts removing the allowlist from the
ingress layer. Enforcement continues for a few minutes while the rules are
removed; once the removal finishes, status.state becomes expired and all
traffic is allowed again. Teleport Cloud does not rewrite spec: mode still
reads enforced and expires still holds the time you set, so enforcing again
always takes a new write.
When the allowlist is enforced, Teleport Cloud applies it at the cluster's
ingress layer: only clients whose source IP falls within one of the allowed CIDR
blocks can reach the cluster. Changes take 5-15 minutes to propagate and
terminate existing connections that no longer match the allowlist. In draft
mode the allowlist is stored but never applied, and all traffic is allowed.
The resource's status.state field reflects the current enforcement state:
| State | Meaning |
|---|---|
draft | The allowlist is saved but not enforced, because mode is draft. All IPs can reach the cluster. |
pending | A change has been saved and is being propagated to the ingress layer. The previous enforcement state remains in effect until propagation finishes. |
active | The allowlist is fully enforced at the ingress layer. Only IPs matching the allowlist can reach the cluster. |
expired | The expires time has passed, so enforcement stopped. The allowlist is still saved and all IPs can reach the cluster. |
Access to read and modify the allowlist is governed by Teleport's RBAC system
through the client_ip_restriction resource kind, and every change is recorded
in the audit log.
Prerequisites
Client IP Restrictions are available to Teleport Cloud customers and are opt-in. Contact your account executive or support at [email protected] to enable the feature for your tenant.
- A Teleport Cloud cluster.
- A Teleport user with a role that can read and write the
client_ip_restrictionresource. The preseteditorrole has this access. To grant it to another role, follow Step 1. - One of the following client tools for managing the
client_ip_restrictionresource: thetctlCLI or the Teleport Terraform provider. The Kubernetes Operator does not support theclient_ip_restrictionresource.
To confirm that you can run tctl against your cluster:
Check that you can connect to your Teleport cluster and verify that you can run
tctl and tsh commands using your current credentials.
-
Assign teleport.example.com to the domain name of the Teleport Proxy Service in your cluster and [email protected] to your Teleport username.
-
Authenticate to your Teleport cluster. This depends on whether your shell is interactive or not.
In an interactive shell: Run the following command. By default, this triggers a multi-factor authentication prompt:
tsh login --proxy=teleport.example.com --user=[email protected]tctl statusCluster teleport.example.com
Version 18.11.0
CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678
On non-interactive environments: If you are running
tshandtctlas an AI agent, in a CI/CD environment, or similar, make sure theTELEPORT_IDENTITY_FILEenvironment variable is assigned to a valid file path with credentials for your cluster.tshandtctlread the file path from the environment variable and do not require a separate authentication step. If there is no identity file available, we recommend that you set up Machine ID to provision one automatically.When executing
tctlcommands with an identity file, you must pass the--auth-serverflag to provide the Teleport Auth Service address, which is not included in the identity file. If you provide the Proxy Service address,tctlconnects to the Proxy Service, which forwards traffic to and from the Teleport Auth Service. Update 443 to3025if you are contacting the Auth Service directly withtctl:tctl status --auth-server=teleport.example.com:443For
tshcommands that read an identity file, you must pass the--proxyflag, which pointstshto the address of the Teleport Proxy Service:tsh status --proxy=teleport.example.comEnsure client commands can access your identity file. Replace path/to/identity/file with the path to your identity file:
export TELEPORT_IDENTITY_FILE="${TELEPORT_IDENTITY_FILE:-path/to/identity/file}"Add the
--auth-serveror--proxyflags to all subsequenttctlandtshcommands.
If you can connect to the cluster and run the tctl status command, you can use your
current credentials to run subsequent tctl commands from your workstation.
If you host your own Teleport cluster, you can also run tctl commands on the computer that
hosts the Teleport Auth Service for full permissions.
Step 1/3. Configure RBAC
To read and modify Client IP Restrictions, a Teleport user needs permission to
manage the client_ip_restriction resource. The preset editor role already
has this access; if the user has the editor role, skip this step.
Create a file called client-ip-restriction-editor.yaml:
kind: role
version: v8
metadata:
name: client-ip-restriction-editor
spec:
allow:
rules:
- resources:
- client_ip_restriction
verbs:
- list
- read
- create
- update
- delete
Use tctl to create the role:
tctl create -f client-ip-restriction-editor.yaml
Assign the role to a user. Open the user resource in your editor, replacing
alice with the Teleport username:
tctl edit users/alice
Add client-ip-restriction-editor to spec.roles, then save and close the
editor to apply the change:
spec:
roles:
- access
+ - client-ip-restriction-editor
Step 2/3. Stage the allowlist in draft mode
A misconfigured allowlist can block all access to your cluster.
To avoid locking yourself out, roll out the allowlist in two stages. Save it in
draft mode first, then enforce it with an expiry. This way, a mistake stops
enforcing itself instead of becoming a permanent lockout that requires a
support ticket.
In this step, set mode: draft to save the allowlist without enforcing it.
Teleport Cloud stores the CIDR blocks but continues to allow all traffic, so you
can review the list with no risk of losing access.
- tctl
- Terraform
- Web UI
Create a file called client-ip-restriction.yaml:
kind: client_ip_restriction
version: v1
metadata:
name: client-ip-restriction
spec:
mode: draft
allowed_cidrs:
- "203.0.113.0/24"
- "198.51.100.10/32"
Replace the entries in allowed_cidrs with the CIDR blocks allowed to connect
to your cluster. metadata.name must be client-ip-restriction; the resource
is a singleton and no other name is accepted.
Apply the allowlist:
tctl create client-ip-restriction.yamlclient_ip_restriction has been created
If Client IP Restrictions already exist, tctl create reports an error. Use the
-f flag to overwrite the current allowlist:
tctl create -f client-ip-restriction.yamlclient_ip_restriction has been created
You can also edit the allowlist interactively. tctl edit opens the current
resource in your editor and applies your changes when you save and exit:
tctl edit client_ip_restriction
Read the resource back and confirm that status.state is draft:
tctl get client_ip_restriction
Before you begin, set up the Teleport Terraform provider.
Create a file called client-ip-restriction.tf:
resource "teleport_client_ip_restriction" "main" {
version = "v1"
metadata = {
name = "client-ip-restriction"
}
spec = {
mode = "draft"
allowed_cidrs = [
"203.0.113.0/24",
"198.51.100.10/32",
]
}
}
Replace the entries in allowed_cidrs with the CIDR blocks allowed to connect
to your cluster. metadata.name must be client-ip-restriction; the resource
is a singleton and no other name is accepted.
Apply the configuration:
terraform plan...
Plan: 1 to add, 0 to change, 0 to destroy.
terraform apply
Read the resource back with tctl get client_ip_restriction and confirm that
status.state is draft.
For the full list of supported fields, see the
teleport_client_ip_restriction resource reference.
Log in to your Teleport Cloud account. Open the user dropdown menu on the top right of the navigation bar and select "Help & Support," then scroll down to the IP Allowlist section and enter your CIDR blocks. A newly saved allowlist is stored as a draft, and the status banner reads "Draft".
If you do not see the IP Allowlist section, the feature has not been enabled for your account. See the Prerequisites for how to enable it.
Drafts and test runs in the Web UI require Teleport 18.12 or later. In earlier versions, saving the allowlist in the Web UI enforces it immediately, with no draft stage or expiry safety net. Before you save, make sure the list includes the network you are connecting from.
If the allowlist was already enforced, status.state reads pending for a few
minutes while Teleport Cloud removes the rules from the ingress layer, and
enforcement continues until that finishes. A first draft becomes draft
immediately, since there is nothing to tear down.
While the state is draft, verify that allowed_cidrs includes the network you
are currently connecting from, as well as any third-party services that need to
reach your cluster (CI/CD systems, identity providers, and so on). Teleport does
not add these ranges automatically.
You do not have to enforce the allowlist right away. You can leave it in draft
indefinitely as a vetted, ready-to-go configuration, then enforce it the moment
you need to — for example, to restrict access to trusted networks during a
security incident — as shown in the next step.
Step 3/3. Enforce the allowlist with an expiry safety net
Enforcing with an expiry is called a test run. It enforces the allowlist
exactly as a permanent rollout does, but only until expires. If the list is
wrong and locks you out, you do not need to do anything: when the test run
expires, Teleport Cloud starts removing the rules from the ingress layer, and a
few minutes later status.state becomes expired, the cluster is reachable
from any IP again, and your allowlist is still saved so you can correct it.
When the draft looks correct, set mode: enforced and an expires timestamp a
short time in the future. expires uses
RFC 3339 format and must be at least 20
minutes ahead. A numeric offset such as 2026-01-01T02:30:00+02:00 is accepted,
but we recommend UTC (the trailing Z) to avoid time zone mistakes. Teleport
Cloud enforces the allowlist, but if it locks you out, teardown starts at the
expiry time and access is restored once status.state becomes expired, a few
minutes later.
Compute a UTC timestamp 30 minutes from now:
- Linux
- macOS
date -u -d '+30 minutes' '+%Y-%m-%dT%H:%M:%SZ'2026-01-01T00:30:00Z
date -u -v+30M '+%Y-%m-%dT%H:%M:%SZ'2026-01-01T00:30:00Z
Use the output as the expires value:
- tctl
- Terraform
- Web UI
Update client-ip-restriction.yaml:
kind: client_ip_restriction
version: v1
metadata:
name: client-ip-restriction
spec:
mode: enforced
# Use the UTC timestamp from the command above.
expires: "2026-01-01T00:30:00Z"
allowed_cidrs:
- "203.0.113.0/24"
- "198.51.100.10/32"
Apply the change:
tctl create -f client-ip-restriction.yamlclient_ip_restriction has been created
Update client-ip-restriction.tf:
resource "teleport_client_ip_restriction" "main" {
version = "v1"
metadata = {
name = "client-ip-restriction"
}
spec = {
mode = "enforced"
# Use the UTC timestamp from the command above.
expires = "2026-01-01T00:30:00Z"
allowed_cidrs = [
"203.0.113.0/24",
"198.51.100.10/32",
]
}
}
Apply the configuration:
terraform apply
In the IP Allowlist panel, select "Test Run". This enforces the draft for 30 minutes and shows a countdown while the test run is active.
Every write replaces the entire resource, so when you edit the allowlist you
must re-send a still-valid expires or clear it. An expires value you read
earlier and send back unchanged is rejected once it is within 20 minutes of
the current time.
Before you clear the safety timer, wait for status.state to become active
and verify the allowlist: check that you can still reach the cluster and that
every expected network (including third-party services) can too. Access is
unchanged while the state is pending, so staying connected during the rollout
does not prove the list is correct — an allowlist confirmed while still
pending can lock you out for good once it takes effect.
Once verified, keep the allowlist enforced by removing expires (or extending
it) and reapplying. In the Web UI, "Confirm" does the same thing and is only
offered once the test run is active. With expires unset, enforcement never
lapses:
kind: client_ip_restriction
version: v1
metadata:
name: client-ip-restriction
spec:
mode: enforced
allowed_cidrs:
- "203.0.113.0/24"
- "198.51.100.10/32"
If you do not need the allowlist enforced yet, you can instead set mode: draft
after the test run. Leave expires unset, since it has no effect in draft
mode. The vetted allowlist stays saved and ready to enforce, but all traffic is
allowed. You can also simply let the test run expire. Once status.state is
expired, all traffic is allowed and the allowlist remains saved.
If you never set expires, the allowlist is enforced immediately and stays
enforced until you change it — with no automatic safety net. This is why we
recommend testing in draft mode first.
Check the enforcement status
Retrieve the resource to view the current allowlist and enforcement state:
tctl get client_ip_restriction
Example output:
kind: client_ip_restriction
version: v1
metadata:
name: client-ip-restriction
spec:
mode: enforced
allowed_cidrs:
- 203.0.113.0/24
- 198.51.100.10/32
status:
state: active
The allowlist is fully enforced when status.state is active. A pending
state means the change is still propagating to the ingress layer, which can take
up to 15 minutes. A draft state means the allowlist is saved but not enforced,
because mode is draft. An expired state means an expires time has passed
and enforcement stopped; the allowlist is still saved, but all IPs can reach the
cluster until you enforce it again.
Disable Client IP Restrictions
To allow traffic from all IP ranges again, either apply an allowlist with an
empty allowed_cidrs list or delete the resource:
tctl rm client_ip_restrictionclient_ip_restriction has been deleted
With Terraform, remove the teleport_client_ip_restriction resource from your
configuration and run terraform apply.
To stop enforcing the allowlist while keeping the CIDR list saved for later, set
mode: draft instead of deleting the resource. Removing the rules from the
ingress layer takes 5-15 minutes: status.state reads pending and enforcement
continues until the teardown finishes. All traffic is allowed once
status.state becomes draft.
Limitations
- Third-party service ranges. Teleport does not add third-party service ranges automatically. Add allow rules for any third-party service that needs to access your Teleport cluster, such as CI/CD systems and identity providers.
- Network security. The allowlist applies only to Teleport Cloud access. It does not replace your organization's network or firewall policies.
- Sync time. Changes to the allowlist take 5-15 minutes to fully sync to the ingress layer.
FAQ
How do I test an allowlist without risking a lockout?
Stage it in draft mode first, confirm the list is correct, then enforce it as a
test run with a short expires. If the list locks you out, enforcement stops on
its own a few minutes after the test run expires. See
Step 2 and
Step 3.
What is the difference between draft mode and disabling restrictions?
draft mode keeps your CIDR list saved but stops enforcing it, so you can
review or resume it later. Disabling restrictions (an empty allowed_cidrs list
or deleting the resource) discards the list. Both allow all traffic.
How many CIDR blocks can I configure?
By default, up to 256 CIDR blocks. Contact your account executive or support to increase the limit.
Do you support a denylist?
Teleport Cloud Client IP Restrictions do not currently support a denylist.
Can I manage Client IP Restrictions with the Kubernetes Operator?
No. The Kubernetes Operator does not support the client_ip_restriction
resource. Use tctl, the Terraform provider, or the Web UI instead.
Next steps
- Review the role resource reference to define more precise RBAC for managing Client IP Restrictions.
- Learn how Teleport records changes to the allowlist in the audit events reference.