Creating an Access List for Standing Access
The Standing Access Guide creates an Access List whose members are automatically granted access to a defined set of resources when they log in. No Access Request is required.
In this guide, you will:
- Decide when a Standing Access List is the right fit
- Create one with the Teleport Web UI,
tctl, or Terraform - Verify that members get access on login
When to use this flow
Use a Standing Access List when:
- Members need the access as part of their day-to-day work.
- The set of resources is well-scoped (e.g. internal dashboards for the analytics team) and changes infrequently.
- You want a single list to govern who has the access, with periodic reviews so the membership is reaffirmed rather than left to drift.
- You'd rather have Teleport generate the supporting roles than write role specs by hand.
If members should instead request temporary access, use the Just-in-Time Access Guide instead.
Prerequisites
-
A running Teleport Enterprise (v18.8.0 or higher) cluster accessible at a hostname with a valid TLS certificate. If you want to get started with Teleport, sign up for a free trial or set up a demo environment.
-
The
tctlandtshclients, required only if creating the list withtctlor Terraform.Installing
tctlandtshclients-
Determine the version of your Teleport cluster. The
tctlandtshclients must be at most one major version behind your Teleport cluster version. Send a GET request to the Proxy Service at/v1/webapi/findand use a JSON query tool to obtain your cluster version. Replace teleport.example.com:443 with the web address of your Teleport Proxy Service:- Mac/Linux
- Windows - Powershell
TELEPORT_DOMAIN=teleport.example.com:443TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')"$TELEPORT_DOMAIN = "teleport.example.com:443"$TELEPORT_VERSION = (Invoke-RestMethod -Uri "https://${TELEPORT_DOMAIN}/v1/webapi/find").server_version -
Follow the instructions for your platform to install
tctlandtshclients:- Mac
- Windows - Powershell
- Linux
Download the signed macOS .pkg installer for Teleport, which includes the
tctlandtshclients:curl -O https://cdn.teleport.dev/teleport-${TELEPORT_VERSION?}.pkgIn Finder double-click the
pkgfile to begin installation.dangerUsing Homebrew to install Teleport is not supported. The Teleport package in Homebrew is not maintained by Teleport and we can't guarantee its reliability or security.
curl.exe -O https://cdn.teleport.dev/teleport-v$TELEPORT_VERSION-windows-amd64-bin.zipUnzip the archive and move the `tctl` and `tsh` clients to your %PATH%
NOTE: Do not place the `tctl` and `tsh` clients in the System32 directory, as this can cause issues when using WinSCP.
Use %SystemRoot% (C:\Windows) or %USERPROFILE% (C:\Users\<username>) instead.
All of the Teleport binaries in Linux installations include the
tctlandtshclients. For more options (including RPM/DEB packages and downloads for i386/ARM/ARM64) see our installation page.curl -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gztar -xzf teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gzcd teleportsudo ./installTeleport binaries have been copied to /usr/local/bin
Connecting with TLS routing disabled
This guide's commands assume your Teleport cluster uses TLS routing (
proxy_listener_mode: multiplex), where thetctlandtshclients reach every Teleport service through the Proxy Service's web address on port443. If you're not sure whether this applies to your cluster, check with whoever manages it.If your cluster uses separate listener ports instead, adjust ports as follows:
-
tshcommands (e.g.,tsh login --proxy=...): continue using the Proxy Service web address on port3080(or443if behind a load balancer). Do not change these to port3025. -
Direct
tctlor Auth Service API commands: use port3025for the Auth Service gRPC listener:tctl status --auth-server=teleport.example.com:3025
-
-
At least one user who will be a member of the list, preferably a user with no access to resources to verify the access flow later.
-
At least one resource enrolled in the cluster for the Access List to grant access to.
- Permissions to create Access Lists, users, and roles. These are included in the preset
editorrole, or you can copy and paste the following into your own role:allow: rules: - resources: - access_list - user - role verbs: - read - list - create - update - delete
Step 1/2. Create the Access List
Choose how to create the list.
- Web UI
- tctl
- Terraform
In the Teleport Web UI, hover over Add New from the sidebar menu then click Access List.
Enter a name and optional description for the list.
Click Standing Access Guide and click Start Guide.
The guide steps you through:
-
Define Access to Resources — for each resource type, specify the matching criteria. Most resource types are matched by labels; others may ask you to select the resource itself. Members get access to anything that matches when they log in.
Previewing ResourcesAfter defining access for a resource type, the UI shows a preview of matching resources. The preview is limited by your own role permissions — members may be granted access to additional resources that aren't visible to you.
-
Define Resource Identities or Principals — for resource types that need them (e.g. SSH logins, database users, Kubernetes users/groups, etc.), specify which principals members can use to connect.
-
Basic Information — confirm the name and description of the Access List, and select the next review date. Periodic reviews are how list owners reaffirm that the right members are still on the list.
-
Define Membership — add the users who should receive the access.
-
Define Ownership — add the users responsible for managing the list and reviewing membership.
At the final Deployment step, click Create Access List Now. The list is created directly via the Teleport API and is immediately active.
tctl acl create was introduced in tctl v18.10.3. On earlier versions of
tctl, use the Web UI.
The following command creates a list that lets bob connect to SSH servers
labeled env: test as the ubuntu OS user. The access applies as soon as bob
logs in to Teleport. alice owns the list and reviews its membership.
Substitute the usernames, roles, labels, and logins with ones that suit your
cluster:
tctl acl create \ --access-type standing \ --title "Standing access for support engineers" \ --description "Standing access to test servers." \ --audit-frequency 6 \ --audit-day 1 \ --owners alice \ --owner-required-roles manager \ --members bob \ --member-required-roles engineer \ --node-labels env=test \ --logins ubuntu
See tctl acl create for the
full list of flags.
Every list-valued flag takes a comma-separated string, for example
--members bob,carol. Members can also be added after the fact with
tctl acl users add.
tctl acl create accepts --output terraform as of tctl v19.0.0. On earlier
versions of tctl, use the Web UI instead: the guided flow mirrors your input as
a Terraform module, which you can copy at the final Deployment step.
Generate the configuration
The tctl acl create --output terraform command will not create anything, but
instead prints a Terraform module describing the Access List the other flags
define, which you can write straight to a file.
The following command generates a module for a list that lets bob connect to
SSH servers labeled env: test as the ubuntu OS user. The access applies as
soon as bob logs in to Teleport. alice owns the list and reviews its
membership. Substitute the usernames, roles, labels, and logins with ones that
suit your cluster:
tctl acl create \ --access-type standing \ --title "Standing access for support engineers" \ --description "Standing access to test servers." \ --owners alice \ --owner-required-roles manager \ --members bob \ --member-required-roles engineer \ --node-labels env=test \ --logins ubuntu \ --output terraform > access-list.tf
See tctl acl create for the
full list of flags.
The dry-run is a complete module: a provider block, the three role definitions a
Standing Access List needs, the Access List itself, and one member resource per
user you passed to --members. The provider's addr is filled in from the
cluster tctl is talking to, so your output will be similar to the following:
# Terraform config for creating an Access List that grants members direct
# access to Teleport resources defined in the associated roles.
terraform {
required_providers {
teleport = {
source = "terraform.releases.teleport.dev/gravitational/teleport"
version = "~> 19.0"
}
}
}
provider "teleport" {
addr = "teleport.example.com:443"
}
resource "teleport_role" "access-standard-acl-preset-0a1b2c3d-4e5f-6789-abcd-ef0123456789" {
version = "v8"
metadata = {
name = "access-standard-acl-preset-0a1b2c3d-4e5f-6789-abcd-ef0123456789"
labels = {
"teleport.dev/iac-tool" = "terraform"
"teleport.internal/access-list-preset" = "0a1b2c3d-4e5f-6789-abcd-ef0123456789"
}
}
spec = {
options = {
max_session_ttl = "30h0m0s"
cert_format = "standard"
enhanced_recording = ["command", "network"]
record_session = {
desktop = true
default = "best_effort"
}
desktop_clipboard = true
desktop_directory_sharing = true
ssh_file_copy = true
}
allow = {
logins = ["ubuntu"]
node_labels = {
env = ["test"]
}
}
}
}
# A role that requires requesting access to resources. Can optionally assign to any users outside of this access list.
resource "teleport_role" "requester-acl-preset-0a1b2c3d-4e5f-6789-abcd-ef0123456789" {
version = "v8"
metadata = {
name = "requester-acl-preset-0a1b2c3d-4e5f-6789-abcd-ef0123456789"
labels = {
"teleport.dev/iac-tool" = "terraform"
"teleport.internal/access-list-preset" = "0a1b2c3d-4e5f-6789-abcd-ef0123456789"
}
}
spec = {
options = {
max_session_ttl = "30h0m0s"
cert_format = "standard"
enhanced_recording = ["command", "network"]
record_session = {
desktop = true
default = "best_effort"
}
desktop_clipboard = true
desktop_directory_sharing = true
ssh_file_copy = true
}
allow = {
request = {
search_as_roles = ["access-standard-acl-preset-0a1b2c3d-4e5f-6789-abcd-ef0123456789"]
}
}
}
}
# A role that allows reviewing access requests (assigned to owners).
resource "teleport_role" "reviewer-acl-preset-0a1b2c3d-4e5f-6789-abcd-ef0123456789" {
version = "v8"
metadata = {
name = "reviewer-acl-preset-0a1b2c3d-4e5f-6789-abcd-ef0123456789"
labels = {
"teleport.dev/iac-tool" = "terraform"
"teleport.internal/access-list-preset" = "0a1b2c3d-4e5f-6789-abcd-ef0123456789"
}
}
spec = {
options = {
max_session_ttl = "30h0m0s"
cert_format = "standard"
enhanced_recording = ["command", "network"]
record_session = {
desktop = true
default = "best_effort"
}
desktop_clipboard = true
desktop_directory_sharing = true
ssh_file_copy = true
}
allow = {
review_requests = {
roles = ["access-standard-acl-preset-0a1b2c3d-4e5f-6789-abcd-ef0123456789"]
preview_as_roles = ["access-standard-acl-preset-0a1b2c3d-4e5f-6789-abcd-ef0123456789"]
}
}
}
}
resource "teleport_access_list" "acl-0a1b2c3d-4e5f-6789-abcd-ef0123456789" {
header = {
kind = "access_list"
version = "v1"
metadata = {
name = "0a1b2c3d-4e5f-6789-abcd-ef0123456789"
labels = {
"teleport.dev/iac-tool" = "terraform"
"teleport.internal/access-list-preset" = "long-term"
"teleport.internal/access-list-preset-roles" = "reviewer-acl-preset-0a1b2c3d-4e5f-6789-abcd-ef0123456789,requester-acl-preset-0a1b2c3d-4e5f-6789-abcd-ef0123456789,access-standard-acl-preset-0a1b2c3d-4e5f-6789-abcd-ef0123456789"
}
}
}
spec = {
description = "Standing access to test servers."
owners = [{
membership_kind = "1"
name = "alice"
}]
membership_requires = {
roles = ["engineer"]
}
ownership_requires = {
roles = ["manager"]
}
grants = {
roles = ["access-standard-acl-preset-0a1b2c3d-4e5f-6789-abcd-ef0123456789"]
}
title = "Standing access for support engineers"
owner_grants = {
roles = ["reviewer-acl-preset-0a1b2c3d-4e5f-6789-abcd-ef0123456789"]
}
type = "static"
}
}
resource "teleport_access_list_member" "acl-member-bob_86c6a0d4" {
depends_on = [teleport_access_list.acl-0a1b2c3d-4e5f-6789-abcd-ef0123456789]
header = {
kind = "access_list_member"
version = "v1"
metadata = {
name = "bob"
}
}
spec = {
access_list = "0a1b2c3d-4e5f-6789-abcd-ef0123456789"
name = "bob"
membership_kind = "1"
}
}
Note the type = "static" field. Access Lists managed with Terraform must be
static so that Terraform can own their membership, and static lists do not
support periodic auditing. To learn the differences, see
Static versus default Access Lists.
Apply the configuration
Log in to your cluster, assigning teleport.example.com:443 to your Teleport proxy address and email@example.com to your Teleport username:
tsh login --proxy=teleport.example.com:443 --user=email@example.com
Generate temporary credentials for the Terraform provider:
eval "$(tctl terraform env)"
Initialize Terraform, preview the changes, and apply them:
terraform initterraform planterraform apply
The Access List is created once terraform apply completes.
The steps above use tctl terraform env to issue short-lived credentials,
which is convenient for trying things out locally. For remote environments
such as CI/CD pipelines or cloud VMs, see the
Terraform provider documentation
for guidance on setting up the provider.
To write the configuration by hand instead of generating it, or for the full set
of fields on the teleport_access_list and teleport_access_list_member
resources, see
Creating Access Lists with IaC.
However you created the list, keep the supporting roles' names and their
teleport.internal/access-list-preset* labels unchanged. Both the Web UI Access
List editor and tctl acl update rely on them to recognize which roles belong
to this Access List.
To change what the list grants:
- Web UI — from the sidebar menu, click Identity Governance > Access Lists, click the target Access List, open the Access Definition tab, then click Edit Access.
tctl— reruntctl acl updatewith the resource flags you want. It updates the supporting roles for you.- Terraform — rerun
tctl acl updatewith the resource flags you want and--output terraformto regenerate the configuration, then apply it.
Both tools support only a limited subset of role fields. If the roles end up
outside that subset, neither can change the list's grants — the Web UI editor
can no longer parse them, and tctl acl update rejects them rather than
silently dropping the fields you added. From that point on you must manage the
roles directly for the rest of the Access List's life.
Step 2/2. Verify the access
Log in as one of the members you added. The resources the list covers should appear in the resource list and you should be able to connect to them immediately.
Next steps
- Create an Access List whose members request temporary access with the Just-in-Time Access Guide.
- Create an Access List by assigning existing roles directly with the Custom Form.
- Group members by inheriting access from other lists with nested Access Lists.
- Learn more about managing Access Lists as code with the Terraform provider and Kubernetes operator.