From 5bddb36c653ca4abc16597250acd58a8dd0f5a2c Mon Sep 17 00:00:00 2001
From: Dan Share <10600907+danielashare@users.noreply.github.com>
Date: Mon, 20 Apr 2026 12:47:27 +0100
Subject: [PATCH] [Browser MFA] Add documentation (#65176)
* [Browser MFA] Add documentation
* Address comments
* Add browser to env vars
* Address feedback
* feedback
* Address comments
---
.../teleport-clients/tsh.mdx | 15 ++
docs/pages/reference/cli/tctl.mdx | 2 +
docs/pages/reference/cli/tsh.mdx | 4 +-
.../authentication/browser-mfa.mdx | 140 ++++++++++++++++++
4 files changed, 159 insertions(+), 2 deletions(-)
create mode 100644 docs/pages/zero-trust-access/authentication/browser-mfa.mdx
diff --git a/docs/pages/connect-your-client/teleport-clients/tsh.mdx b/docs/pages/connect-your-client/teleport-clients/tsh.mdx
index cd8b2487a20..824bc79a23a 100644
--- a/docs/pages/connect-your-client/teleport-clients/tsh.mdx
+++ b/docs/pages/connect-your-client/teleport-clients/tsh.mdx
@@ -354,6 +354,21 @@ a browser of your choice to continue the login flow.
[CLI Docs - tsh login](../../reference/cli/tsh.mdx#tsh-login)
+### MFA mode
+
+When a command requires MFA, `tsh` uses the `--mfa-mode` flag to determine how
+to complete the MFA check. If omitted, it defaults to `auto`, which tries each
+method in order until one succeeds:
+
+1. WebAuthn (with TOTP if available)
+1. SSO
+1. Browser MFA
+1. TOTP
+
+[Browser MFA](../../zero-trust-access/authentication/browser-mfa.mdx) allows
+users whose only registered MFA device is browser-based (e.g. a passkey or
+Touch ID) to complete MFA checks from the CLI by opening a browser window.
+
### Inspecting an SSH certificate
To inspect the SSH certificates in `~/.tsh`, a user may execute the following
diff --git a/docs/pages/reference/cli/tctl.mdx b/docs/pages/reference/cli/tctl.mdx
index 47e8034cf2c..96fb019519c 100644
--- a/docs/pages/reference/cli/tctl.mdx
+++ b/docs/pages/reference/cli/tctl.mdx
@@ -35,6 +35,7 @@ Global flags:
|`-d`, `--[no-]debug`|`false`|Enable verbose logging to stderr|
|`-i`, `--identity`|none|Path to an identity file. Must be provided to make remote connections to auth. An identity file can be exported with 'tctl auth sign'|
|`--[no-]insecure`|`false`|When specifying a proxy address in --auth-server, do not verify its TLS certificate. Danger: any data you send can be intercepted or modified by an attacker.|
+|`--mfa-mode`|`auto`|Preferred mode for MFA assertions (auto, cross-platform, platform, sso, browser).|
Global environment variables:
@@ -42,6 +43,7 @@ Global environment variables:
|---|---|---|
|`TELEPORT_AUTH_SERVER`|none|Attempts to connect to specific auth/proxy address(es) instead of local auth [127.0.0.1:3025]|
|`TELEPORT_IDENTITY_FILE`|none|Path to an identity file. Must be provided to make remote connections to auth. An identity file can be exported with 'tctl auth sign'|
+|`TELEPORT_MFA_MODE`|`auto`|Preferred mode for MFA assertions (auto, cross-platform, platform, sso, browser).|
## tctl acl get
diff --git a/docs/pages/reference/cli/tsh.mdx b/docs/pages/reference/cli/tsh.mdx
index c64a22bb74e..5e81ebce05c 100644
--- a/docs/pages/reference/cli/tsh.mdx
+++ b/docs/pages/reference/cli/tsh.mdx
@@ -34,7 +34,7 @@ Global flags:
|`-J`, `--jumphost`|none|SSH jumphost.|
|`-k`, `--add-keys-to-agent`|`auto`|Controls how keys are handled. Valid values are \[auto no yes only\].|
|`-l`, `--login`|none|Remote host login.|
-|`--mfa-mode`|`auto`|Preferred mode for MFA and Passwordless assertions (auto, cross-platform, platform, otp, sso).|
+|`--mfa-mode`|`auto`|Preferred mode for MFA and Passwordless assertions (auto, cross-platform, platform, otp, sso, browser).|
|`--mlock`|`auto`|Determines whether process memory will be locked and whether failure to do so will be accepted (off, auto, best_effort, strict).|
|`--[no-]enable-escape-sequences`|`true`|Enable support for SSH escape sequences. Type '~?' during an SSH session to list supported sequences. Default is enabled.|
|`--[no-]headless`|`false`|Use headless login. Shorthand for --auth=headless.|
@@ -60,7 +60,7 @@ Global environment variables:
|`TELEPORT_IDENTITY_FILE`|none|Identity file.|
|`TELEPORT_LOGIN`|none|Remote host login.|
|`TELEPORT_LOGIN_BIND_ADDR`|none|Override host:port used when opening a browser for cluster logins.|
-|`TELEPORT_MFA_MODE`|`auto`|Preferred mode for MFA and Passwordless assertions (auto, cross-platform, platform, otp, sso).|
+|`TELEPORT_MFA_MODE`|`auto`|Preferred mode for MFA and Passwordless assertions (auto, cross-platform, platform, otp, sso, browser).|
|`TELEPORT_MLOCK_MODE`|`auto`|Determines whether process memory will be locked and whether failure to do so will be accepted (off, auto, best_effort, strict).|
|`TELEPORT_PIV_SLOT`|none|Specify a PIV slot key to use for Hardware Key support instead of the default. Ex: "9d".|
|`TELEPORT_PROXY`|none|Teleport proxy address.|
diff --git a/docs/pages/zero-trust-access/authentication/browser-mfa.mdx b/docs/pages/zero-trust-access/authentication/browser-mfa.mdx
new file mode 100644
index 00000000000..03276315b10
--- /dev/null
+++ b/docs/pages/zero-trust-access/authentication/browser-mfa.mdx
@@ -0,0 +1,140 @@
+---
+title: Browser MFA
+description: Complete MFA checks in the browser when using tsh, tctl, or Teleport Connect
+tags:
+ - how-to
+ - zero-trust
+ - privileged-access
+---
+
+Browser MFA enables users of `tsh`, `tctl`, and Teleport Connect to complete
+MFA checks in the browser using a WebAuthn device. This is particularly useful
+when a user's only registered MFA device is browser-based (e.g. a passkey or
+Touch ID), which would otherwise prevent them from authenticating via the CLI
+entirely.
+
+Example usage:
+```code
+# Login to a cluster
+$ tsh login --proxy example.teleport.sh --user alice --mfa-mode=browser
+
+# SSH in to a node
+$ tsh ssh --mfa-mode=browser alice@node
+
+# Add a new MFA device
+$ tsh mfa add --mfa-mode=browser
+
+# Edit a Teleport resource
+$ tctl edit --mfa-mode=browser cluster_auth_preference
+```
+
+## How it works
+
+In the Browser MFA flow, a user runs a command requiring MFA but only has a
+browser-based WebAuthn device (such as a passkey or Touch ID) registered. The CLI
+tool requests an MFA challenge from Teleport, then opens the user's browser to
+`/web/mfa/browser/[request_id]` where they are prompted to complete the
+challenge. The browser performs the WebAuthn verification, and the response is
+encrypted with a secret key generated by the CLI tool. The encrypted response is
+then forwarded to a local callback server run by the CLI tool, which decrypts it
+and uses it to complete the original command.
+
+## Prerequisites
+
+- A Teleport Cloud cloud or a self-hosted cluster with WebAuthn configured.
+
+
+Enable WebAuthn
+
+To enable WebAuthn support, create a `cap.yaml` file or get the existing
+configuration using `tctl get cluster_auth_preference`:
+
+```yaml
+kind: cluster_auth_preference
+version: v2
+metadata:
+ name: cluster-auth-preference
+spec:
+ type: local
+ second_factors: ["webauthn"]
+ webauthn:
+ rp_id: example.teleport.sh
+```
+
+Update the configuration:
+
+```code
+$ tctl create -f cap.yaml
+# cluster auth preference has been updated
+```
+
+
+
+- A machine with the `tsh` binary installed and a Web browser with [WebAuthn support](
+ https://developers.yubico.com/WebAuthn/WebAuthn_Browser_Support/).
+
+ (!docs/pages/includes/install-tsh.mdx!)
+
+## Step 1/2. Configuration
+
+A Teleport cluster with WebAuthn configured is automatically capable of Browser
+MFA without any additional configuration.
+
+
+Alternative: disable Browser MFA
+
+If you want to forbid Browser MFA in your cluster, add
+`allow_cli_auth_via_browser: false` to your configuration.
+
+Create a `cap.yaml` file or get the existing configuration using
+`tctl get cluster_auth_preference`:
+
+```yaml
+kind: cluster_auth_preference
+version: v2
+metadata:
+ name: cluster-auth-preference
+spec:
+ type: local
+ second_factors: ["webauthn"]
+ webauthn:
+ rp_id: example.teleport.sh
+ allow_cli_auth_via_browser: false # disable Browser MFA
+```
+
+Update the configuration:
+
+```code
+$ tctl create -f cap.yaml
+# cluster auth preference has been updated
+```
+
+
+
+## Step 2/2. Authenticate via the browser
+
+Run a command that requires MFA, for example, logging in to a cluster using `tsh`.
+
+```code
+$ tsh login --proxy example.teleport.sh --user alice --mfa-mode=browser
+# Enter password for Teleport user alice:
+# If browser window does not open automatically, open it by clicking on the link:
+# http://127.0.0.1:51697/d658314e-68f0-4ad4-be79-0181e6e0dae5
+```
+
+A Web browser window should automatically open, if not, click or copy+paste the
+URL printed by `tsh`. You will be prompted to complete the MFA verification
+process in the browser. Once successfully verified, the originating command will
+be authenticated and allowed to proceed.
+
+The `--mfa-mode` flag is optional. If omitted, it defaults to `auto`, which
+tries each authentication mode in order until one succeeds:
+1. WebAuthn (with TOTP if available)
+1. SSO
+1. Browser MFA
+1. TOTP
+
+Browser MFA is not attempted automatically on Windows because Windows natively
+supports platform WebAuthn authenticators (such as Windows Hello) in CLI
+applications. To use Browser MFA on Windows, pass `--mfa-mode=browser`
+explicitly.