AI Implements 2FA with SMS and Nothing Else
AI generates 2FA with: SMS as the only second factor (vulnerable to SIM-swapping, SS7 attacks, and delivery delays), no rate limiting on code attempts (brute-force 6-digit code in 1 million attempts), no recovery mechanism (user loses their phone — permanently locked out), enrollment as a mandatory wall (forced 2FA on next login with no preparation or explanation), and codes that never expire (a code sent 24 hours ago still works). Each of these patterns makes 2FA either insecure or user-hostile.
Modern 2FA is: TOTP-primary (authenticator apps like Google Authenticator, Authy, 1Password — offline, no SIM dependency), WebAuthn-available (passkeys for phishing-resistant authentication), recovery-equipped (8-10 hashed recovery codes generated at enrollment), enrollment-friendly (guided setup with QR code, verification step, and recovery codes shown once), and enforcement-graduated (encourage first, require for admin accounts, enforce org-wide with notice period). AI generates none of these.
These rules cover: TOTP authenticator setup, WebAuthn passkeys, recovery code management, enrollment UX flow, enforcement policies, and backup method handling.
Rule 1: TOTP with Authenticator Apps
The rule: 'Use TOTP (Time-based One-Time Password, RFC 6238) as the primary 2FA method. Generate a secret: const secret = speakeasy.generateSecret({ name: "RuleSync (user@email.com)" }). Display as QR code: the user scans with their authenticator app. Verify: speakeasy.totp.verify({ secret: secret.base32, token: userCode, window: 1 }). The window: 1 parameter allows 30 seconds of clock drift (current period plus one before and after). Store the secret encrypted in the database — it is equivalent to a password.'
For why not SMS: 'SMS 2FA vulnerabilities: SIM-swapping (attacker convinces carrier to transfer the number — receives all SMS codes), SS7 network attacks (intercept SMS in transit — demonstrated by security researchers), delivery delays (SMS takes 30-60 seconds in some regions — code may expire), and no offline support (no cell signal = no code). TOTP: works offline (generated on the device), no carrier dependency, no interception vector, and codes refresh every 30 seconds. SMS is acceptable as a fallback — never as the primary method.'
AI generates: send a random 6-digit code via SMS, verify the code. The code is valid for 10 minutes (too long — allows interception), there is no rate limiting on attempts (brute-force is trivial), and losing the phone number means losing account access. TOTP: 30-second code rotation, offline generation, rate-limited verification (5 attempts then lockout), and recovery codes as backup. Same user experience, fundamentally different security.
- TOTP (RFC 6238): authenticator app generates codes offline, 30-second rotation
- speakeasy or otplib for Node.js: generateSecret, verify with window: 1 for clock drift
- QR code enrollment: user scans with Google Authenticator, Authy, or 1Password
- Store secret encrypted in database: equivalent to a password, protect accordingly
- SMS as fallback only: SIM-swapping, SS7, and delivery delays make it unreliable as primary
SMS: depends on carrier, interceptable via SIM-swap or SS7, delays in some regions. TOTP: generated offline on the device, 30-second rotation, no network dependency, no interception vector. Same 6-digit code UX, fundamentally different security properties.
Rule 2: WebAuthn Passkeys for Phishing Resistance
The rule: 'Offer WebAuthn/passkeys as the strongest 2FA option. WebAuthn: the browser authenticates using a hardware key (YubiKey), biometric (fingerprint, Face ID), or device credential (platform authenticator). Phishing-resistant: the authentication is bound to the origin (rulesync.com) — a phishing site on ruIesync.com (with a capital I) cannot trigger the credential. Libraries: @simplewebauthn/server + @simplewebauthn/browser handle the entire WebAuthn ceremony.'
For the registration flow: '(1) Server generates registration options: generateRegistrationOptions({ rpName: "RuleSync", rpID: "rulesync.com", userID: user.id }). (2) Browser calls navigator.credentials.create() with the options — user touches fingerprint reader or security key. (3) Browser returns the credential. (4) Server verifies and stores the credential public key. On login: server generates authentication options, browser calls navigator.credentials.get(), user authenticates with the same method, server verifies. Zero codes to type, zero phishing risk.'
AI generates: no WebAuthn support. Users who have YubiKeys or prefer passkeys are forced to use TOTP or SMS. WebAuthn: the user touches their fingerprint reader instead of typing a 6-digit code. Faster (1 second vs 10 seconds), more secure (phishing-proof), and more convenient (no app switching). Offer WebAuthn alongside TOTP — let security-conscious users choose the strongest option.
Rule 3: Hashed Recovery Codes
The rule: 'Generate 8-10 recovery codes at 2FA enrollment. Each code: 8-character alphanumeric string (e.g., AXKF-M29D). Hash each code with bcrypt before storing (they are single-use passwords). Display the codes once during enrollment: "Save these codes in a safe place. Each code can be used once if you lose access to your authenticator." On use: compare the entered code against stored hashes, mark the matched code as used (delete the hash). When fewer than 3 codes remain: prompt the user to regenerate.'
For the backup flow: 'User loses their phone (authenticator app gone). Login: enter email + password, prompted for 2FA code. Click "Use recovery code" link. Enter one of the 8 saved codes. Code is verified against stored hashes, marked as used. User is logged in and immediately prompted to set up a new authenticator (the old one is gone with the phone). Recovery codes bridge the gap between losing a device and setting up a new one — without this bridge, the user is permanently locked out.'
AI generates: no recovery mechanism. User loses their phone: locked out permanently. Customer support ticket: "I cannot access my account." Support options: (1) disable 2FA manually (requires identity verification, days of back-and-forth), or (2) user creates a new account (loses all data). Recovery codes: the user self-recovers in 30 seconds with a pre-saved code. Zero support tickets, zero data loss, zero lockouts.
- 8-10 recovery codes: 8-char alphanumeric, generated at enrollment
- Hash with bcrypt: recovery codes are single-use passwords, protect accordingly
- Display once: 'Save these codes in a safe place' with download/copy option
- Single-use: mark as used after successful verification, cannot reuse
- Regenerate prompt when fewer than 3 remain: user always has backup access
No recovery codes: user loses phone, authenticator is gone, permanently locked out. Support ticket takes days. Recovery codes: user enters a pre-saved 8-character code, logs in immediately, sets up new authenticator. 30-second self-recovery vs days of support.
Rule 4: Smooth Enrollment UX
The rule: 'The 2FA enrollment flow: (1) explain the benefit: "Add an extra layer of security to your account. Even if someone learns your password, they cannot access your account without your authenticator." (2) Show QR code + manual entry key (for users who cannot scan). (3) Require verification: user enters a code from the authenticator to confirm it is set up correctly before enabling 2FA. (4) Display recovery codes with a download button and copy button. (5) Require the user to confirm they saved the recovery codes: "I have saved my recovery codes" checkbox. (6) 2FA is now active.'
For the verification step: 'Never enable 2FA without verifying the user can produce a valid code. If the user scans the QR code incorrectly (wrong account, typo in manual key), 2FA is enabled with an authenticator that produces wrong codes. The user is immediately locked out. Verification: after scanning, the user enters the current code. If it matches: 2FA is enabled. If it does not match: show an error, let the user try again or rescan. This single step prevents the most common 2FA setup failure.'
AI generates: scan QR code, 2FA enabled immediately. No verification (user may have scanned wrong), no recovery codes (user loses phone, permanently locked out), no explanation (user does not understand why they should enable it). The enrollment flow is: explain, verify, recover. Skip any step and the user either does not enable 2FA (no explanation), gets locked out immediately (no verification), or gets locked out eventually (no recovery codes).
Rule 5: Graduated 2FA Enforcement Policies
The rule: 'Enforce 2FA gradually, not as a sudden wall. Phase 1 (encourage): show a banner on the dashboard: "Protect your account with two-factor authentication" with a setup button. Phase 2 (require for privileged accounts): admin and owner roles must enable 2FA within 14 days or lose access to admin features. Phase 3 (organization-wide): org admins can require 2FA for all members with a 30-day grace period and setup instructions. At every phase: provide clear instructions, support documentation, and a grace period.'
For the grace period: 'When 2FA is enforced org-wide: send an email: "Your organization requires 2FA. You have 30 days to set it up." Show an in-app countdown: "2FA required in 23 days." At 7 days: more prominent warning. At 1 day: blocking modal with setup flow. After deadline: redirect to 2FA setup on every login (cannot use the app until enrolled). The grace period respects that people travel, take vacations, and do not read every email immediately. Sudden enforcement without notice locks out traveling employees.'
AI generates: organization admin flips a switch, 2FA is required immediately for all 500 employees. 200 employees are currently logged in and working. 50 employees are traveling. On next login: forced 2FA setup with no preparation, no authenticator app installed, no recovery codes. Result: 50 support tickets from confused employees, 10 locked-out travelers, and frustrated IT staff. Graduated enforcement with 30-day grace period: zero emergency tickets, 100% enrollment, zero lockouts.
Sudden 2FA enforcement for 500 employees: 50 confused tickets, 10 locked-out travelers, frustrated IT. Graduated enforcement with 30-day grace period + email + in-app countdown: 100% enrollment, zero lockouts, zero emergency tickets.
Complete Two-Factor Authentication Rules Template
Consolidated rules for two-factor authentication.
- TOTP authenticator as primary: offline, no SIM dependency, 30-second rotation
- WebAuthn passkeys: phishing-resistant, origin-bound, fingerprint or security key
- SMS as fallback only: SIM-swapping and SS7 make it unreliable as primary
- Recovery codes: 8-10 hashed, single-use, displayed once, regenerate when low
- Enrollment flow: explain → QR scan → verify code → show recovery → confirm saved
- Verify before enabling: user must produce valid code to prevent lockout from misconfig
- Graduated enforcement: encourage → require admins → org-wide with 30-day grace
- Rate limit code attempts: 5 tries then lockout — prevent brute-force of 6-digit codes