Securing Infrastructure Access at Scale in Large Enterprises
Dec 12
Virtual
Register Now
Teleport logoTry For Free
Fork me on GitHub

Teleport

Teleport Access Controls Reference

This guide shows you how to use Teleport roles to manage role-based access controls (RBAC) in your Teleport cluster.

A Teleport role manages access by having two lists of rules: allow rules and deny rules. When declaring access rules, keep in mind the following:

  • Nothing is allowed by default.
  • Deny rules get evaluated first and take priority.

You can use any of the following to manage Teleport roles and other dynamic resources:

  • Teleport Web UI
  • The tctl client tool
  • Teleport Terraform provider
  • Teleport Kubernetes operator
  • Custom API clients

To read more about managing dynamic resources, see the Dynamic Resources guide.

You can view all roles in your cluster on your local workstation by running the following commands:

Log in to your cluster with tsh so you can use tctl from your local machine.

tsh login --user=myuser --proxy=mytenant.teleport.sh
tctl get roles
Warning

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.

Example role specification

Here is a full role specification:

kind: role
version: v7
metadata:
  name: example
  description: This is an example role.
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 assigned user of this role.
    device_trust_mode: optional|required|off
    # require_session_mfa require per-session MFA for any assigned user 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 'optional', 'always' or 'reason'. If set to always or reason,
    # it instructs tsh or the web UI clients to always create an Access Request. 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
    # Specify whether directory sharing should be allowed from the
    # local machine to remote desktop (requires a supported browser). Defaults to true
    # if unspecified. If one or more of the user's roles has disabled
    # directory sharing, then it will be disabled.
    desktop_directory_sharing: true
    # enterprise-only: when enabled, the source IP that was used to log in is embedded in the user
    # certificates, preventing a compromised certificate from being used on another
    # network. The default is false.
    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: login@github.com
       value: '{{ external.github_login }}'
    # Controls whether this role supports auto provisioning of SSH users.
    # Options: keep (keep users at session end), insecure-drop (remove user on session end),
    #          and off (disable host user creation)
    create_host_user_mode: keep
    # Controls whether this role requires automatic database user provisioning.
    # Options: off (disable database user auto-provisioning), keep (disables the
    # user at session end, removing the roles and locking it), and
    # best_effort_drop (try to drop the user at session end, if it doesn't
    # succeed, fallback to disabling it).
    create_db_user_mode: keep
    # 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 with labels matching 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 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$'
      'reg': '^us-west-1|eu-central-1$'

    # List of host groups the created user will be added to. Any that don't
    # already exist are created. Only applies when create_host_user_mode
    # is not 'off'.
    host_groups: [ubuntu, nginx, other]

    # List of entries to include in a temporary sudoers file created in
    # `/etc/sudoers.d`. The records are removed on session close.
    host_sudoers: [
      # This line will allow the login user to run `systemctl restart nginx.service`
      # as root without requiring a password. The sudoers entry will be prefixed
      # with the logged in username.
      "ALL = (root) NOPASSWD: /usr/bin/systemctl restart nginx.service"
    ]

    # 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 with labels matching 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 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$'

    # kubernetes_resources indicates the Kubernetes resources that a user with
    # this role is allowed to access.
    kubernetes_resources:
        # The resource kind. Teleport currently supports:
        # - * (all resources)
        # - pod
        # - secret
        # - configmap
        # - namespace
        # - service
        # - serviceaccount
        # - kube_node
        # - persistentvolume
        # - persistentvolumeclaim
        # - deployment
        # - replicaset
        # - statefulset
        # - daemonset
        # - clusterrole
        # - kube_role
        # - clusterrolebinding
        # - rolebinding
        # - cronjob
        # - job
        # - certificatesigningrequest
        # - ingress
      - kind: '*'
        # 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-]+$'
        # The verbs that the user is allowed to perform on the resource.
        # Teleport currently supports:
        # - * (all verbs)
        # - get
        # - list
        # - watch
        # - create
        # - update
        # - patch
        # - delete
        # - deletecollection
        # - exec - allows users to execute commands in a pod
        # - portforward - allows users to forward ports from a pod
        verbs: ['*']

    # Functions transform variables.
    db_users: ['{{email.local(external.email)}}']
    db_names: ['{{external.db_names}}']
    db_labels:
      'env': '{{regexp.replace(external.env, "^(staging)$", "$1")}}'

    # List of database roles to grant. Mutually exclusive with 'db_permissions'.
    db_roles: ['{{external.db_roles}}']

    # Grant all possible Postgres permissions for all tables.
    # List of database permissions to grant. Mutually exclusive with 'db_roles'.
    db_permissions:
    - match:
        object_kind: table
      permissions:
	    - SELECT
	    - INSERT
	    - UPDATE
	    - DELETE
	    - TRUNCATE
	    - REFERENCES
	    - TRIGGER

    # app_labels: a user with this role will be allowed to connect to
    # applications with labels matching 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$'

    # group_labels: a user with this role will be given permissions to the
    # underlying user_groups. Services such as the Okta service may use these
    # permissions to grant access to external services.
    group_labels:
      # A user is given group membership to production related groups.
      'env': 'prod'

    # cluster_labels: a user with this role will be allowed to connect to remote
    # clusters with labels matching below.
    cluster_labels:
      'env': 'prod'

    # node_labels_expression has the same purpose as node_labels but
    # supports predicate expressions to configure custom logic.
    # A user with this role will be allowed to access nodes if they are in the
    # staging environment *or* if they belong to one of the user's own teams.
    node_labels_expression: |
      labels["env"] == "staging" ||
      contains(user.spec.traits["teams"] , labels["team"])

    # The below <kind>_labels_expression fields have the same purpose of the
    # matching <kind>_labels fields, but support predicate expressions instead
    # of label matchers.
    app_labels_expression: 'labels["env"] == "staging"'
    cluster_labels_expression: 'labels["env"] == "staging"'
    kubernetes_labels_expression: 'labels["env"] == "staging"'
    db_labels_expression: 'labels["env"] == "staging"'
    db_service_labels_expression: 'labels["env"] == "staging"'
    windows_desktop_labels_expression: 'labels["env"] == "staging"'
    group_labels_expression: 'labels["env"] == "staging"'

    # 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

      # max_duration specifies the maximum duration for which a user can request
      # access to a role. The duration can be specified in seconds (s), minutes
      # (m), hours (h), or days (d), e.g. 4d, 10h, 30m, 60s.
      # The maximum duration is 14 days.
      max_duration: 7d

      # 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.
      #
      # This example leverages Teleport's regular expression support, which allows
      # for dynamic mapping from claims. The below mapping says that users with
      # claims that match 'projects: product-(.*)' can request roles that match
      # '$1-admin', where '$1' is the first capture group in the
      # regular expression.
      # Example: the 'projects: product-foo' claim allows a user to request the
      # 'foo-admin' role
      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', 'peer']

    # spiffe is a list of SPIFFE IDs that the role holder is allowed to request
    # SVIDs for. As long as the request matches one of the blocks within the
    # spiffe list, the certificate will be issued.
    spiffe:
        # The path of the SPIFFE ID that can be requested. This field is
        # required for each block. It must begin with a preceding slash and
        # should not contain a trailing slash.
      - path: "/svc/foo"
        # IP SANs that the user can request be included in a SVID along with the
        # SPIFFE ID in this block. This field is optional and if omitted,
        # the user will not be able to request a SVID with IP SANs.
        ip_sans: ["10.0.0.100/32"]
        # DNS SANs that the user can request be included in a SVID along with
        # the SPIFFE ID in this block. This field is optional and if omitted,
        # the user will not be able to request a SVID with DNS SANs.
        #
        # The '*' wildcard character is supported to indicated one or more of
        # any character. For example, '*.example.com' would match
        # 'foo.example.com'.
        dns_sans: ["foo.svc.example.com"]

    # 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
    # session_tracker    - an active session
    # ssh_session        - allows seeing active sessions page
    # instance           - a Teleport instance
    # 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: {}

Role options

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:

OptionDescriptionMulti-role behavior
max_session_ttlMax. time to live (TTL) of a user's SSH certificatesThe shortest TTL wins
forward_agentAllow SSH agent forwardingLogical "OR" i.e. if any role allows agent forwarding, it's allowed
port_forwardingAllow TCP port forwardingLogical "OR" i.e. if any role allows port forwarding, it's allowed
ssh_file_copyAllow SCP/SFTPLogical "AND" i.e. if all roles allows file copying, it's allowed
client_idle_timeoutForcefully terminate active sessions after an idle intervalThe shortest timeout value wins, i.e. the most restrictive value is selected
disconnect_expired_certForcefully terminate active sessions when a client certificate expiresLogical "OR" i.e. evaluates to "yes" if at least one role requires session termination
max_sessionsTotal number of session channels which can be established across a single SSH connection via TeleportThe lowest value takes precedence.
enhanced_recordingIndicates which events should be recorded by the BFP-based session recorder
permit_x11_forwardingAllow users to enable X11 forwarding with OpenSSH clients and servers
device_trust_modeEnforce authenticated device access for users assigned this role (required, optional, off). Applies only to the resources in the roles' allow field.
require_session_mfaEnforce per-session MFA or PIV-hardware key restrictions on user login sessions (no, yes, hardware_key, hardware_key_touch). Applies only to the resources in the roles' allow field.For per-session MFA, Logical "OR" i.e. evaluates to "yes" if at least one role requires session MFA
lockLocking mode (strict or best_effort)strict wins in case of conflict
request_accessEnterprise-only Access Request strategy (optional, always or reason)
request_promptPrompt for the Access Request "reason" field
max_connectionsEnterprise-only limit on how many concurrent sessions can be started via TeleportThe lowest value takes precedence.
max_kubernetes_connectionsDefines the maximum number of concurrent Kubernetes sessions per user
record_sessionDefines the Session recording mode.The strictest value takes precedence.
desktop_clipboardAllow clipboard sharing for desktop sessionsLogical "AND" i.e. evaluates to "yes" if all roles enable clipboard sharing
desktop_directory_sharingAllows sharing local workstation directory to remote desktopLogical "AND" i.e. evaluates to "yes" if all roles enable directory sharing
pin_source_ipEnable source IP pinning for SSH certificates.Logical "OR" i.e. evaluates to "yes" if at least one role requires session termination
cert_extensionsSpecifies extensions to be included in SSH certificates
create_host_user_modeAllow users to be automatically created on a hostLogical "AND" i.e. if all roles matching a server specify host user creation (off, keep, insecure-drop), it will evaluate to the option specified by all of the roles. If some roles specify both insecure-drop or keep it will evaluate to keep
create_db_user_modeAllow database user auto provisioning. Options: off (disable database user auto-provisioning), keep (disables the user at session end, removing the roles and locking it), and best_effort_drop (try to drop the user at session end, if it doesn't succeed, fallback to disabling it).Logical "OR" i.e. if any role allows database user auto-provisioning, it's allowed

Preset roles

Teleport provides several preset roles:

RoleDescriptionEnterprise-only
accessAllows access to cluster resources.
editorAllows editing of cluster configuration settings.
auditorAllows reading cluster events, audit logs, and playing back session records.
requesterAllows a user to create Access Requests.
reviewerAllows review of Access Requests.
group-accessAllows access to all user groups.
device-adminUsed to manage trusted devices.
device-enrollUsed to grant device enrollment powers to users.
require-trusted-deviceRequires trusted device access to resources.
terraform-providerAllows the Teleport Terraform provider to configure all of its supported Teleport resources.

Role versions

There are currently five supported role versions: v3, v4, v5, v6, and v7.

v4 and higher 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 with version v5 or higher are required to use Moderated Sessions.

Labelv3 Defaultv4 and higher Default
node_labels[{"*": "*"}] if the role has any logins, else [][]
app_labels[{"*": "*"}][]
kubernetes_labels[{"*": "*"}][]
db_labels[{"*": "*"}][]

Role v6 introduced a new field kubernetes_resources that allows fine-grained control over Kubernetes resources. See Kubernetes RBAC for more details.

Versionkubernetes_resources
v3, v4 and v5 Default[{"kind":"pod", "name":"*", "namespace":"*", "verbs": ["*"]}]
v6 Default[]
v7 Default[{"kind":"*", "name":"*", "namespace":"*", "verbs": ["*"]}]

RBAC for infrastructure resources

A Teleport role defines which resources (e.g., applications, servers, and databases) a user can access. This works by labeling resources and configuring 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']

Teleport handles multiple label entries with logical "AND" operations. As an example, this entry would match to databases that have the env: prod label and a region label of either us-west-1 or eu-central-1:

    db_labels:
      'env': 'prod'
      'region': ['us-west-1', 'eu-central-1']
Dynamic RBAC

Resource 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 label matching 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$'

Label expressions

Warning

Label expressions are available starting in Teleport version 13.1.1. All components of your Teleport cluster must be upgraded to version 13.1.1 or newer before you will be able to use label expressions. This includes the Auth Service and all Teleport agents.

Teleport roles also support matching resource labels with predicate expressions when you need to:

  • combine logic with OR and AND operators
  • perform matching on label keys
  • implement negative matches

The following example role would allow access to any nodes labeled env=staging or labeled team=<team>, where <team> is one of the values of the user's teams trait:

kind: role
version: v7
metadata:
  name: example-role
spec:
  allow:
    node_labels_expression: |
      labels["env"] == "staging" ||
      contains(user.spec.traits["teams"], labels["team"])

The <kind>_labels_expression fields have the same purpose of the matching <kind>_labels fields, but support predicate expressions instead of label matchers. They can be used in the following fields of role spec.allow and spec.deny conditions:

  • node_labels_expression
  • app_labels_expression
  • cluster_labels_expression
  • kubernetes_labels_expression
  • db_labels_expression
  • db_service_labels_expression
  • windows_desktop_labels_expression
  • group_labels_expression

Check out our predicate language guide for a more in depth explanation of the language.

Typically you will only want to use one of <kind>_labels or <kind>_labels_expression in a single role, but you are allowed to specify both. If you have both in a deny rule, the matching is greedy, if either one matches access will be denied. In an allow rule, the matching is not greedy, if both are set they both have to match for access to be allowed.

RBAC for dynamic 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).

