MFA for SFTP: TOTP setup walkthrough with the Web Portal

· ~4 minute read

A password gets you into the server. A TOTP code proves you still have the phone that set it up. That second factor is the difference between “credential leaked, account compromised” and “credential leaked, attacker stuck at the door.” This post walks through the whole setup: enabling MFA in the server config, enrolling a user through the Web File Portal, and what the login flow looks like from an SFTP client once it’s live.

Step 1: Enable MFA in the server configuration

MFA is off by default. Turning it on is one block in sftp-server.xml:

<mfa>
    <policy>optional</policy>
    <issuer>Stylus SFTP Server</issuer>
    <window-size>1</window-size>
    <recovery-codes>8</recovery-codes>
</mfa>

The <policy> element controls enforcement. Three values:

<issuer> sets the label that appears in your authenticator app (Google Authenticator, Authy, 1Password, etc.). The default is the product name. <window-size> controls clock-skew tolerance — a value of 1 means the server accepts codes from ±30 seconds of the current time step. <recovery-codes> is how many one-time backup codes are generated at enrollment, for when the phone is lost or broken.

This block is parsed at startup and hot-reloaded when the config file changes. No restart needed to flip from disabled to optional.

Step 2: Enroll through the Web File Portal

Once the policy is optional or required, users can self-enroll through the Web File Portal. The flow is four steps, all in the browser:

  1. Log in with your password. The Portal detects that MFA is enabled on the server and that you haven’t enrolled yet. It offers an enrollment link.
  2. Scan the QR code. The Portal generates a standard otpauth:// URI (RFC 6238) and renders it as a QR code. Point your authenticator app at it. The URI encodes the issuer name, your username, a 160-bit secret, and the algorithm parameters — HMAC-SHA1, 6-digit codes, 30-second time step.
  3. Save your recovery codes. The Portal shows eight one-time backup codes. Each is eight alphanumeric characters, drawn from a reduced alphabet that drops I, O, 0, and 1 to avoid visual ambiguity. Copy them somewhere safe. These codes are BCrypt-hashed in the database — the server never stores them in cleartext, and they can’t be retrieved after this screen.
  4. Confirm with a live code. Type the current 6-digit code from your authenticator app. The server verifies it against the secret it just generated. If it matches, enrollment is confirmed and MFA is active on your account from this moment forward.

The Portal also exposes an MFA status page where enrolled users can check their status or disable MFA (if the server policy allows it). Admins can force-enroll or force-reset any user through the Web Admin console, the Swing admin GUI, or the CLI.

Step 3: What SFTP login looks like with MFA

SFTP doesn’t have a web form. The second factor rides on SSH’s keyboard-interactive authentication method — the same mechanism SSH uses for PAM prompts, challenge-response tokens, and any multi-step login. The flow is two rounds:

  1. The client connects. The server sends a "Password:" prompt. The client sends the password.
  2. Password checks out. The server sees that this user has MFA enrolled. Instead of accepting, it sends a second prompt: "Verification code:". The client sends the 6-digit TOTP code (or a recovery code). The server verifies and either accepts or rejects.

Every mainstream SFTP client handles keyboard-interactive transparently — WinSCP, FileZilla, OpenSSH sftp, Cyberduck, and the Stylus SFTP Server Web Portal all present the prompts in sequence. No client-side configuration is needed. The user just sees two password boxes instead of one.

Public-key authentication bypasses MFA entirely. An SSH key is already a possession factor — requiring a TOTP code on top of it would add friction without adding meaningful security.

What happens in the audit trail

Every MFA event is recorded in the audit trail — whether that’s the log file, the JDBC audit table, a syslog server, or a webhook. Five distinct event types:

These events show up in the same audit pipeline as login attempts, file transfers, and admin actions. If you’re forwarding audit to a SIEM, they’re searchable by event type. If a recovery code is used, that’s a signal someone lost their phone — the kind of thing you want to notice before the remaining codes run out.

Choosing the right policy for your rollout

Start with optional. Let your power users enroll first. Monitor the audit trail for mfaEnrolled events to track adoption. Once coverage is where you want it, flip to required. Users who haven’t enrolled will be locked out — so give advance notice, and make sure your admins can force-enroll stragglers from the admin tools (CLI, Swing GUI, or Web Admin).

If you’re running LDAP or Active Directory authentication, MFA works the same way. The server creates a local database row for the user on first login, links the TOTP secret to it, and the second factor applies regardless of where the password was verified. One policy covers every auth provider.

Try MFA on your SFTP server

Free evaluation key. Install on Windows or Linux, enable MFA in one config block, and enroll through the Web Portal in under a minute.

Request Evaluation Key More articles ›