Skip to main content

Per-session MFA

Report an IssueView as Markdown
Video guide
Teleport - Multi-Factor SSH and Kubectl Authentication
Introducing Teleport's additional second-factor authentication.
Teleport - Multi-Factor SSH and Kubectl Authentication

Teleport supports requiring additional multi-factor authentication checks when starting new:

  • SSH connections (a single tsh ssh call, Web UI SSH session or Teleport Connect SSH session)
  • Kubernetes sessions (a single kubectl call or a single tsh proxy kube run)
  • Database sessions (a single tsh db connect call, a single tsh db exec call, or a single tsh proxy db --tunnel run)
  • Application sessions
  • Desktop sessions

This is an advanced security feature that protects human users against compromises of their on-disk Teleport certificates.

Per-session MFA checks can be satisfied by a webauthn device or by delegating MFA checks to your IdP.

note

In addition to per-session MFA, enable login MFA in your SSO provider and/or for all local Teleport users to improve security.

Prerequisites

  • A running Teleport cluster. If you want to get started with Teleport, sign up for a free trial or set up a demo environment.

  • The tctl and tsh clients.

    Installing tctl and tsh clients
    1. Determine the version of your Teleport cluster. The tctl and tsh clients must be at most one major version behind your Teleport cluster version. Send a GET request to the Proxy Service at /v1/webapi/find and use a JSON query tool to obtain your cluster version. Replace teleport.example.com:443 with the web address of your Teleport Proxy Service:

      TELEPORT_DOMAIN=teleport.example.com:443
      TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')"
    2. Follow the instructions for your platform to install tctl and tsh clients:

      Download the signed macOS .pkg installer for Teleport, which includes the tctl and tsh clients:

      curl -O https://cdn.teleport.dev/teleport-${TELEPORT_VERSION?}.pkg

      In Finder double-click the pkg file to begin installation.

      danger

      Using 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.

  • To check that you can connect to your Teleport cluster, sign in with tsh login, then verify that you can run tctl commands using your current credentials. For example, run the following command, assigning teleport.example.com to the domain name of the Teleport Proxy Service in your cluster and [email protected] to your Teleport username:
    tsh login --proxy=teleport.example.com --user=[email protected]
    tctl status

    Cluster teleport.example.com

    Version 18.7.3

    CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678

    If you can connect to the cluster and run the tctl status command, you can use your current credentials to run subsequent tctl commands from your workstation. If you host your own Teleport cluster, you can also run tctl commands on the computer that hosts the Teleport Auth Service for full permissions.
  • WebAuthn configured on this cluster
  • Hardware device for multi-factor authentication, such as YubiKey or SoloKey
  • A Web browser with WebAuthn support (if using SSH or desktop sessions from the Teleport Web UI).
Per-session MFA with FIPS

Teleport FIPS builds disable local users. To configure WebAuthn in order to use per-session MFA with FIPS builds, provide the following in your teleport.yaml:

teleport:
  auth_service:
    local_auth: false
    second_factors: ["webauthn"]
    webauthn:
      rp_id: teleport.example.com

Configure per-session MFA

Per-session MFA can be enforced cluster-wide or only for some specific roles.

Cluster-wide

To enforce MFA checks for all roles, edit your cluster authentication configuration.

Edit your cluster_auth_preference resource:

tctl edit cap

Ensure that the resource contains the following content:

kind: cluster_auth_preference
metadata:
  name: cluster-auth-preference
spec:
  require_session_mfa: true
version: v2

Apply your changes by saving and closing the file in your editor.

Per role

To enforce MFA checks for a specific role, update the role to contain:

kind: role
version: v7
metadata:
  name: example-role-with-mfa
spec:
  options:
    # require per-session MFA for this role
    require_session_mfa: true
  allow:
    ...
  deny:
    ...

Role-specific enforcement only applies when accessing resources matching a role's allow section.

Roles example

Let's walk through an example of setting up per-session MFA checks for roles.

Jerry is an engineer with access to the company infrastructure. The infrastructure is split into development and production environments. Security engineer Olga wants to enforce MFA checks for accessing production servers. Development servers don't require this to reduce engineers' friction.

Olga defines two Teleport roles: access-dev and access-prod:

# access-dev.yaml
kind: role
version: v7
metadata:
  name: access-dev
spec:
  allow:
    node_labels:
      env: dev
    logins:
      - jerry
---
# access-prod.yaml
kind: role
version: v7
metadata:
  name: access-prod
spec:
  options:
    # require per-session MFA for production access
    require_session_mfa: true
  allow:
    node_labels:
      env: prod
    logins:
      - jerry
  deny: {}

Olga then assigns both roles to all engineers, including Jerry.

When Jerry logs into node dev1.example.com (with label env: dev as login jerry), nothing special happens:

But when Jerry logs into node rod3.example.com (with label env: prod as login jerry), he gets prompted for an MFA check:

Tap any security key <tap>


[email protected] >

If per-session MFA was enabled cluster-wide, Jerry would be prompted for MFA even when logging into dev1.example.com.

Per-session MFA for Database Access

