Learn 2FA Authentication - Production: Deployment, Secrets & Observability
Episode 20 of 23

Learn 2FA Authentication - Production: Deployment, Secrets & Observability

This episode takes 2FA to production: environment configuration with MFA_ENCRYPTION_KEY and the session secret, KMS for key management, encrypted backups, plus observability with PII-free and code-free MFA event logs, with alerting for rate limits and login anomalies.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Introduction

All the features already work on localhost. Episode 20 answers the far more uncomfortable question: what happens when this runs in production, for years, with real users. Three things decide it: correct secret configuration, safe observability, and alerting that catches anomalies.

The secret to 2FA in production doesn't lie in a single technology, but in discipline: encryption keys never in source control, logs never carrying codes, and suspicious events always triggering warnings. You'll set up all three as the operational foundation.

Deployment and Environment

Mandatory Environment Variables

Production needs documented, encrypted configuration. The minimum list:

Production environment for 2FA
MFA_ENCRYPTION_KEY=9a3c2f4e1d0b7c6a5f8e9d0c1b2a3f4e5d6c7b8a9f0e1d2c3b4a5f6e7d8c9a0b
SESSION_SECRET=panjangAcakTidakMudahDitebak
JWT_SECRET=panjangAcakBerbedaDariSession
DATABASE_URL=postgresql://devvnull:xxx@db.internal/devvnull
APP_ORIGIN=https://auth.devvnull.dev

The MFA_ENCRYPTION_KEY value must be 32 bytes of hex created with a random generator, not typed by hand:

Create the encryption key correctly
openssl rand -hex 32

The openssl rand -hex 32 command produces 64 hex characters — exactly 32 bytes of entropy. Store the value in a platform secret manager (Vercel, AWS Secrets Manager, or GitHub Secrets), never in a committed file.

KMS for Encryption Keys

At a certain scale, pull the encryption key from a KMS instead of the environment. KMS provides envelope encryption: the app holds a temporary data key while the master key lives in the KMS. The advantage: rotation and key access auditing are centralized, and a single environment leak doesn't immediately leak the decryption capability.

Backup and Recovery

Encrypted Backups

Database backups must be encrypted at the system level — the 2FA secrets inside are already application-encrypted, but a second layer protects the data when it's moved and stored. Use the snapshot encryption the platform provides (EBS encryption, RDS encryption) and copy to a separate location for disaster resilience.

Real Recovery Tests

Periodically restore a backup to a test environment and run a login with a real Google Authenticator. This test verifies three things at once: the backup isn't corrupted, the encryption key is stored correctly, and the whole flow stays alive after restore. Teams that only restore during emergencies always find surprises at the worst moment.

Safe Observability

MFA Events Without PII and Codes

MFA logs must give context for investigation without storing dangerous data. Use a JSON structure with consistent event names:

JSSafe MFA event logging
function logMfa(event, userId) {
  console.log(JSON.stringify({
    event,
    userId,
    ts: new Date().toISOString(),
    source: 'mfa'
  }));
}
 
logMfa('MFA_ENABLED', user.id);
logMfa('MFA_DISABLED', user.id);
logMfa('MFA_FAILED', user.id);

The logMfa pattern separates the event name from the response details. No TOTP code, secret, or provisioning URI passes through the log — only the user identity and the event.

Add a request id to every line so logs can be correlated with traces during an incident.

Metrics and Dashboards

Besides logs, collect metrics: verification success rate, average time to complete enrollment, and the failure distribution per IP. A dashboard showing these trends gives early warning — an MFA failure spike almost always precedes an attack or a bug.

Alerting for Anomalies

Rate Limits and Failure Spikes

Alerting doesn't wait for a human to look at the dashboard. Simple rules with big impact:

Basic MFA alerting rules
- rate limit 429 exceeding 50 per 5 minutes per IP
- MFA_FAILED 3x the 1-hour baseline
- MFA_DISABLED 5 accounts in 10 minutes
- Successful login with a recovery code from a new IP

The last pattern — recovery login from a new IP — is the classic account hijack signal. Each rule targets an actionable scenario, not mere noise.

Defined Responses

An alert without a runbook is just a notification. Write a response for each rule: block the IP on rate limit, suspend the account on a mass MFA_DISABLED pattern, and contact the user on suspicious recovery logins. Written procedures keep on-call from panicking at night.

Conclusion

Episode 20 prepared production operations: environment and KMS for encryption keys, encrypted backups with recovery tests, PII-free and code-free observability, and alerting with a runbook for every anomaly.

The key takeaways:

  • Store MFA_ENCRYPTION_KEY and SESSION_SECRET in a secret manager.
  • Use openssl rand -hex 32 to create the correct key.
  • Pull keys from a KMS for centralized rotation and audit.
  • Encrypt backups and test recovery periodically.
  • Log MFA events in JSON without codes and secrets.
  • Alert with a runbook for rate limits and login anomalies.

In the next episode, episode 21, we will cover the 2026 ecosystem: providers and authenticator apps — when to use Clerk, Auth0, Supabase Auth, or WorkOS versus building your own, plus compatibility across Google Authenticator, Microsoft Authenticator, Authy, and 1Password.

Learn 2FA Authentication - Production: Deployment, Secrets & Observability | Learn 2FA Authentication