A rule for modifying RBAC resources 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 active sessions. You can see all of the available resources and verbs under the allow section in the example role configuration below.

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]

Allowing access to token resources

If you configure a role that allows tokens to be created, users assigned to the role can create tokens to provision any type of Teleport resource. For example, you might create a role with the following configuration to enable assigned users to enroll servers:

kind: role
version: v7
metadata:
  name: enroll-servers
spec:
  allow:
    node_labels:
      'env': 'us-lab'
    rules:
      - resources: [token]
        verbs: [list, create, read, update, delete]
  deny: {}

With these permissions, users assigned to the role can generate tokens to enroll a server, application, or database, establish a trust relationship between a root cluster and a new Teleport Proxy Service, or add a new leaf cluster.

Because the token resource isn't scoped to a specific context, such as a node or trusted cluster, you should consider any role that provides token permissions to be an administrative role. In particular, you should avoid configuring allow rules that grant create and update permissions on token resources to prevent unexpected changes to the configuration or state of your cluster.

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.

Preset Auditor Role

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 session access to the user's sessions
    # and sessions they can join by default. This allows seeing any sessions.
    - resources: [session_tracker]
      verbs: ['*']
  deny:
    rules:
    # ... and then limit that access via a deny rule.
    # Deny rules take precedence over allow rules, so the resulting role
    # only allows user to see their own active sessions.
    - resources: [session_tracker]
      verbs: [list, read, update, delete]
      where: '!contains(session_tracker.participants, user.metadata.name)'