The Teleport Database Service supports per-connection MFA. When Jerry connects to the database prod-mysql-instance (with label env: prod), he gets prompted for an MFA check for each tsh db connect or tsh proxy db call:

tsh db connect prod-mysql-instance

Tap any security key


Welcome to the MySQL monitor. Commands end with ; or \g.

Your MySQL connection id is 10002

Server version: 8.0.0-Teleport (Ubuntu)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

If Jerry wants to avoid frequent MFA ceremonies, he can launch a local proxy tunnel using tsh proxy db --tunnel command. He will then only be required to perform MFA when establishing the tunnel.

tsh proxy db --tunnel prod-postgres-instance --db-user=my-prod-user --db-name=my-prod-db
Started authenticated tunnel for the PostgreSQL database "prod-postgres-instance" in cluster "example.com" on 127.0.0.1:65282.To avoid port randomization, you can choose the listening port using the --port flag.
Teleport Connect is a desktop app that can manage database proxies for you.Learn more at https://goteleport.com/docs/connect-your-client/teleport-connect/#connecting-to-a-database
Use the following command to connect to the database or to the address above using other database GUI/CLI clients: $ psql postgres://my-prod-user@localhost:65282/my-prod-dbMFA is required to access Database "prod-postgres-instance"Available MFA methods [WEBAUTHN, BROWSER]. Continuing with WEBAUTHN.If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,browser> or environment variable TELEPORT_MFA_MODE=<webauthn,browser>.
Tap any security key <tap>Detected security key tap

Notice that tsh proxy db prints the command that can now be used to connect to the database. Jerry can now connect to the database without using MFA on every connection:

psql postgres://my-prod-user@localhost:65282/my-prod-db
psql (17.5)Type "help" for help.
my-prod-db=#

Jerry can also execute a query against multiple databases with a single MFA check using the tsh db exec command:

tsh db exec "select 1" --labels env=prod --db-user teleport-user --output-dir=logs
Searching databases ...Found 2 database(s):
Name Description Protocol Labels--------------------- ----------- -------- --------prod-mysql-instance-1 mysql env=prodprod-mysql-instance-2 mysql env=prod
Do you want to proceed with 2 database(s)? [y/N]: yExecuting command for "prod-mysql-instance-1". Output will be saved at "logs/prod-mysql-instance-1.output".MFA is required to access Database "prod-mysql-instance-1"Tap any security keyDetected security key tapExecuting command for "prod-mysql-instance-2". Output will be saved at "logs/prod-mysql-instance-2.output".
Summary: 2 of 2 succeeded.Summary is saved at "logs/summary.json".

Note that each MFA check remains valid for up to 5 minutes. After the 5-minutes window, a new MFA check will be requested for new connections.

Per-session MFA for Kubernetes Access

When per-session MFA is required, each kubectl command Jerry will execute will require confirmation using an MFA device.

tsh kube login prod-kube-cluster
Logged into Kubernetes cluster "prod-kube-cluster". Try 'kubectl version' to test the connection.
kubectl version
MFA is required to access Kubernetes cluster "prod-kube-cluster"Available MFA methods [WEBAUTHN, BROWSER]. Continuing with WEBAUTHN.If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,browser> or environment variable TELEPORT_MFA_MODE=<webauthn,browser>.
Tap any security key <tap>Detected security key tapClient Version: v1.34.1Kustomize Version: v5.7.1Server Version: v1.35.0

If confirming every single command becomes tedious, Jerry can start a local proxy. That eliminates the need to confirm every single command; instead, MFA confirmation is required by the proxy itself.

tsh proxy kube --exec
Preparing the following Teleport Kubernetes clusters from the default kubeconfig:Teleport Cluster Name Kube Cluster Name Context Name--------------------- ----------------- -----------------------------example.com prod-kube-cluster example.com-prod-kube-cluster
MFA is required to access Kubernetes cluster "prod-kube-cluster"Available MFA methods [WEBAUTHN, BROWSER]. Continuing with WEBAUTHN.If you wish to perform MFA with another method, specify with flag --mfa-mode=<webauthn,browser> or environment variable TELEPORT_MFA_MODE=<webauthn,browser>.
Tap any security key <tap>Detected security key tapStarted local proxy for Kubernetes Access in the background.
Warning! Teleport will initiate a new shell configured with kubectl for local proxy access.To conclude the session, simply use the "exit" command. Upon exiting, your original shell will be restored,the local proxy will be closed, and future access through this headless session won't be possible.

Try issuing a command, for example "kubectl version".

The tsh proxy kube --exec command performs the MFA ceremony and opens up a shell configured to access the given cluster using kubectl. Jerry can now execute this command without additional MFA:

kubectl version
Client Version: v1.34.1Kustomize Version: v5.7.1Server Version: v1.35.0

The kubectl call uses an already authenticated connection offered by the local proxy.

Limitations

Current limitations for this feature are:

  • VNet SSH must be used for per-session MFA when using an OpenSSH client (ssh, scp).
  • Only kubectl supports per-session WebAuthn authentication for Kubernetes.
  • When accessing a multi-port TCP application through VNet, the first connection over each port triggers an MFA check.
  • For the tsh db exec command, only WebAuthn devices are supported.

Next steps