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.