Role templates

In a Teleport role resource, certain fields allow you to use functions and variables to configure a user's access. The functions and variables available for a field depend on the access controls that the field configures.

Template expressions for access to infrastructure resources

When a user attempts to authenticate to an infrastructure resource proxied by Teleport, such as a database or Kubernetes cluster, Teleport determines from the user's roles:

  • Whether the user is authorized to connect to the resource.
  • Which principals the user can assume when they authenticate (for example, Linux server logins and Kubernetes groups).

Fields

The following role fields control a user's access to infrastructure resources. All of these are fields within the allow and deny sections of a Teleport role resource.

Labels for resources enrolled with Teleport:

Role FieldTeleport Resource
app_labelsApplications
cluster_labelsTrusted Clusters
db_labelsDatabases
db_service_labelsDatabase Service instances
kubernetes_labelsKubernetes clusters
node_labelsSSH Servers
windows_desktop_labelsWindows desktops

Principals a user can assume on infrastructure resources:

  • aws_role_arns
  • azure_identities
  • db_names
  • db_roles
  • db_users
  • desktop_groups
  • gcp_service_accounts
  • host_groups
  • host_sudoers
  • kubernetes_groups
  • kubernetes_users
  • logins
  • windows_desktop_logins

Teleport principals that a user can impersonate:

  • impersonate.rules
  • impersonate.users

Functions

You can use the following functions in role fields that govern access to principals on infrastructure resources:

FunctionDescription
{{email.local(variable)}}Extracts the local part of an email address.
{{regexp.replace(variable, expression, replacement)}}Finds all matches of the expression within the variable and replaces them with the replacement.

Traits

For fields that configure access to infrastructure resources, Teleport substitutes the following traits with data from the authenticating user, drawing from the local user database as well as the user's external single sign-on provider.

