tutorial

2FAuth Monitoring with Vigilmon

"Learn how to monitor 2FAuth, the open-source self-hosted two-factor authentication manager, with Vigilmon — covering web application availability, health endpoint checks, API health, SSL certificate alerts, and OTP generation pipeline heartbeats."

2FAuth Monitoring with Vigilmon

2FAuth is a self-hosted web application for managing TOTP and HOTP two-factor authentication tokens. Instead of relying on a phone app, teams store 2FA secret keys in 2FAuth and access current OTP codes via a web UI or REST API. It is used by DevOps teams needing shared 2FA access to service accounts, for 2FA code backups beyond a single mobile device, and in server environments where mobile apps are not available.

Because 2FAuth stores 2FA secret seeds — the root credentials from which all OTP codes are derived — it is security-critical infrastructure. An expired SSL certificate or an unavailable application server does not just cause an outage: it exposes high-value secrets to interception and blocks the team from authenticating to any service that requires 2FA codes managed through it.

This guide covers how to monitor 2FAuth with Vigilmon.


Why 2FAuth Needs Monitoring

2FAuth failures can block authentication to downstream services:

  • Laravel application server crash — the PHP application stops responding; users and automated scripts cannot retrieve OTP codes; every service requiring a 2FAuth-managed 2FA code is effectively inaccessible
  • Database connectivity failure — the SQLite/MySQL/PostgreSQL backend is corrupted or unreachable; 2FA accounts cannot be loaded and OTP generation fails
  • SSL certificate expiry — CRITICAL: an expired cert on the 2FAuth server exposes 2FA secret seeds to potential interception, and browser clients are blocked by TLS errors, making OTP codes unavailable during active authentication
  • API authentication failure — the REST API returns errors; automated pipelines that retrieve OTP codes via API break silently
  • OTP generation failure — the TOTP algorithm engine has a clock drift or database issue; the API returns codes but they are invalid at the destination service

Vigilmon monitors all of these failure modes so your team is alerted before a 2FA outage blocks critical service access.


2FAuth Architecture Overview

| Component | Default Port | Role | Monitoring Priority | |-----------|-------------|------|---------------------| | Laravel/PHP-FPM | 8000 (Docker) or 80/443 (proxy) | Web application and REST API | Critical | | SQLite/MySQL/PostgreSQL | Embedded or 3306/5432 | 2FA account and secret storage | Critical | | Nginx/Apache (optional) | 80/443 | Reverse proxy with SSL termination | High |


Monitor 1: 2FAuth Web Application Availability

Monitor the Laravel/PHP login page:

  1. Log in to VigilmonMonitors → New Monitor
  2. Type: HTTP
  3. Name: 2FAuth - Web Application
  4. URL: http://your-2fauth-host:8000/ (Docker) or https://2fauth.your-domain.com/
  5. Method: GET
  6. Expected status: 200
  7. Keyword check: 2FAuth
  8. Interval: 1 minute

Test your endpoint:

curl -s http://your-2fauth-host:8000/ | grep -i "2fauth"
# Expected: HTML containing "2FAuth"

Monitor 2: 2FAuth Health Endpoint

Recent versions of 2FAuth include a built-in health check endpoint that returns application and database status:

  1. Type: HTTP
  2. Name: 2FAuth - Health Check
  3. URL: http://your-2fauth-host:8000/healthcheck
  4. Method: GET
  5. Expected status: 200
  6. Keyword check: ok
  7. Interval: 1 minute
curl -s http://your-2fauth-host:8000/healthcheck
# Expected: {"status": "ok"} (HTTP 200)

If the /healthcheck endpoint returns 404 (not available in your 2FAuth version), fall back to monitoring the login page (/) for HTTP 200 + keyword 2FAuth. The health endpoint is preferred because it explicitly verifies the database connection, not just HTTP reachability.


Monitor 3: 2FAuth API Health (Unauthenticated)

The /api/v1/user endpoint returns HTTP 401 (not 500) when the request is unauthenticated. A 401 response confirms API routes are registered and the database session store is accessible — a 500 response indicates a Laravel or database failure:

  1. Type: HTTP
  2. Name: 2FAuth - API Routes Health
  3. URL: http://your-2fauth-host:8000/api/v1/user
  4. Method: GET
  5. Expected status: 401
  6. Interval: 2 minutes
curl -s -o /dev/null -w "%{http_code}" http://your-2fauth-host:8000/api/v1/user
# Expected: 401 (unauthenticated — correct behavior confirming API is functional)
# Error: 500 (Laravel/database failure)

This monitor catches Laravel errors that would not show on the login page (which may be served from cache or a static fallback).


Monitor 4: SSL Certificate Alert — CRITICAL

2FAuth stores 2FA secret seeds. An expired SSL certificate on the 2FAuth server exposes these high-value secrets to potential interception and immediately blocks all browser clients with TLS errors:

  1. Type: HTTP
  2. Name: 2FAuth - SSL Certificate
  3. URL: https://2fauth.your-domain.com/
  4. SSL certificate expiry alert: 30 days before expiry
  5. Interval: 1 hour

