diff --git a/docs/config.json b/docs/config.json
index 206f22d3e8f85..6430d558fb379 100644
--- a/docs/config.json
+++ b/docs/config.json
@@ -263,6 +263,10 @@
"slug": "/access-controls/guides/device-trust/",
"forScopes": ["enterprise", "cloud"]
},
+ {
+ "title": "Headless WebAuthn (Preview)",
+ "slug": "/access-controls/guides/headless/"
+ },
{
"title": "IP Pinning (Preview)",
"slug": "/access-controls/guides/ip-pinning/",
diff --git a/docs/pages/access-controls/guides/headless.mdx b/docs/pages/access-controls/guides/headless.mdx
new file mode 100644
index 0000000000000..56d71d14f1c87
--- /dev/null
+++ b/docs/pages/access-controls/guides/headless.mdx
@@ -0,0 +1,154 @@
+---
+title: Headless WebAuthn (Preview)
+description: Headless WebAuthn
+---
+
+
+ Headless WebAuthn is currently in Preview mode.
+
+
+Headless WebAuthn provides a secure way to authenticate with WebAuthn from a
+machine without access to a WebAuthn device. This enables the use of WebAuthn
+features which are usually not usable in WebAuthn-incompatible environments.
+For example:
+
+- Logging into Teleport with WebAuthn from a remote dev box
+- Connecting to a Teleport SSH Service from a remote dev box with per-session MFA
+- Performing `tsh scp` from one Teleport SSH Service to another with per-session MFA
+- Logging into Teleport on a machine without a WebAuthn-compatible browser
+
+
+ Headless WebAuthn only supports the following `tsh` commands:
+
+ - `tsh ls`
+ - `tsh ssh`
+ - `tsh scp`
+
+ In the future, Headless WebAuthn will be extended to other `tsh` commands.
+
+
+## Prerequisites
+
+- A v12.2+ Teleport cluster with WebAuthn configured.
+ See the [Second Factor: WebAuthn](./webauthn.mdx) guide.
+- WebAuthn hardware device, such as YubiKey.
+- A Web browser with [WebAuthn support](
+ https://developers.yubico.com/WebAuthn/WebAuthn_Browser_Support/).
+
+
+## Step 1/3. Configuration
+
+A v12.2+ Teleport cluster capable of WebAuthn is automatically capable of
+Headless WebAuthn without any additional configuration.
+
+
+
+To make Headless WebAuthn the default authentication method for your Teleport
+Cluster, add `connector_name: headless` to your cluster 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_factor: "on"
+ webauthn:
+ rp_id: example.com
+ connector_name: headless # headless by default
+```
+
+Update the configuration:
+
+```code
+$ tctl create -f cap.yaml
+# cluster auth preference has been updated
+```
+
+
+
+
+Headless WebAuthn is enabled automatically when WebAuthn is configured. If you
+want to forbid Headless WebAuthn in your cluster, add `headless: 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_factor: "on"
+ webauthn:
+ rp_id: example.com
+ headless: false # disable Headless WebAuthn
+```
+
+Update the configuration:
+
+```code
+$ tctl create -f cap.yaml
+# cluster auth preference has been updated
+```
+
+
+
+## Step 2/3. Initiate Headless WebAuthn
+
+Run a headless `tsh` command with the `--headless` flag. This will initiate
+headless authentication, printing a URL and `tsh` command.
+
+```code
+$ tsh ls --headless --proxy=proxy.example.com --user=alice
+# Complete headless authentication in your local web browser:
+#
+# https://proxy.example.com:3080/web/headless/86172f78-af7c-5935-a7c1-ed06b94f17dc
+#
+# or execute this command in your local terminal:
+#
+# tsh headless approve --user=alice --proxy=proxy.example.com 86172f78-af7c-5935-a7c1-ed06b94f17dc
+```
+
+## Step 3/3. Approve Headless WebAuthn
+
+To approve the headless authentication, click or copy+paste the URL printed by
+`tsh` in your local web browser. You will be prompted to approve the log in with
+WebAuthn verification. Once approved, your initial `tsh --headless `
+should continue as if you had logged in locally.
+
+Unlike a standard login session, headless sessions are only available for the
+lifetime of a single `tsh` request. This means that for each `tsh --headless`
+command, you will need to go through the Headless WebAuthn flow:
+
+```code
+$ tsh ls --headless --proxy=proxy.example.com --user=alice
+# Complete headless authentication in your local web browser:
+#
+# https://proxy.example.com:3080/web/headless/86172f78-af7c-5935-a7c1-ed06b94f17dc
+#
+# or execute this command in your local terminal:
+#
+# tsh headless approve --user=alice --proxy=proxy.example.com 86172f78-af7c-5935-a7c1-ed06b94f17dc
+# # User approves through link
+# Node Name Address Labels
+# --------- -------------- -----------
+# server01 127.0.0.1:3022 arch=x86_64
+#
+$ tsh ssh --headless --proxy=proxy.example.com --user=alice server01
+# Complete headless authentication in your local web browser:
+#
+# https://proxy.example.com:3080/web/headless/864cccd9-2425-46d9-a9f2-636387e66ebf
+#
+# or execute this command in your local terminal:
+#
+# tsh headless approve --user=alice --proxy=proxy.example.com 864cccd9-2425-46d9-a9f2-636387e66ebf
+# # User approves through link
+```
\ No newline at end of file
diff --git a/docs/pages/includes/access-control-guides.mdx b/docs/pages/includes/access-control-guides.mdx
index 80efb8b52fcfc..01c1439da73e0 100644
--- a/docs/pages/includes/access-control-guides.mdx
+++ b/docs/pages/includes/access-control-guides.mdx
@@ -8,4 +8,5 @@
- [Moderated Sessions](../access-controls/guides/moderated-sessions.mdx): Require session auditors and allow fine-grained live session access.
- [Hardware Key Support (Preview)](../access-controls/guides/hardware-key-support.mdx): Enforce the use of hardware-based private keys.
- [Device Trust (Preview)](../access-controls/guides/device-trust.mdx): Register and enforce trusted devices.
-- [IP Pinning (Preview)](../access-controls/guides/ip-pinning.mdx): Pin a user's certificates to a login IP address.
\ No newline at end of file
+- [Headless WebAuthn (Preview)](../access-controls/guides/headless.mdx): Login with Webauthn from a remote device.
+- [IP Pinning (Preview)](../access-controls/guides/ip-pinning.mdx): Pin a user's certificates to a login IP address.
diff --git a/docs/pages/includes/config-reference/auth-service.yaml b/docs/pages/includes/config-reference/auth-service.yaml
index e557c81b2527a..d47ebc0551989 100644
--- a/docs/pages/includes/config-reference/auth-service.yaml
+++ b/docs/pages/includes/config-reference/auth-service.yaml
@@ -141,16 +141,23 @@ auth_service:
# - 'otp' and 'webauthn' require the corresponding second factor.
second_factor: otp
- # Sets whether passwordless authorization is allowed.
+ # Sets whether passwordless authentication is allowed.
# Passwordless requires WebAuthn.
# Defaults to "true".
#passwordless: true
- # Sets the authenticator connector for SSO (Enterprise) or the default
- # connector for "local" authentication.
- # See SSO for Enterprise (https://goteleport.com/docs/enterprise/sso/).
- # See Passwordless for local
- # (http://goteleport.com/docs/access-controls/guides/passwordless/#optional-enable-passwordless-by-default).
+ # Sets whether headless authentication is allowed.
+ # Headless authentication requires WebAuthn.
+ # Defaults to "true".
+ #headless: true
+
+ # Sets the default authentication connector for the cluster:
+ # - 'local' for local authentication (password, WebAuthn, etc.)
+ # - 'passwordless' for passwordless authentication
+ # (http://goteleport.com/docs/access-controls/guides/passwordless/#optional-enable-passwordless-by-default)
+ # - 'headless' for headless authentication
+ # (http://goteleport.com/docs/access-controls/guides/headless-login/#optional-enable-passwordless-by-default)
+ # - A specific SSO connector name - see https://goteleport.com/docs/access-controls/sso/ for details.
# Defaults to "local".
#connector_name: local
diff --git a/docs/pages/reference/cli.mdx b/docs/pages/reference/cli.mdx
index 7afabe71c29c7..441594ae7e115 100644
--- a/docs/pages/reference/cli.mdx
+++ b/docs/pages/reference/cli.mdx
@@ -147,6 +147,7 @@ information about the cluster.
| `--skip-version-check` | none | none | Skip version checking between server and client. |
| `-d, --debug` | none | none | Verbose logging to stdout |
| `-J, --jumphost` | none | A jump host | SSH jumphost |
+| `--headless` | none | none | Use Headless WebAuthn for authentication |
### tsh help
@@ -1270,6 +1271,7 @@ Environment variables configure your tsh client and can help you avoid using fla
| TELEPORT_ADD_KEYS_TO_AGENT | Specifies if the user certificate should be stored on the running SSH agent | yes, no, auto, only |
| TELEPORT_USE_LOCAL_SSH_AGENT | Disable or enable local SSH agent integration | true, false |
| TELEPORT_GLOBAL_TSH_CONFIG | Override location of global `tsh` config file from default `/etc/tsh.yaml` | /opt/teleport/tsh.yaml |
+| TELEPORT_HEADLESS | Use headless authentication | true, false, 1, 0 |
### tsh configuration files