# Per-session MFA

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)
- Database sessions (a single `tsh db connect` call)
- 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](https://goteleport.com/docs/zero-trust-access/sso/sso-for-mfa.md).

---

NOTE

In addition to per-session MFA, enable login MFA in your SSO provider and/or for all [local Teleport users](https://goteleport.com/docs/reference/access-controls/authentication.md) to improve security.

---

## Prerequisites

- A running Teleport cluster. If you want to get started with Teleport, [sign up](https://goteleport.com/signup) for a free trial or [set up a demo environment](https://goteleport.com/docs/get-started/deploy-community.md).

- 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:

     **Mac**

     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.

     ---

     **Windows - Powershell**

     ```
     $ curl.exe -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-windows-amd64-bin.zip
     Unzip the archive and move the `tctl` and `tsh` clients to your %PATH%
     NOTE: Do not place the `tctl` and `tsh` clients in the System32 directory, as this can cause issues when using WinSCP.
     Use %SystemRoot% (C:\Windows) or %USERPROFILE% (C:\Users\<username>) instead.
     ```

     **Linux**

     All of the Teleport binaries in Linux installations include the `tctl` and `tsh` clients. For more options (including RPM/DEB packages and downloads for i386/ARM/ARM64) see our [installation page](https://goteleport.com/docs/installation.md).

     ```
     $ curl -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ tar -xzf teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ cd teleport
     $ sudo ./install
     Teleport binaries have been copied to /usr/local/bin
     ```

* 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\@example.com to your Teleport username:
  ```
  $ tsh login --proxy=teleport.example.com --user=email@example.com
  $ 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](https://goteleport.com/docs/zero-trust-access/management/security/idp-compromise.md) on this cluster
* Hardware device for multi-factor authentication, such as YubiKey or SoloKey
* A Web browser with [WebAuthn support](https://developers.yubico.com/WebAuthn/WebAuthn_Browser_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:

```
$ tsh ssh jerry@dev1.example.com

jerry@dev1.example.com >
```

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

```
$ tsh ssh jerry@prod3.example.com
Tap any security key <tap>

jerry@prod3.example.com >
```

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>
```

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=prod
prod-mysql-instance-2             mysql    env=prod

Do you want to proceed with 2 database(s)? [y/N]: y
Executing 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 key
Detected security key tap
Executing 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.

---

## 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](https://goteleport.com/docs/enroll-resources/application-access/protect-apps/tcp.md#configuring-access-to-multiple-ports) TCP application through [VNet](https://goteleport.com/docs/connect-your-client/teleport-clients/vnet.md), the first connection over each port triggers an MFA check.
- For the `tsh db exec` command, only WebAuthn devices are supported.

## Next steps

- [Require MFA for administrative actions](https://goteleport.com/docs/zero-trust-access/authentication/mfa-for-admin-actions.md)