A 30-day lead time is mandatory for 2FAuth. SSL certificate renewal failures are common enough that 14-day or 7-day lead times leave insufficient runway — especially when the 2FA manager itself is needed to authenticate the renewal tooling.


Monitor 5: OTP Generation Pipeline Heartbeat

The most reliable end-to-end verification is an hourly automated check that authenticates to the 2FAuth API, lists accounts, and generates a test OTP. This confirms the TOTP algorithm engine, database, and API authentication are all working:

Prerequisites

Create a dedicated service account in 2FAuth for monitoring, and a dedicated test 2FA account with a known TOTP seed. Record the account ID for use in the heartbeat script.

Heartbeat Script

#!/bin/bash
# 2fauth-heartbeat.sh — run hourly via cron
set -euo pipefail

TWOFAUTH_URL="http://your-2fauth-host:8000"
TWOFAUTH_EMAIL="heartbeat@your-domain.com"
TWOFAUTH_PASSWORD="$TWOFAUTH_HEARTBEAT_PASSWORD"
TEST_ACCOUNT_ID="1"  # ID of your dedicated test 2FA account
VIGILMON_HEARTBEAT="YOUR_HEARTBEAT_ID"

# Step 1: Authenticate and obtain a Bearer token
AUTH_RESPONSE=$(curl -s -X POST \
  -H "Content-Type: application/json" \
  -d "{\"email\":\"${TWOFAUTH_EMAIL}\",\"password\":\"${TWOFAUTH_PASSWORD}\"}" \
  "${TWOFAUTH_URL}/api/v1/user/login")

AUTH_TOKEN=$(echo "$AUTH_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('token',''))" 2>/dev/null)

if [ -z "$AUTH_TOKEN" ]; then
  echo "[2fauth-hb] Authentication failed"
  exit 1
fi

# Step 2: List accounts to verify database read access
ACCOUNTS_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  "${TWOFAUTH_URL}/api/v1/twofaccounts")

if [ "$ACCOUNTS_STATUS" -ne 200 ]; then
  echo "[2fauth-hb] Account list returned $ACCOUNTS_STATUS"
  exit 1
fi

# Step 3: Generate an OTP for the test account
OTP_RESPONSE=$(curl -s \
  -X POST \
  -H "Authorization: Bearer $AUTH_TOKEN" \
  "${TWOFAUTH_URL}/api/v1/twofaccounts/${TEST_ACCOUNT_ID}/otp")

OTP_CODE=$(echo "$OTP_RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin).get('otp',''))" 2>/dev/null)

# Validate OTP is a 6-digit code
if ! echo "$OTP_CODE" | grep -qE '^[0-9]{6}$'; then
  echo "[2fauth-hb] OTP generation failed or invalid format: '$OTP_CODE'"
  exit 1
fi

echo "[2fauth-hb] OTP generated successfully (${#OTP_CODE} digits)"

# Step 4: Signal successful OTP generation to Vigilmon
curl -s "https://heartbeat.vigilmon.online/$VIGILMON_HEARTBEAT"
echo "[2fauth-hb] Pipeline healthy"

Add to cron:

# /etc/cron.d/2fauth-heartbeat
0 * * * * www-data /opt/2fauth/2fauth-heartbeat.sh >> /var/log/2fauth-heartbeat.log 2>&1

In Vigilmon:

  • Type: Heartbeat
  • Name: 2FAuth - OTP Generation Pipeline
  • Expected interval: 1 hour
  • Grace period: 15 minutes

A missed heartbeat means OTP generation has failed — the system that provides 2FA codes when users need to authenticate is broken, and every downstream service requiring 2FA will be inaccessible.


Alert Configuration

| Monitor | Type | Interval | Alert Channel | |---------|------|----------|---------------| | Web application | HTTP | 1 min | PagerDuty + Slack | | Health endpoint | HTTP | 1 min | PagerDuty + Slack | | API routes health (401 check) | HTTP | 2 min | Slack | | SSL certificate | HTTP | 1 hour | Email + Slack (30-day lead) | | OTP generation pipeline | Heartbeat | 1 hour | PagerDuty + Email |

Use PagerDuty or phone alerts for the web application and OTP pipeline monitors. A 2FAuth outage blocks authentication to every downstream service requiring 2FA — this is a high-priority incident requiring immediate response.


Status Page

  1. Status Pages → New Page → name it "2FAuth OTP Service"
  2. Add all monitors above
  3. Share with your DevOps and security team

When engineers are blocked from authenticating to a service requiring 2FA, they can check this status page first to determine whether 2FAuth itself is the root cause before escalating.


Summary

2FAuth is security-critical infrastructure — it holds the 2FA secret seeds that protect every service account your team uses. Vigilmon ensures it remains available and generating valid OTP codes:

  • HTTP monitors for web application availability, built-in health endpoint, and unauthenticated API route health
  • SSL certificate monitoring with a mandatory 30-day lead time given the sensitivity of stored 2FA secrets
  • Hourly heartbeat that authenticates, lists accounts, and generates a test OTP — confirming the full TOTP pipeline is operational

Get started at vigilmon.online.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →