
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 guide.
- WebAuthn hardware device, such as YubiKey.
- A Web browser with WebAuthn 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
:
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:
tctl create -f cap.yamlcluster 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
:
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:
tctl create -f cap.yamlcluster 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.
tsh ls --headless --proxy=proxy.example.com --user=aliceComplete 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 <command>
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:
tsh ls --headless --proxy=proxy.example.com --user=aliceComplete 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 server01Complete 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
Troubleshooting
"WARN: Failed to lock system memory for headless login: ..."
When using Headless WebAuthn, tsh
does not write private key and certificate data
to disk(~/.tsh
). Instead, tsh
holds these secrets in memory for the duration of
the request. Additionally, it will try to lock the process memory to further protect
the secrets from being stolen by other users on a shared machine.
Below are some of the specific warning messages you may run into and how to fix them:
"operation not permitted" OR "cannot allocate memory"
In order to lock the process memory, your OS user must have permission to lock
the amount of memory needed. Use ulimit -l
to check your OS user's current limit.
The exact amount of memory needed may vary from system to system, so we recommend
updating your ulimit to unlimited, with either ulimit -l unlimited
or by adding
the line <os_username> hard memlock unlimited
to your /etc/security/limits.conf
.
"memory locking is not supported on non-linux operating systems"
The mlockall
syscall is only supported on Linux operating systems. This means
that on other operating systems, the memory lock attempt will always fail and
output the warning. We recommend only using Headless WebAuthn on Linux machines
for the best level of security on shared machines.
Disable mlock
If the above solutions are not feasible in your environment, you can also disable
the memory locking requirement by setting the --mlock
flag or TELEPORT_MLOCK_MODE
environment variable to off
or best_effort
. This is not recommended in production
environments on shared systems where a memory swap attack is possible.