Multi-Factor Authentication
MFA adds a time-based one-time code to signing in to the console.
Set the recovery email first
The profile carries a recovery email, separate from the address you sign in with, and enabling MFA fails without it: the request is refused before the code you typed is even checked, so an empty recovery email looks like a wrong code unless you know to look. It is also half of the reset path — a reset sends one code to your sign-in address and another to the recovery one, and needs both — and it cannot be set from a locked-out account, which is the moment you would think of it.
Enabling it
From Account › Security.
Scan the QR code with an authenticator app:
Then confirm with a code from the app. From then on, sign-in asks for one:
Recovery codes
Setup produces a set of recovery codes. Save them somewhere that is not the phone holding the authenticator.
Each is single use, and they are the way back in when the authenticator is lost. Lose both and recovery becomes a support matter.
What MFA covers
Console sign-in. That is its scope.
It does not gate SSH connections. An SSH connection is authorized by access policies against an SSH identity, and MFA is not part of that path.
If you want a second, deliberate step in front of connections rather than sign-in, that is
require_reauth on a policy — see Login Approvals. The
two are complementary: MFA protects the account, re-auth protects a connection.
MFA and API keys
Every MFA endpoint refuses API keys. It is a human-only flow by construction — an API key holder has no browser and no authenticator, and allowing one to manipulate MFA state would undermine the point.
An automation that needs to reach devices should connect as an API key, which never has MFA because it never signs in. See SSH Access.
Account lockout
Wrong passwords and wrong MFA codes each lock an account out for a while. The third failure
starts a lockout. Attempts sent during it are refused without being checked and do not count. A
failure shortly after a lockout ends makes the next one four times longer. The first lasts
SHELLHUB_ACCOUNT_LOCKOUT_BASE, so by default they run 1, 4, 16 and then 60 minutes, the cap set
by SHELLHUB_MAXIMUM_ACCOUNT_LOCKOUT. After a lockout at the cap the count
starts over. Setting SHELLHUB_MAXIMUM_ACCOUNT_LOCKOUT to 0 disables both lockouts.
Password lockout is keyed on the account and the client address, resolved through
SHELLHUB_PROXY_TRUSTED_IPS. A self-hosted deployment behind a load balancer without that set
correctly will lock out on the balancer’s address, so a lockout on an account applies to everyone
signing in to it, wherever they are. See
Ports and Connectivity.
MFA lockout has its own counter, keyed on the account alone, whatever the address. Wrong codes from every sign-in add to it, and a correct password does not reset it. Someone who knows your password can therefore keep you out of the MFA step by sending wrong codes. A recovery code still signs you in during the MFA lockout, and clears it. Change your password once you are in, so nobody can start a new sign-in with the old one.
A sign-in already past the password step can still send wrong codes for 30 minutes after it started. The last of those can start one more lockout, so with the default cap the MFA lockout can last up to about 90 minutes after the password change.
Where to go next
- Single Sign-On (SAML) — Delegating sign-in to your IdP.
- Login Approvals — A second factor on connections.