VariableDescription
{{internal.aws_role_arns}}List of allowed AWS role ARNS for the user.
{{internal.azure_identities}}Returns the Azure identities defined in Teleport available to the user. Azure identities can be set for a specific user or defined in a role.
{{internal.db_names}}List of all allowed database names for the user.
{{internal.db_roles}}List of all allowed database roles for the user.
{{internal.db_users}}List of all allowed database users for the user.
{{internal.gcp_service_accounts}}List of GCP service accounts for the user.
{{internal.jwt}}JWT header used for app access.
{{internal.kubernetes_groups}}List of allowed Kubernetes groups for the user.
{{internal.kubernetes_users}}List of allowed Kubernetes users for the user.
{{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 root cluster, then ubuntu will be substituted in the leaf cluster with this variable.
{{internal.windows_logins}}List of allowed Windows logins for the user.
{{external.xyz}}Substituted with a value from an external SSO provider. If using SAML, this will be expanded with "xyz" assertion value. For OIDC, the variable is expanded to the value of the "xyz" claim. See the next section for more information on referring to the external variable in Teleport roles.

Referring to internal traits in Teleport roles

The internal trait namespace includes only the exact internal trait names included in the above table. For local Teleport users, these traits can be set in the spec.traits field of the user resource. These trait names can also be set for SSO users if they are included in an attribute or claim from your IdP.

Internal traits are referenced in the preset roles access and require-trusted-device to allow access to resources based on user traits. External traits are never referenced in preset roles (unless you manually edit said preset roles).

You can use the following format in your role to reference an internal trait:

logins:
  - '{{internal.logins}}'
Warning

For backward compatibility, some internal traits will differ when expanded in a leaf cluster vs a root cluster. In a leaf cluster the logins, kubernetes_groups, kubernetes_users, db_names, db_users, and aws_role_arns traits will all be set to the complete set of values that are encoded into the user's certificate when they sign in to Teleport. For example, when accessing a leaf cluster, the internal.logins trait will be set to the complete list of SSH logins allowed for the user, which may include values from the user's internal.logins trait in the root cluster as well as logins only included in the spec.allow.logins field of roles the user holds in the root cluster.

Referring to external traits in Teleport roles

For local Teleport users, the external trait namespace includes all values from the spec.traits field of the user resource. This includes any custom trait names, as well as names matching the internal traits listed above. For example, {{internal.logins}} and {{external.logins}} are both valid ways to refer to the logins trait, but a custom trait called groups can only be referenced by {{external.groups}}.

When a user authenticates to Teleport through a single sign-on identity provider (IdP), Teleport populates external traits using attributes it receives from the IdP. For example, 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"]}}'

In role templates, you can refer to these variables using the following two formats, where trait is the name of the trait:

  • Dot syntax: {{external.trait}}
  • Bracket syntax: {{external["trait"]}}

Teleport expands the template variables above with the value of the SAML attribute or OIDC claim called trait.

You can specify an external trait in dot syntax if it begins with a letter and contains only letters, numbers, and underscores. Otherwise, you must use bracket syntax to specify a trait.

When using Azure AD or ADFS as your IdP, you must use bracket notation, as these IdPs assign attribute keys to URLs such as the following:

http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname

Common examples of external traits available through an identity provider include the following:

  • {{external.logins}}
  • {{external.username}}
  • {{external.env}}

Teleport can only expand an external variable to a string or a list of strings. If you are using an OIDC-based SSO solution, ensure that you have configured your identity provider to include claims with values that have a supported data type.

Refer to your identity provider's documentation for the complete list of available claims and attributes.

Access Request template functions

The following variables and functions allow more fine-grained control over a user's permissions to submit and review Access Requests.

Fields

You can use Access Request template functions in the following fields. You can include these fields within either allow rules or deny rules:

  • request.search_as_roles
  • request.roles
  • review_requests.preview_as_roles
  • review_requests.roles
  • review_requests.where

Functions

Access Requests support the following role template functions:

FunctionDescription
{{regexp.match(regexp)}}Returns true if the regular expression matches a user's role.
{{regexp.not_match(regexp)}}Returns true if the regular expression does not match a user's role.

Regular expressions support both glob-style wildcards (the * character) and Go-style regular expressions. If an expression begins with the ^ character and ends with the $ character, Teleport will evaluate it as a regular expression. Otherwise, it will evaluate it as a wildcard expression. Wildcards match any sequence of zero or more characters.

Variables

Teleport does not perform variable expansion on the values of the fields above.

Filter fields

Here is an explanation of the fields used in the where and filter conditions within this guide:

FieldDescription
user.spec.rolesThe list of roles assigned to a user
session.participantsThe list of participants from a session recording
session_tracker.participantsThe list of participants from the session
user.metadata.nameThe user's name

Read the predicate language guide for a more in depth explanation of the language.

Second Factor - U2F

Refer to the Second Factor - WebAuthn guide if you have a cluster using the legacy U2F support.