
This guide shows you how to use Teleport roles to manage role-based access controls (RBAC) in your Teleport cluster.
Roles
A Teleport role
works by having two lists of rules: allow
rules and deny
rules.
When declaring access rules, keep in mind the following:
- Everything is denied by default.
- Deny rules get evaluated first and take priority.
A rule consists of two parts: the resources and verbs. Here's an example of an
allow
rule describing a list
verb applied to the SSH sessions
resource. It means "allow
users of this role to see a list of active SSH sessions".
allow:
- resources: [session]
verbs: [list]
If this rule was declared in the deny
section of a role definition, it
would prohibit users from getting a list of Trusted Clusters and
sessions. You can see all of the available resources and verbs under the allow
section in the example role configuration below.
To manage cluster roles, a Teleport administrator can use the Web UI or the command line using tctl resource commands. To see the list of roles in a Teleport cluster, an administrator can execute:
Log in to your cluster with tsh so you can use tctl from your local machine.
You can also run tctl on your Auth Service host without running "tsh login"
first.
tsh login --user=myuser --proxy=teleport.example.comtctl get roles
Backing up production instances, environments, and/or settings before making permanent modifications is encouraged as a best practice. Doing so allows you to roll back to an existing state if needed.
Here is a full role specification:
kind: role
version: v6
metadata:
name: example
spec:
# options specify connection, in case if user has multiple non-default
# conflicting options, teleport chooses the least permissive value.
options:
# max_session_ttl defines the TTL (time to live) of certificates
# issued to the users with this role.
max_session_ttl: 8h
# forward_agent controls whether SSH agent forwarding is allowed
forward_agent: true
# port_forwarding controls whether TCP port forwarding is allowed for SSH
port_forwarding: true
# ssh_file_copy controls whether file copying (SCP/SFTP) is allowed.
# Defaults to true.
ssh_file_copy: false
# client_idle_timeout determines if SSH sessions to cluster nodes are
# forcefully terminated after no activity from a client (idle client).
# it overrides the global cluster setting. examples: "30m", "1h" or "1h30m"
client_idle_timeout: never
# Determines if the clients will be forcefully disconnected when their
# certificates expire in the middle of an active session.
# It overrides the global cluster setting.
disconnect_expired_cert: no
# max_sessions is the total number of session channels that can be established
# across a single connection. Setting it to 10 matches OpenSSH default behavior.
# (enterprise-only)
max_sessions: 10
# Defines which events are recorded by the BPF-based session recorder.
enhanced_recording:
- command
- disk
- network
# permit_x11_forwarding allows users to use X11 forwarding with openssh
# clients and servers through the proxy
permit_x11_forwarding: true
# device_trust_mode enforces authenticated device access for the owner of this role.
device_trust_mode: optional|required|off
# require_session_mfa require per-session MFA for any owner of this role
require_session_mfa: true
# lock sets locking mode for user of this role,
# valid values are "strict" or "best_effort"
lock: strict
# enterprise-only request_access field is either 'always' or 'reason'. If set to always, it instructs
# tsh or the web UI clients to always create an Access Request on login. If it is
# set to 'reason', the user will be required to indicate why they are
# generating the Access Request.
request_access: reason
# the `request_prompt` field can be used to tell the user what should
# be supplied in the request reason field.
request_prompt: Please provide your ticket ID
# enterprise-only max_connections field sets a limit of concurrent sessions within a
# cluster. This setting slows down Teleport performance because it has to track
# connections cluster-wide.
max_connections: 2
# limit number of concurrent Kubernetes sessions per user
max_kubernetes_connections: 1
# Define how Teleport deals with session recording failures, such as a full
# disk error. The value can be set to either `best_effort` or `strict`. If
# set to `strict`, the session will terminate immediately. If set to
# `best_effort`, the session won’t be terminated, and the recording will be
# disabled. The configuration is done per service (currently, only `ssh` is
# supported).
record_session:
# Specify whether or not to record the user's desktop sessions.
# Desktop session recording is enabled if one or more of the user's
# roles has enabled recording. Defaults to true if unspecified.
# Desktop sessions will never be recorded if auth_service.session_recording
# is set to 'off' in teleport.yaml (Auth Service) or if the cluster's
# session_recording_config resource has set 'mode: off'.
desktop: true
# Optional: the default session recording mode to use when a
# protocol-specific mode is not set.
default: best_effort|strict
# Optional: Session recording mode for SSH sessions (Teleport Server
# Access). If not set, the value set on default will be used.
ssh: best_effort|strict
# Specify whether clipboard sharing should be allowed with the
# remote desktop (requires a supported browser). Defaults to true
# if unspecified. If one or more of the user's roles has disabled
# the clipboard, then it will be disabled.
desktop_clipboard: true
# enterprise-only: when enabled, the source IP that was used to log in is embedded in the SSH
# certificate, preventing a compromised certificate from being used on other
# devices. The default is false.
# Note: Source IP pinning is currently in Preview mode.
pin_source_ip: true
# Specify a list of names and associated values to be included in user SSH keys.
# The key type can only be "ssh" and the mode can only be "extension".
# The name and value fields can be arbitrary strings and the value field
# supports variable interpolation.
cert_extensions:
- type: ssh
mode: extension
name: [email protected]
value: "{{ external.github_login }}"
# Controls whether this role supports auto provisioning of users.
create_host_user: true
# Specifies role specific options for identity provider access.
idp:
# Specifies role specific options for SAML identity provider access.
saml:
# Specifies whether this role has access to the SAML identity provider.
# Defaults to true.
enabled: true
# The allow section declares a list of resource/verb combinations that are
# allowed for the users of this role. By default, nothing is allowed.
allow:
# The logins array defines the OS/UNIX logins a user is allowed to use.
# both strings and template variables are supported in this field
logins: [root, '{{internal.logins}}']
# Windows logins a user is allowed to use for desktop sessions.
windows_desktop_logins: [Administrator, '{{internal.logins}}']
# node_labels: a user with this role will be allowed to connect to
# SSH nodes, which labels match expressions below.
node_labels:
# literal strings:
'env': 'test'
# the wildcard ('*') means "any node"
'*': '*'
# a list of alternative options:
'region': ['us-west-1', 'eu-central-1']
# regular expressions start with ^ and end with $
# Teleport uses golang regexp syntax.
# of the list example above can be expressed as:
'reg': '^us-west-1|eu-central-1$'
# kubernetes_groups specifies Kubernetes groups a user with this role will assume.
# You can refer to a SAML/OIDC trait via the "external" property bag.
# This allows you to specify Kubernetes group membership in an identity manager:
kubernetes_groups: ["system:masters", "{{external.trait_name}}"]
# kubernetes_users is an optional field that specifies kubernetes users
# this role can assume.
kubernetes_users: ['IAM#{{external.foo}};']
# kubernetes_labels: a user with this role will be allowed to connect to
# k8s clusters, which labels match expressions below.
kubernetes_labels:
# A user can only access prod environments
'env': 'prod'
# User can access any region in us-west, e.g us-west-1, us-west-2
'region': 'us-west-*'
# regular expressions start with ^ and ending with $
# Teleport uses golang regexp syntax.
'cluster_name': '^us.*\.example\.com$'
# kubernetes_resources indicates the Kubernetes resources that a user with
# this role is allowed to access.
kubernetes_resources:
# The resource kind. Teleport currently only supports "pod".
- kind: pod
# The name of the Kubernetes namespace in which to allow access the
# resources you specify with "name" and "kind".
# The wildcard character "*" matches any sequence of characters.
# If the value begins with "^" and ends with "$", the Kubernetes
# Service will treat it as a regular expression.
namespace: "*"
# The name of the resource to allow access to.
# The wildcard character "*" matches any sequence of characters.
# If the value begins with "^" and ends with "$", the Kubernetes
# Service will treat it as a regular expression.
name: "^nginx-[a-z0-9-]+$"
# Functions transform variables.
db_users: ['{{email.local(external.email)}}']
db_names: ['{{external.db_names}}']
db_labels:
'env': '{{regexp.replace(external.access["env"], "^(staging)$", "$1")}}'
# app_labels: a user with this role will be allowed to connect to
# applications, which labels match expressions below.
app_labels:
# A user can only access prod environments
'env': 'prod'
# User can access any region in us-west, e.g us-west-1, us-west-2
'region': 'us-west-*'
# Regular expressions start with ^ and end with $.
# Teleport uses Go's regular expression syntax:
# https://github.com/google/re2/wiki/Syntax
# The list example above can be expressed as:
# 'region': '^us-west-1|eu-central-1$'
'cluster_name': '^us.*\.example\.com$'
# aws_role_arns allows a user with this role to assume AWS roles when
# accessing AWS console using UI or AWS API using CLI
aws_role_arns:
- 'arn:aws:iam::1234567890:role/ec2-read-only'
- 'arn:aws:iam::1234567890:role/ec2-full-access'
- 'arn:aws:iam::0987654321:role/example-role'
# impersonate allows a user with this role to issue certificates on behalf
# of other users and roles matching expressions below
impersonate:
users: ['*']
roles: ['jenkins']
# where is an optional where condition
# further limiting the scope for matching users and roles
where: >
contains(user.spec.traits["group"], impersonate_role.metadata.labels["group"]) &&
contains(user.spec.traits["group"], impersonate_user.metadata.labels["group"])
# review_requests allows a user holding this role
# to approve or deny Access Requests (enterprise-only)
review_requests:
# the reviewer can view and approve or deny access requests for any roles
# listed here
roles: ['dbadmin']
# the reviewer can preview details about resources accessible by any roles
# listed in preview_as_roles when reviewing Resource Access Requests
preview_as_roles: ['dbadmin']
# request allows a user user request roles matching
# expressions below
request:
# the `roles` list can be a mixture of literals and wildcard matchers
roles: ['common', 'dev-*']
# `search_as_roles` allows users to search for and request access to
# resources accessible by the listed roles (enterprise-only)
search_as_roles: ['access']
# thresholds specifies minimum amount of approvers and deniers,
# defaults to 1 for both (enterprise-only)
thresholds:
# requires at least two qualifying approvers and at least one denier.
- approve: 2
deny: 1
# the `claims_to_roles` mapping works the same as it does in
# the OIDC connector, with the added benefit that the roles being mapped to
# can also be matchers. the below mapping says that users with
# the claims `groups: admins` can request any role in the system.
claims_to_roles:
- claim: 'projects'
# matches all group names with a leading 'product-'
value: '^product-(.*)$'
# generates a role name from the value capture
roles: ['$1-admin']
# Teleport can attach annotations to pending Access Requests. these
# annotations may be literals, or be variable interpolation expressions,
# effectively creating a means for propagating selected claims from an
# external identity provider to the plugin system.
annotations:
foo: ['bar']
groups: ['{{external.groups}}']
# Moderated Sessions policy that dictates requirements for starting a session.
require_session_join:
# Defines the name of the policy. The name serves only as an
# identifier in logs and for organisation/categorisation.
- name: Auditor oversight
# Specifies an RBAC predicate that is used to define
# which users count against the required user count of the policy.
filter: 'contains(user.spec.roles, "auditor")'
# The different session kinds this policy applies to.
kinds: ['k8s', 'ssh']
# A list of session participant modes that a participant must have
# one of in order to count against the policy.
modes: ['moderator']
# The minimum amount of users that need to match the filter expression
# in order to satisfy the policy.
count: 1
# The action to take if a moderator leaves a session, causing the policy to no longer be satisfied.
# This may be either "terminate" or "pause". An empty or unknown value will default to "terminate".
on_leave: "terminate"
# Moderated Sessions policy that dictates the ability to join sessions
join_sessions:
# Defines the name of the policy. The name serves only as an
# identifier in logs and for organisation/categorisation.
- name: Auditor oversight
# Allows one to join sessions created by other users with these roles
roles : ['prod-access']
# The different session kinds this policy applies to.
kinds: ['k8s', 'ssh']
# The list of session participant modes the role may join the session as.
modes: ['moderator', 'observer']
# rules allow a user holding this role to modify other resources
# matching the expressions below
# supported resources:
# role - role resource
# user - user resource
#
# auth_connector - any auth connector resource
# oidc - OIDC connector resource
# saml - connector resource
# github - GitHub connector resource
#
# trusted_cluster - Trusted Cluster resource
# remote_cluster - remote cluster resource
#
# access_request - Access Request resource
# access_plugin_data - allows modifying Access Request plugin data
#
# session - session playback records
# ssh_session - an active SSH session
# event - structured audit logging event
#
#
# lock - lock resource.
# network_restrictions - restrictions for SSH sessions
#
# auth_server - Auth Service resource
# proxy - Proxy Service resource
# node - SSH node resource
# app - application resource
# db - database resource
# kube_cluster - Kubernetes cluster resource
# token - provisioning token resource
# cert_authority - certificate authority resource
#
# cluster_name - resource that contains the cluster name.
# cluster_config - resource that holds cluster level config
# cluster_auth_preference - type of authentication for this cluster
# session_recording_config - resource for session recording config
# cluster_audit_config - resource that holds cluster audit config
# cluster_networking_config - resource that holds cluster networking config
rules:
- resources: [role]
verbs: [list, create, read, update, delete]
- resources: [auth_connector]
verbs: [list, create, read, update, delete]
- resources: [session]
verbs: [list, read]
- resources: [trusted_cluster]
verbs: [list, create, read, update, delete]
- resources: [event]
verbs: [list, read]
- resources: [user]
verbs: [list, create, read, update, delete]
- resources: [token]
verbs: [list, create, read, update, delete]
# The deny section uses the identical format as the 'allow' section.
# The deny rules always override allow rules.
deny: {}
The following variables can be used with logins
and windows_desktop_logins
fields:
Variable | Description |
---|---|
{{internal.logins}} | Substituted with a value stored in Teleport's local user database and logins from a root cluster. For local users, Teleport will substitute this with the "allowed logins" parameter used in the tctl users add [user] <allowed logins> command. If the role is within a leaf cluster in a Trusted Cluster, Teleport will substitute the logins from the root cluster whether the user is a local user or from an SSO provider. As an example, if the user has the ubuntu login in the rootcluster, then ubuntu will be substituted in the leafcluster with this variable. |
{{external.xyz}} | Substituted with a value from an external SSO provider. If using SAML, this will be expanded with "xyz" assertion value. For OIDC, this will be expanded a value of "xyz" claim. |
Both variables above are there to deliver the same benefit: they allow Teleport administrators to define allowed OS logins via the user database, be it the local DB, or an identity manager behind a SAML or OIDC endpoint.
An example of a SAML assertion
Assuming you have the following SAML assertion attribute in your response:
<Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname">
<AttributeValue>firstname.lastname</AttributeValue>
</Attribute>
... you can use the following format in your role:
logins:
- '{{external["http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname"]}}'
Role options
As shown above, a role can define certain restrictions on sessions initiated by users. The table below documents the behavior of each option if multiple roles are assigned to a user.
Option | Description | Multi-role behavior |
---|---|---|
max_session_ttl | Max. time to live (TTL) of a user's SSH certificates | The shortest TTL wins |
forward_agent | Allow SSH agent forwarding | Logical "OR" i.e. if any role allows agent forwarding, it's allowed |
port_forwarding | Allow TCP port forwarding | Logical "OR" i.e. if any role allows port forwarding, it's allowed |
ssh_file_copy | Allow SCP/SFTP | Logical "AND" i.e. if all roles allows file copying, it's allowed |
client_idle_timeout | Forcefully terminate active sessions after an idle interval | The shortest timeout value wins, i.e. the most restrictive value is selected |
disconnect_expired_cert | Forcefully terminate active sessions when a client certificate expires | Logical "OR" i.e. evaluates to "yes" if at least one role requires session termination |
max_sessions | Total number of session channels which can be established across a single SSH connection via Teleport | |
enhanced_recording | Indicates which events should be recorded by the BFP-based session recorder | |
permit_x11_forwarding | Allow users to enable X11 forwarding with OpenSSH clients and servers | |
device_trust_mode | Enforce authenticated device access for the owner of this role (required , optional , off ) | |
require_session_mfa | Enforce per-session MFA or PIV-hardware key restrictions on user login sessions (no , yes , hardware_key , hardware_key_touch ) | For per-session MFA, Logical "OR" i.e. evaluates to "yes" if at least one role requires session MFA |
lock | Locking mode (strict or best_effort ) | strict wins in case of conflict |
request_access | Enterprise-only Access Request strategy (optional , always or reason ) | |
request_prompt | Prompt for the Access Request "reason" field | |
max_connections | Enterprise-only limit on how many concurrent sessions can be started via Teleport | |
max_kubernetes_connections | Defines the maximum number of concurrent Kubernetes sessions per user | |
record_session | Defines the Session recording mode. | The strictest value takes precedence. |
desktop_clipboard | Allow clipboard sharing for desktop sessions | Logical "AND" i.e. evaluates to "yes" if all roles enable clipboard sharing |
pin_source_ip | Enable source IP pinning for SSH certificates. Note: IP pinning is currently in Preview mode | Logical "OR" i.e. evaluates to "yes" if at least one role requires session termination |
cert_extensions | Specifies extensions to be included in SSH certificates | |
create_host_user | Allow users to be automatically created on a host | Logical "AND" i.e. evaluates to "yes" if all roles matching a Node enable host user creation |
Preset roles
Teleport provides several pre-defined roles out-of-the-box:
Role | Description |
---|---|
editor | Allows editing of cluster configuration settings. |
auditor | Allows reading cluster events, audit logs, and playing back session records. |
access | Allows access to cluster resources. |
Role versions
There are currently four supported role versions: v3
, v4
, v5
and v6
. v4
, v5
and v6
roles are
completely backwards-compatible with v3
, the only difference lies in the
default values which will be applied to the role if they are not
explicitly set. Additionally, roles v5
or v6
are required to use Moderated Sessions.
Label | v3 Default | v4 , v5 and v6 Default |
---|---|---|
node_labels | [{"*": "*"}] if the role has any logins, else [] | [] |
app_labels | [{"*": "*"}] | [] |
kubernetes_labels | [{"*": "*"}] | [] |
database_labels | [{"*": "*"}] | [] |
Role v6
introduced a new field kubernetes_resources
that allows
fine-grained control over Kubernetes resources. See Kubernetes RBAC for more details.
Label | v3 , v4 and v5 Default | v6 Default |
---|---|---|
kubernetes_resources | [{"kind":"pod", "name":"*", "namespace":"*"}] | [] |
RBAC for hosts
A Teleport role can also define which hosts (nodes) a user can have access to. This works by labeling nodes and listing allow/deny labels in a role definition.
Consider the following use case:
The infrastructure is split into staging/production environments using labels
like environment=production
and environment=staging
. You can create roles
that only have access to one environment. Let's say you create an intern role with the allow rule for label environment=staging
.
Example
The role below allows access to all nodes labeled "env=stage" except those that also have "workload=database" or "workload=backup".
Access to any other nodes will be denied.
kind: role
version: v5
metadata:
name: example-role
spec:
allow:
node_labels:
'env': 'stage'
deny:
node_labels:
# Multiple labels are interpreted as an "or" operation. In this case,
# Teleport will deny access to any node labeled as 'workload=database' or
# 'workload=backup'
'workload': ['database', 'backup']
Node labels can be dynamic, i.e. determined at runtime by an output of an executable. In this case, you can implement "permissions follow workload" policies (eg., any server where PostgreSQL is running becomes automatically accessible only by the members of the "DBA" group and nobody else).
Extended Node labels syntax
Below are a few examples for more complex filtering using various regexes.
kind: role
version: v5
metadata:
name: example-role
spec:
allow:
node_labels:
# literal strings:
'environment': 'test'
# the wildcard ('*') means "any node"
'*': '*'
# a list of alternative options:
'environment': ['test', 'staging']
# regular expressions are also supported, for example the equivalent
# of the list example above can be expressed as:
'environment': '^test|staging$'
Teleport resources
RBAC lets teams limit what resources are available to Teleport users. This can be helpful if, for example,
you don't want regular users editing SSO (auth_connector
) or creating and editing new roles
(role
).
Below is an example allow
section that illustrates commonly used rules
.
Each rule includes a list of Teleport resources and the CRUD
operations that a user is allowed to execute on them:
allow:
rules:
# CRUD options for managing Teleport Server Access Nodes
- resources:
- node
verbs: [list, create, read, update, delete]
- resources:
- app
verbs: [list, create, read, update, delete]
- resources:
- kube_service
verbs: [list, create, read, update, delete]
- resources:
- kube_cluster
verbs: [list, create, read, update, delete]
- resources:
- db
verbs: [list, create, read, update, delete]
- resources:
- windows_desktop
verbs: [list, create, read, update, delete]
- resources:
- role
verbs: [list, create, read, update, delete]
# Auth connectors are also known as SSO connectors
- resources:
- auth_connector
verbs: [list, create, read, update, delete]
# Session: Provides access to Session Recordings.
# e.g If session read is false, users can't play the recordings
# It is possible to restrict "list" but to allow "read" (in this case a user will
# be able to replay a session using `tsh play` if they know the session ID).
- resources:
- session
verbs: [list, read]
- resources:
- trusted_cluster
verbs: [list, create, read, update, delete]
# Events: Determines whether a user can view the audit log
# and session recordings.
- resources:
- event
verbs: [list, read]
- resources:
- user
verbs: [list, create, read, update, delete]
- resources:
- token
verbs: [list, create, read, update, delete]
RBAC for sessions
It is possible to further limit access to shared sessions and session recordings. The examples below illustrate how to restrict session access only for the user who created the session.
Teleport versions prior to 8.1 don't support the roles shown below. You may create these roles after upgrading, but in the event of a cluster downgrade they will become invalid.
In order for these roles to take effect, you must ensure your user doesn't also
have a more permissive role, like the preset auditor
role, which allows access
to all events, sessions, and session recordings.
Role for restricted access to session recordings:
version: v5
kind: role
metadata:
name: only-own-sessions
spec:
allow:
rules:
# Users can only view session recordings for sessions in which they
# participated.
- resources: [session]
verbs: [list, read]
where: contains(session.participants, user.metadata.name)
Role for restricted access to active sessions:
version: v5
kind: role
metadata:
name: only-own-ssh-sessions
spec:
allow:
rules:
# Teleport allows shared session access by default, so for our restrictions
# to work we first allow access to ssh_sessions...
- resources: [ssh_session]
verbs: ['*']
deny:
rules:
# ... and then limit that access via a deny rule.
# Deny rules take precedence over allow rules, so the resulting role allows
# users to create SSH sessions but to only view their own sessions.
- resources: [ssh_session]
verbs: [list, read, update, delete]
where: '!contains(ssh_session.participants, user.metadata.name)'
Second Factor - U2F
Refer to the Second Factor - WebAuthn guide if you have a cluster using the legacy U2F support.
Filter fields
Here is an explanation of the fields used in the where
and filter
conditions within this guide.
Field | Description |
---|---|
user.spec.roles | The list of roles assigned to a user |
session.participants | The list of participants from a session recording |
ssh_session.participants | The list of participants from an SSH session |
user.metadata.name | The user's name |
Check out our predicate language guide for a more in depth explanation of the language.