Fork me on GitHub

Dual Authorization

Teleport Access Requests

Teleport Access Requests

Length: 01:17

Dual Authorization

You can set up Teleport to require require the approval of multiple team members to perform some critical actions. Here are the most common scenarios:

  • Improve security of your system and prevent one successful phishing attack from compromizing your system.
  • Satisfy FedRamp AC-3 Dual authorization control that requires approval of two authorized individuals.

Let's set up Teleport's access requests to require approval of two team members for a privileged role dbadmin.

Version Warning

This guide requires a commercial edition of Teleport. The open source edition of Teleport only supports Github as an SSO provider.


The steps below describe how to use Teleport with Mattermost. You can also integrate with many other providers.


Running Mattermost locally with Docker
docker run --name mattermost-preview -d --publish 8065:8065 --add-host dockerhost: mattermost/mattermost-preview

Verify that your Teleport client is connected:

$ tctl status

# Cluster
# Version  8.0.7
# CA pin   sha256:sha-hash-here

To try this flow in the cloud, login into your cluster using tsh, then use tctl remotely:

$ tsh login
$ tctl status

Set up Teleport bot

Enable bot account creation in "System Console -> Integrations".

Toggle Enable Bot Account Creation.

Enable bots

Go back to your team settings, navigate to "Integrations -> Bot Accounts". Press "Add Bot Account".

Enable bots

Add the "Post All" permission on the new account.

Enable bots

Create the bot and save the access token.

Create a non-interactive bot access-plugin user and role.

kind: user
  name: access-plugin
  roles: ['access-plugin']
version: v2
kind: role
version: v4
  name: access-plugin
      - resources: ['access_request']
        verbs: ['list', 'read']
      - resources: ['access_plugin_data']
        verbs: ['update']
    # teleport currently refuses to issue certs for a user with 0 logins,
    # this restriction may be lifted in future versions.
    logins: ['access-plugin-not-used']
Creating resources

Here and below follow along and create yaml resources using tctl create -f:

tctl create -f access.yaml

Export access-plugin cert

Teleport Plugin uses the access-plugin role and user to perform the approval. We export the identify files, using tctl auth sign.

tctl auth sign --format=tls --user=access-plugin --out=auth --ttl=720h

Teleport will generate auth.crt, auth.key, and auth.cas - a certificate, a private key, and a set of CA certs respectively.

Install the plugin

curl -L
tar -xzf teleport-access-mattermost-v8.0.7-linux-amd64-bin.tar.gz
cd teleport-access-mattermost

To install from source you need git and go >= 1.17 installed.

Checkout teleport-plugins

git clone
cd teleport-plugins/access/mattermost
teleport-mattermost configure > /etc/teleport-mattermost.toml

Update the config with Teleport address, Mattermost URL, and a bot token.

# example mattermost configuration TOML file
auth_server = ""                             # Teleport Auth Server GRPC API address
client_key = "/var/lib/teleport/plugins/mattermost/auth.key" # Teleport GRPC client secret key
client_crt = "/var/lib/teleport/plugins/mattermost/auth.crt" # Teleport GRPC client certificate
root_cas = "/var/lib/teleport/plugins/mattermost/auth.cas"   # Teleport cluster CA certs

url = "" # Mattermost Server URL
team = "team-name"                     # Mattermsot team in which the channel resides.
channel = "channel-name"               # Mattermost Channel name to post requests to
token = "api-token"                    # Mattermost Bot OAuth token
secret = "signing-secret-value"        # Mattermost API signing Secret

public_addr = "" # URL on which callback server is accessible externally, e.g. [https://]
# listen_addr = ":8081" # Network address in format [addr]:port on which callback server listens, e.g.
https_key_file = "/var/lib/teleport/plugins/mattermost/server.key"  # TLS private key
https_cert_file = "/var/lib/teleport/plugins/mattermost/server.crt" # TLS certificate

output = "stderr" # Logger output. Could be "stdout", "stderr" or "/var/lib/teleport/mattermost.log"
severity = "INFO" # Logger severity. Could be "INFO", "ERROR", "DEBUG" or "WARN".

Dual authorization

Alice and Ivan are reviewers - they can approve requests for assuming role dbadmin. Bob is a devops and can assume dbadmin role if two members of the reviewer role approved the request.

Create dbadmin, reviewer and devops roles:

kind: role
version: v4
  name: reviewer
      roles: ['dbadmin']
kind: role
version: v4
  name: devops
      roles: ['dbadmin']
        - approve: 2
          deny: 1
kind: role
version: v4
  name: dbadmin
    logins: ['root']
      'env': 'prod'
      'type': 'db'

Example below creates local users Alice, Ivan and Bob.

Bob does not have a role dbadmin assigned to him, but can create an access request for it.

tctl users add [email protected] --roles=devops
tctl users add [email protected] --roles=reviewer
tctl users add [email protected] --roles=reviewer

Access Requests flow

Bob can create an access request for the dbadmin role in the Web UI or CLI:


Bob has to set valid emails of Alice and Ivan matching in Mattermost.

tsh request create --roles=dbadmin [email protected],[email protected]

Chatbot will notify both Alice and Ivan:


Alice and Ivan can review and approve request using Web UI or CLI:


tsh request list

ID User Roles Created (UTC) Status

------------------------------------ --------------- ------- ------------------- -------

9c721e54-b049-4ef8-a7f6-c777aa066764 [email protected] dbadmin 03 Apr 21 03:58 UTC PENDING

tsh request review --approve --reason="hello" 9c721e54-b049-4ef8-a7f6-c777aa066764

Successfully submitted review. Request state: APPROVED

If Bob has created a request using CLI, he will assume it once it has been approved. Bob can also assume granted access request roles using Web UI:

Teleport Assume


Cert errors

You may be getting certificate errors if Teleport's auth server is missing an address in the server certificate:

authentication handshake failed: x509: cannot validate certificate for because it doesn't contain any IP SANs
x509: certificate is valid for,*.teleport.cluster.local, teleport.cluster.local, not

To fix the problem, update the auth service with a public address, and restart Teleport:

  public_addr: ['localhost:3025', '']
Have a suggestion or can’t find something?