My working list for a builder app starts with 6 provider dashboards: registrar, host, database, payments, email and code repository. To implement two factor authentication, enforce a second factor on each one and the app’s admin login, then try signing in without it. One leaked password on a dashboard account is a full takeover of the product and its data.
What it means to implement two factor authentication for owner and admin accounts
Implementing two-factor authentication for owner and admin accounts means enforcing a second factor, not offering one, on two kinds of login: the app’s own admin sign-in and every provider dashboard behind the product. Enforced means the account cannot sign in without it; enabled only means someone could turn it on.
The definition of an authentication factor in NIST SP 800-63B names three types: something you know, something you have and something you are; MFA is sign-in that requires more than one distinct type. Multi-factor sign-in on owner accounts is one line of the authentication checklist for an AI-built app, and this page takes that line apart. In my reading, “2FA”, “MFA” and “2-step verification” name the same control here, so how you implement two-factor authentication does not change with the name a provider gives it; OWASP’s cheat sheet also treats MFA and 2FA as one term. Google shortens 2-step verification to 2SV, so 2SV has the same meaning in authentication: this same control. And since 2FA is simply MFA with exactly 2 factors, neither name is the better choice: the two-factor authentication best practices below hold whatever a dashboard calls its setting.
Of the multi-factor authentication best practices OWASP’s cheat sheet gives as quick recommendations, the one this page starts from is “Require MFA for administrative or other high privileged users.” How you implement 2FA, and how you enforce it for admin accounts, depends on the surface: in the app it is your own code, and on a dashboard it is a setting the provider owns. The table lists every surface where MFA can be enabled and needs to be enforced.
| Surface | Who signs in | What “enforced” means there | Where the setting is documented |
|---|---|---|---|
| The app’s own admin login | you, plus any staff with an admin role | admin pages and the admin API refuse a session that has not passed the second factor | your own code: the TOTP steps below |
| Registrar | the account holder and anyone given access | every sign-in to the account asks for the second factor | dashboards table: Namecheap, Porkbun |
| Host | every team member | the team setting blocks any member without 2FA | dashboards table: Vercel, Cloudflare |
| Database service | every organization member | no access to the organization without an MFA-backed session | dashboards table: Supabase |
| Payment provider | everyone on the account | each member enrolls; a team-wide rule comes through single sign-on | dashboards table: Stripe |
| Email provider | every login with admin rights | every sign-in asks for the second factor | not in the dashboards table: read the provider’s own 2FA page |
| Code repository | organization members, outside collaborators and billing managers | the organization setting blocks or removes anyone without 2FA | dashboards table: GitHub |
| Cloud account, where one exists | the root user and admins | MFA on the root user | dashboards table: AWS |
| Team workspace (Google Workspace or Microsoft 365) | every staff account | 2-Step Verification enforced for the organization | dashboards table: Google Workspace |
The table lists accounts to protect, not who owns them. Which accounts have to be in your name is its own question, and moving them into your name is a separate job. For a small team, my working rule is that the two-factor authentication rollout checklist and the MFA enforcement policy are one document: this table plus the vault rule in the dashboards section, written down and dated.
In the Production Hardening Sprint, deliverable 1.11 is this control: enforce a second factor on every owner and admin account, in the application and on every provider dashboard behind it, with recovery codes stored in the owner’s vault.
For context from my own audits, the Authentication pillar averages 52.8 out of 100 across the 14 third-party apps scored on it. Those 14 are among the 11 public and 10 held-out third-party apps I audited in June and July 2026: a selected set of audited apps, not a random sample and not a rate for AI-built apps in general.
What goes wrong without it: why MFA is important for owner accounts
MFA matters for owner accounts because a password is one secret, and a leaked or reused one is enough to sign in. A second factor means the password alone is no longer enough. CISA calls any form of MFA better than none and phishing-resistant MFA the gold standard.
Once an admin password has leaked, a dashboard sign-in is a full account takeover: the product and its data, as the opener says. Nothing in the app’s code sees that sign-in happen, because it happens on the provider’s site, not in your app. Multi-factor authentication (MFA) is designed to close exactly that gap: in the words of CISA’s fact sheet on phishing-resistant MFA, if one factor such as a password is compromised, unauthorized users “will be unable to access the account if they cannot also provide the second factor.” That is how multi-factor authentication helps protect you against authentication attacks that start from a stolen password, and the same fact sheet adds that any form of MFA “will reduce an organization’s attack surface.”
The FTC’s case against Drizly shows the shape of the failure. According to the FTC’s press release on Drizly, dated October 24, 2022 and citing its complaint, in 2018 a Drizly employee posted company cloud computing account login information on GitHub. Then, the release says: “Two years later, a hacker breached an employee account, got access to Drizly’s corporate GitHub login information, hacked into the company’s database, and then stole customers’ information.” Among the failures the complaint alleges, Drizly “did not require employees to use two-factor authentication for GitHub”. The proposed order requires, among other measures, that employees use multi-factor authentication to access databases and other assets containing consumer data. All of this is the FTC’s allegation, and the release does not say how the employee account was breached or that the missing requirement caused it. The lesson I take from it is that 2FA available on a code-hosting account is not 2FA required: the setting that matters is the one that stops every member signing in without it.
In my reading, multi-factor authentication improves security most on accounts like these, where one login reaches everything. It does not make a leaked password harmless: a password known to a stranger still needs changing with 2FA on, because the second factor is then the only thing left. The next question is what gets past that second factor.
2FA bypass and 2FA hacks: what a second factor stops and what beats it
2FA bypass increasingly means attacking how MFA is deployed, not defeating MFA itself. OWASP lists the patterns: push prompts sent until someone approves, reverse-proxy pages that relay the sign-in and capture the session, SIM swaps that take the SMS, extracted device keys, and downgrades to a weaker factor. Phishing-resistant keys and passkeys resist the proxy.
OWASP’s MFA cheat sheet puts the trend in one sentence: “Attackers increasingly target weaknesses in MFA deployments and authentication workflows rather than attempting to defeat MFA itself.” The table lists the MFA attacks it names, in its order, each with one or two of the mitigations it gives; the last column is mine.
| Attack pattern (OWASP’s name) | What it does | A mitigation OWASP names | Where this page handles it |
|---|---|---|---|
| MFA fatigue (push notification bombing) | repeated push prompts, often with social engineering, until the user approves one | challenge-response push, such as number matching; rate-limit or cap push notifications | the out-of-band line in the TOTP section |
| Real-time phishing using reverse proxies | a copy of the login page relays traffic and captures credentials and session tokens in real time | phishing-resistant authenticators that bind authentication to the legitimate origin | the passkey and security key sections |
| SIM swap and phone number takeover | the carrier is talked into moving the number, so SMS or voice codes are intercepted | prefer phishing-resistant authenticators or TOTP instead of SMS or voice codes | the no-SMS rule in the TOTP section |
| Device binding bypass | exportable keys are extracted, or cloned device attributes replayed, where the authenticator is not hardware-protected | hardware-backed, non-exportable keys | the security key section |
| MFA downgrade attacks | a weak fallback or legacy endpoint can let the user sign in with a lower-assurance factor | prevent fallback from phishing-resistant authenticators to lower-assurance methods unless a documented security policy requires it | the recovery-code rule and the verify checks |
None of these is a bypass of the two-factor authentication math itself, and the same holds for any 2-step verification hack: each one attacks the prompt, the phone number, the key or the fallback around it. Whether 2-step verification is safe depends on the method: CISA’s Table 1 rates app-based codes and push with number matching as “Vulnerable to phishing attacks” and “Resistant to push bombing”, with SS7 and SIM swap attacks not applicable, and rates FIDO/WebAuthn as “Resistant to phishing.” In my reading, codes stop the common attack, a password bought or guessed, and not the targeted one, a live fake login page; that is why the owner account gets a key.
A session captured after sign-in is a session problem, a matter of JWT security and session revocation, and guessing the code itself is a job for brute force login protection and rate limits.
How to do it in the app and on every dashboard
Two-factor for a small SaaS is three jobs: TOTP with recovery codes on the app’s admin login, the organization-level enforce setting on each provider dashboard, and a passkey or hardware key on the owner account, with every recovery code kept in the owner’s password-manager vault.
Every step below comes from the standards and each provider’s own documentation, read on September 27, 2026, not from signing in to your accounts. Where a provider documents a way to require MFA on dashboard logins for a whole team, the dashboards table names it.
In the app: TOTP with recovery codes, and what the best authentication app is
TOTP is a one-time code computed from a shared secret and the current time step: 30 seconds is RFC 6238’s recommended default step, 6 digits the otpauth key format’s default length. The server generates the secret, shows it as an otpauth QR code, requires a valid code before enforcing, stores the secret encrypted and issues single-use recovery codes.
That is what time-based authentication means in practice: RFC 6238 extends the HOTP algorithm “to support the time-based moving factor”, so the server and the app each compute the code from the same secret and the current time. A software OATH token is the same thing held in an app; the RFC’s reference code calls itself “an example implementation of the OATH TOTP algorithm.”
- 01 Generate a random secret for each user on the server
- 02 Show the secret as a key URI in a QR code, and as text the user can type in
- 03 Require one valid code before switching the account to enforced
- 04 Store the secret encrypted at rest
- 05 Issue single-use recovery codes and store only their hashes
- 06 Apply strict attempt limits on code entry
- 07 Ask for the second factor again before anyone disables MFA or changes the account email
- 08 Never write a code value to a log
The eight steps are my list, and each one that states a standard takes it from its source. Step 1 follows RFC 6238’s unique, randomly generated key per user, and step 4 is my way of meeting its rule that keys “SHOULD be protected against unauthorized access and usage.” Step 2 uses the otpauth://TYPE/LABEL?PARAMETERS format that Google Authenticator’s Key Uri Format wiki documents. Steps 5 to 8 draw on OWASP’s cheat sheet, with storing only hashes my own addition: single-use recovery codes are among its reset suggestions, “Apply strict attempt limits” is on its SHOULD list, disabling MFA and changing the email are sensitive actions for which “it may also be appropriate to require MFA”, and “Log OTP values” is on its SHOULD NOT list. The limits in step 6 belong to the brute-force protection page named above. Step 3 is how to verify the authenticator app was set up: the user proves the app produces valid codes before the account depends on it. I’d hold any admin login to those TOTP authentication best practices.
On Node, the npm route is otplib, an OTP generator that describes itself as a “TypeScript-first library for HOTP and TOTP” and states compliance with RFC 6238 and RFC 4226. Where the app already uses a managed auth provider, its built-in MFA comes first. Supabase Auth’s MFA guide documents an enroll, challenge and verify flow and two assurance levels: aal1 after a conventional sign-in such as email and password, aal2 after at least one second factor; its TOTP page says the TOTP MFA API “is free to use and is enabled on all Supabase projects by default.” For any other managed auth service, read its MFA docs before writing your own.
Two conditions come with the Supabase route. A password-only session sits at aal1, and MFA is enforced only by your own rules requiring aal2 “on the frontend, backend, API servers or Row-Level Security policies.” Recovery codes are not stated in Supabase’s MFA docs, so on that route step 5 is your own code, or the owner enrolls a second factor; the docs say the phone and app authenticator flows can be combined.
Keep SMS off the admin login. OWASP’s warning reads “Do not use SMS for high-value or PII-handling applications”, NIST SP 800-63B-4 treats codes sent over the phone network (SMS or voice) as a restricted authenticator, and CISA’s fact sheet says SMS or voice MFA “should only be used as a last resort MFA option.” One out-of-band authentication example NIST gives is a smartphone with an app the verifier can reach on its own, over what NIST calls a secondary channel, and for push prompts to such an app CISA points to number matching, where the user enters numbers from the sign-in screen into the app.
The best authentication app for an owner account, by my working rule, is any TOTP app that keeps an encrypted backup the owner controls. I don’t rank them. For 2-step sign-in UX, the one rule I’d keep from OWASP’s reset suggestions is “multiple types”: two-factor authentication best practice is to let a user register a second method before the first one is lost.
On every provider dashboard: enabled is not enforced
Provider dashboards separate enabled from enforced: enabled lets each member turn 2FA on, enforced blocks any member who has not. GitHub, Vercel, Supabase, Cloudflare and Google Workspace each document an organization or team setting that enforces it (Supabase’s on its Pro, Team and Enterprise plans); where a provider documents none, each person turns it on for their own login.
| Provider | What the docs call the setting | Who can switch it on | Where it is documented |
|---|---|---|---|
| GitHub (organization) | “Require two-factor authentication for everyone in your organization”, under Authentication security; an extra “Only allow secure two-factor methods” option | organization owners, who must have 2FA on their own account first; available on GitHub Free and Team as well as Enterprise Cloud and Enterprise Server | GitHub’s organization 2FA requirement |
| Vercel (team) | Two-Factor Authentication Enforcement, under Team Settings, Security & Privacy | not stated in Vercel’s docs; whoever enables it must have 2FA on their own account first | Vercel’s two-factor enforcement |
| Supabase (organization) | Require MFA to access organization; Pro, Team and Enterprise plans only | organization owners only, with MFA on their own account | Supabase’s organization MFA enforcement |
| Stripe | no team-wide 2FA switch described; the Dashboard supports passkeys, hardware security keys, TOTP and SMS, and Stripe recommends passkeys or hardware keys; SAML 2.0 single sign-on lets you “mandate sign-in requirements” | not stated in Stripe’s docs | Stripe’s security documentation |
| Cloudflare (account) | 2FA Enforcement | Super Administrators | Cloudflare’s 2FA Enforcement |
| Google Workspace | 2-Step Verification enforcement, under Security, Authentication, 2-step verification in the Admin console | a super administrator | Google Workspace’s 2-Step Verification rollout |
| AWS | MFA on the root user, which AWS requires for every account type | the root user | AWS’s root user best practices |
| Registrar (Namecheap, Porkbun) | per-account 2FA: Namecheap offers a U2F device or a TOTP app, Porkbun app-based 2FA or a physical security key (WebAuthn), with one-time backup codes; a team-wide requirement is not stated in either registrar’s docs | the account holder | Namecheap’s and Porkbun’s help articles |
Read the side effects before you switch it on. On GitHub, members and billing managers without 2FA lose access to the organization’s resources but keep their membership, while outside collaborators without it, bots and service accounts included, are removed from the organization. The requirement lives on an organization, so in my reading a repository under a personal account has no such switch, and the owner’s own 2FA is the only control there. On Vercel, CI/CD pipeline tokens tied to members without 2FA “will cease to work”, and builds fail for those members. On Supabase, members without MFA “immediately lose access” to the organization’s resources but stay members, and personal access tokens are not affected. AWS says root users must register MFA within 35 days of their first console sign-in attempt if it is not already on. Google Workspace calls its organization-wide 2-Step Verification policy “enforcement”, and a super administrator can start it at once or from a date. Netlify’s team 2FA options are covered in is Netlify safe, so they are not repeated here, and Microsoft 365 is left out of the table because none of this page’s sources covers its setting.
The shared login comes first. One owner login used by several people cannot be enforced per person, so my working rule is named accounts first, then enforcement. Another working rule of mine puts recovery codes for every dashboard in the owner’s password-manager vault, shared with one other named person, and never in the repository, a chat thread or a notes app. Cloudflare’s own page recommends at least two different 2FA factors and safely stored backup codes to prevent lockouts.
To check multi-factor authentication on a dashboard, read the organization setting and, where the provider shows one, each member’s 2FA status: GitHub documents a view of whether members use 2FA, and Vercel shows each member’s status on the team members page.
Biometrics and passkeys: the pros and cons of biometric authentication for an owner account
Biometric authentication on an owner account belongs in one place: the unlock step of a passkey. The fingerprint or face is usually checked on the device itself, and the passkey, bound to the real site, does the signing in. The biometric disadvantages worth planning for are device loss and the platform account behind synced passkeys.
A passkey is a FIDO2/WebAuthn credential, and browsers and operating systems “enforce that passkeys are only ever used for the appropriate service”, so a look-alike phishing page cannot use it; what passkeys are, on passkeys.dev, also notes that site servers store public keys. OWASP describes passkeys as combining possession with a PIN or biometric, and calls them resistant to phishing attacks. The biometric is the unlock: passkeys.dev calls a passkey “a secret stored on one’s devices, unlocked with biometrics”, and NCSC’s guidance on using biometrics explains that the scan taken at login is compared with enrolled data stored on the device.
The disadvantages of biometric authentication are the ones NCSC weighs in its risks section: presentation attacks with an artifact, replay of a captured sample, a weak fallback PIN or password, false acceptance, and privacy, since biometric data is classed as personally identifying information, subject to regulation such as GDPR. For built-in biometric features, NCSC says the processing and capture of data “is also usually performed entirely on the device.” The biometric risk I’d plan for on an owner account is the device, not the template.
The table sets the pros and cons of biometrics against the other factors an owner account can use.
| Factor | Phishing-resistant | What happens on device loss | What the biometric does |
|---|---|---|---|
| Authenticator app (TOTP) | no: CISA rates app-based codes “Vulnerable to phishing attacks” | OWASP: with the phone lost, the user “will be unable to authenticate”; a recovery code or second method is the way back | nothing in the factor itself; it only unlocks the phone |
| SMS or voice code | no: CISA rates it “Vulnerable to phishing, SS7, and SIM swap attacks” | not stated in CISA’s or OWASP’s text | nothing |
| Synced passkey | yes: CISA rates FIDO/WebAuthn “Resistant to phishing” | a passkey provider may restore it from a backup on a new device; NIST requires AAL2-equivalent MFA to reach the synced keys | unlocks the passkey on the device |
| Device-bound passkey or security key | yes, as FIDO/WebAuthn | the credential cannot leave the device, so a lost key needs a second registered key or a recovery code | a PIN or, on a biometric key, a fingerprint checked on the key |
Weighed for one account, the advantages and disadvantages of biometric authentication come down to the table’s two passkey rows: fast, phishing-resistant sign-in, paid for with a plan for a lost device. Biometric login is safe for a dashboard as the unlock step of a passkey, and not as the only thing between a stranger and the account, in my reading; NIST SP 800-63B-4 says a biometric characteristic “is not recognized as an authenticator by itself.” Some dashboards document an authenticator app with backup codes: Porkbun’s 2FA article describes app-based 2FA with one-time backup codes, so recovery codes and a second registered method stay part of the plan. Biometrics for Android phones, the fingerprint or face unlock, are a device setting and not app MFA: they protect the phone, and they count toward a sign-in only when they unlock a passkey. Passwordless authentication best practices for the app’s own customers are a separate decision that the authentication checklist covers.
FIDO2 security keys for the owner account
A FIDO2 security key, a small physical device the owner taps or plugs in to sign in, is the owner account’s strongest factor: phishing-resistant and independent of a phone. My working rule is two keys per dashboard, one kept off-site, with recovery codes in the vault regardless, because a provider that accepts no key still needs a second factor.
CISA’s fact sheet says it directly: “The only widely available phishing-resistant authentication is FIDO/WebAuthn authentication.” In my reading, that is why the owner account on each dashboard gets a hardware key wherever the provider accepts one: it resists phishing and does not depend on a phone. Eight of the dashboards on this page list a security key as a 2-step verification method: Stripe, Cloudflare, AWS, GitHub, Vercel (as a passkey on any WebAuthn device), Namecheap, Porkbun and Google Workspace, whose enforcement even has an “Only security key” option. AWS and Cloudflare each recommend registering more than one MFA device or key, which is what the second key is for.
AWS’s root-user page notes that “FIDO Certified hardware security keys are provided by third-party providers.” I name the label here and don’t describe the certification program itself. For mobile, Yubico’s Security Key Series lists tap-and-go NFC authentication for phones, and passkeys.dev describes the other direction: a phone can be linked to a laptop, so a passkey on the phone signs you in on the laptop. OWASP calls the YubiKey the most common U2F token, and the maker’s store, Yubico’s security keys, lists the Security Key Series from $29 USD when checked on September 27, 2026, so a pair starts at about $58. That names a common example, not a recommendation over other FIDO2 keys.
How to verify it
Two-factor enforcement is verified by trying to break it: from a clean browser profile, sign in to each owner and admin account with the password only and confirm the second-factor prompt stops the session, then read each provider’s organization setting and confirm it says enforced, with the date.
The core test is an admin login without the second factor, run on every surface in the table. Check 4 is how to check if MFA is enforced on a dashboard rather than merely available.
- 01 List every owner and admin account by filling in the surfaces table with names, then date it
- 02 From a clean browser profile, sign in to each dashboard with the password only and confirm the second-factor prompt appears and no session starts without it
- 03 Sign in to the app admin login with the password only and confirm the admin pages and admin API refuse until the code is entered, then send a burst of wrong codes and confirm the attempt limit refuses them
- 04 Read each provider organization setting and confirm it reads enforced, not just available, where the provider documents one
- 05 Use one app recovery code once, then try the same code again and confirm it is refused; where the owner holds a second enrolled factor instead, sign in with it
- 06 Confirm every account belongs to a named person, with no shared owner login
Keep the evidence with the date: the filled-in table for check 1, a screenshot of each prompt for check 2, the refusal responses for checks 3 and 5 (or the successful sign-in with the second factor), a screenshot of each setting for check 4, and the member lists for check 6. On Supabase Auth the password-only session exists at aal1, so check 3 passes when an aal1 session is refused. Where the rule is Supabase’s restrictive Row Level Security template, which “will not accept any JWTs with an aal claim other than aal2”, in my reading an admin read at aal1 comes back with no rows rather than an error, and that empty result is the refusal.
API keys and service tokens do not go through a 2FA prompt, so these checks do not cover them; API authentication best practices between services does.
In the sprint, deliverable 1.11 is verified this way: attempt sign-in to each owner and admin account without the second factor and confirm it is refused.
Where the sprint does this
Deliverable 1.11 is the control set out in the first section and the check in the verify section above. Its result goes into the production readiness report, deliverable 13.1, which delivers the result for every scope item, the work completed and its verification evidence. Third-party hosting, service subscriptions and API consumption remain in the client’s own accounts. Every item is on the sprint’s full deliverable list.
Common questions about two-factor authentication
What is replacing 2FA?
Passkeys, which replace the password rather than the second factor. passkeys.dev calls passkeys “a replacement for passwords”, and OWASP describes a passkey as possession combined with a PIN or biometric, so in my reading the second factor stays, built into the passkey.
What are common 2FA mistakes?
The ones I’d look for first: 2FA turned on but never required, SMS as the default factor, recovery codes kept in the repository or a notes app, one owner login shared by several people, and no test of a sign-in without the second factor. The SMS one is also a standards point: OWASP says not to use SMS for high-value or PII-handling applications.
Which is safer, password or biometrics?
For a dashboard sign-in, neither on its own. The fingerprint or face works best as what unlocks a passkey, which passkeys.dev describes as the secret kept on your devices, and NCSC notes that built-in device biometrics are usually captured and processed entirely on the device.
What are the downsides of multi-factor authentication?
Lockout and a new way in. OWASP lists users who get locked out when they lose or cannot use their other factors, and reset processes that “may be exploitable by attackers”; CISA rates SMS codes as vulnerable to SIM swap, and OWASP lists push fatigue among its attack patterns.
Can I still get hacked if I have 2FA?
Yes. OWASP’s attack patterns include reverse-proxy phishing, push fatigue, SIM swap on SMS codes and downgrade to a weaker method, all of which work around a second factor rather than through it. CISA rates FIDO/WebAuthn as resistant to phishing, which is why a security key goes on the owner account.
What are the NIST guidelines for multifactor authentication (MFA)?
The current version is SP 800-63B-4, which counts three kinds of authentication factor, something you know, have and are, requires more than one distinct kind for MFA, and treats codes sent by SMS or voice over the phone network as a restricted authenticator whose risks an organization must assess and accept before using it.
Which is the strongest 2FA method?
Phishing-resistant MFA. CISA’s Table 1 orders MFA forms from strongest to weakest and puts FIDO/WebAuthn and PKI-based MFA first, then app-based codes and push with number matching, with SMS or voice last. For an owner account that means a FIDO2 security key or a passkey.
The checks in this guide show you where the app is open. The sprint below closes those gaps, tests the result and writes the evidence down.
Built it with AI. Now it has to hold up for real customers.
The Production Hardening Sprint takes the app you already have and builds the production foundation underneath it. Authentication and access rules, payments that stay consistent, error handling, monitoring, backups, automated tests and a documented handover. Our engineers work inside your existing codebase for ten working days. All 123 deliverables are included, and you get the evidence for each one.
See the Production Hardening Sprint →
$2,500 fixed price · 10 working days · One codebase