Fork me on GitHub
Teleport

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.
Note
The steps below describe how to use Teleport with Mattermost. You can also integrate with many other providers.

Prerequisites

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

Verify that your Teleport client is connected:

$ tctl status

# Cluster  tele.example.com
# Version  7.1.3
# CA pin   sha256:sha-hash-here
Connecting to the cloud

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

$ tsh login --proxy=myinstance.teleport.sh
$ 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
metadata:
  name: access-plugin
spec:
  roles: ['access-plugin']
version: v2
---
kind: role
version: v4
metadata:
  name: access-plugin
spec:
  allow:
    rules:
      - 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 https://get.gravitational.com/teleport-access-mattermost-v7.1.3-linux-amd64-bin.tar.gz
tar -xzf teleport-access-mattermost-v7.1.3-linux-amd64-bin.tar.gz
cd teleport-access-mattermost
./install
teleport-mattermost configure > /etc/teleport-mattermost.toml

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

# example mattermost configuration TOML file
[teleport]
auth_server = "example.com:3025"                             # 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

[mattermost]
url = "https://mattermost.example.com" # 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

[http]
public_addr = "example.com" # URL on which callback server is accessible externally, e.g. [https://]teleport-mattermost.example.com
# listen_addr = ":8081" # Network address in format [addr]:port on which callback server listens, e.g. 0.0.0.0:443
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

[log]
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
metadata:
  name: reviewer
spec:
  allow:
    review_requests:
      roles: ['dbadmin']
---
kind: role
version: v4
metadata:
  name: devops
spec:
  allow:
    request:
      roles: ['dbadmin']
      thresholds:
        - approve: 2
          deny: 1
---
kind: role
version: v4
metadata:
  name: dbadmin
spec:
  allow:
    logins: ['root']
    node_labels:
      '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:

Mattermost-Request

Chatbot will notify both Alice and Ivan:

Mattermost-Request

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

Teleport-Approve

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

Troubleshooting

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 127.0.0.1 because it doesn't contain any IP SANs
x509: certificate is valid for,*.teleport.cluster.local, teleport.cluster.local, not example.com

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

auth_service:
  public_addr: ['localhost:3025', 'example.com:3025']
Have a suggestion or can’t find something?
IMPROVE THE DOCS