Self-Hosted MFA

Run your own two-factor authentication system. Understand how MFA actually works, and control your own codes.

What Two-Factor Actually Is

Two-factor authentication (2FA) is just two things you need to log in instead of one:

  • Factor 1: Something you know (your password)
  • Factor 2: Something you have (usually a code from your phone)

The second factor is usually generated by an app on your phone. That app? It's generating a code based on time and a secret.

QR Codes Are Just The Shortcut

When you set up two-factor on something like Google or GitHub, they show you a QR code. That QR code is basically just a faster way to enter a long string of characters.

What the QR code actually contains:

otpauth://totp/Google:user@gmail.com?secret=JBSWY3DPEBLW64TMMQ======&issuer=Google

That weird string of characters? That's your secret. The QR code is just a fancy way to share it with your phone without you having to type 32 random characters by hand. You could literally type that in manually if you wanted to.

Your phone's authenticator app (Google Authenticator, Authy, whatever) reads that secret and uses it to generate a new code every 30 seconds.

How The Code Generation Works

The Algorithm: TOTP

It's called TOTP (Time-based One-Time Password). Here's what happens every 30 seconds:

1. Your phone checks the current time
2. It takes your secret (that string from the QR)
3. It combines the secret + time into math
4. Out pops a 6-digit code
5. 30 seconds later, it does it again with a new time

Example:
Secret: JBSWY3DPEBLW64TMMQ======
Time: May 10, 2026 - 14:30:00
Result: 483652

Time: May 10, 2026 - 14:30:30  
Result: 927184

The magic is that both your phone AND the server doing the authenticating use the exact same algorithm with the exact same secret. So when you type 483652, the server does the math and goes "yep, that's right for this time period."

Running Your Own MFA System

Why Self-Hosted?

  • Control: You manage the secrets. No cloud provider holding them.
  • Understanding: You see exactly how it works instead of it being magic.
  • Flexibility: Build it into your own apps or systems.
  • Privacy: Your authentication data never leaves your system.

Step 1: Generate A Secret

You create a random 32-character string. This is your secret key. Store it somewhere safe. This is what your phone will use to generate codes.

Step 2: Create A QR Code (Optional)

Convert that secret into a QR code using an encoder. Your phone's authenticator app scans it. Boom, your phone now knows the secret and starts generating codes.

Step 3: Validate Codes On Your Server

When someone tries to log in and enters a 6-digit code, your server does the TOTP math using the same secret. If the math matches, access granted. Simple.

Step 4: Keep Codes Running

Your phone's authenticator app keeps generating new codes automatically every 30 seconds. It's running locally on your phone, no network needed. You just copy-paste or look at the screen when you need to log in.

Real Example Flow

User Setup

System generates secret: ABCD1234EFGH5678IJKL90MN

Sharing

System creates QR code from that secret. User scans with Google Authenticator.

Codes Start Generating

Phone app now has the secret. Every 30 seconds: new 6-digit code (827364, then 194528, then 756392...).

Login Time

User enters password: correct. System asks for 2FA code. User opens authenticator app: shows 756392. Enters it.

Verification

Your server takes the secret, does the TOTP math with current time, checks if it matches 756392. It does. Access granted.

The Math

TOTP Formula:
T = floor((current_time - epoch) / 30)
HMAC = SHA1(secret, T)
Code = last_6_digits(HMAC)

Verification:
Generate code for current time
Compare with user-entered code
Allow 30 seconds of drift (to account for clock sync)

Libraries: pyotp (Python), speakeasy (Node), google-authenticator (Android)

The actual math uses HMAC-SHA1, which is a one-way cryptographic function. You can't reverse it to get the secret back just from looking at the code. This makes TOTP secure — even if someone intercepts a code, they can't use it again or derive the secret.

⚠️ Backup Codes

Here's the problem: if you lose your phone, you can't generate codes anymore. You're locked out.

Self-hosted systems should always generate backup codes when someone sets up MFA. These are single-use codes you store safely (printed, in a vault, wherever). If you lose your phone, one backup code gets you in, and you can set up a new authenticator.

This is how Google and others handle it. You get 10 backup codes during setup. Use them sparingly.

Learn More

Ente Auth - Open Source Authentication →