herald-totp

command module
v1.2.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 14, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

README

herald-totp

License Go Version Go Report Card

Multi-language Documentation

TOTP 2FA service for the Herald/Stargate stack: enroll (bind), verify, and optional backup codes. It does not send codes; users generate TOTP in an authenticator app (e.g. Google Authenticator). Stargate calls herald-totp for per-user TOTP instead of a single global secret.

The HTTP server currently uses Fiber v3.5.0 and the matching v2 module lines of the Fiber-facing kit packages. Building from source requires Go 1.26 or later; go.mod is the authoritative source for exact dependency versions.

Core Features

  • Enroll: POST /v1/enroll/start (returns QR content) and POST /v1/enroll/confirm (confirm with one TOTP code).
  • Verify: POST /v1/verify (TOTP or backup code), returns subject, amr, issued_at; optional challenge_id for replay protection.
  • Revoke: POST /v1/revoke to remove TOTP credential and backup codes for a subject.
  • Status: GET /v1/status?subject=... to check if a user has TOTP enabled.
  • Backup codes: 10 one-time codes returned on confirm; can be used in verify when the device is lost.
  • Security: Encrypted secret storage (AES-GCM), rate limiting, atomic one-time consumption of TOTP steps, backup codes, and challenge IDs, plus API key or HMAC auth.
  • Graceful shutdown: On SIGINT or SIGTERM, server stops accepting new requests and shuts down with a 10s timeout.

Architecture

Stargate orchestrates login and TOTP bind; herald-totp stores per-user TOTP secrets (encrypted) and backup codes in Redis and performs enroll/verify.

sequenceDiagram
  participant User
  participant Stargate
  participant HeraldTotp as herald-totp
  participant Redis

  Note over User,Redis: Bind flow (after login)
  User->>Stargate: Open TOTP enroll page
  Stargate->>HeraldTotp: POST /v1/enroll/start (subject)
  HeraldTotp->>Redis: Store temp enrollment
  HeraldTotp-->>Stargate: enroll_id, otpauth_uri
  Stargate-->>User: Show QR code
  User->>Stargate: Enter TOTP code
  Stargate->>HeraldTotp: POST /v1/enroll/confirm (enroll_id, code)
  HeraldTotp->>Redis: Save credential, backup_codes
  HeraldTotp-->>Stargate: backup_codes
  Stargate-->>User: Bind done

  Note over User,Redis: Login flow (TOTP step)
  User->>Stargate: Submit TOTP or backup code
  Stargate->>HeraldTotp: POST /v1/verify (subject, code)
  HeraldTotp->>Redis: Read credential, verify
  HeraldTotp-->>Stargate: ok, subject, amr, issued_at
  Stargate-->>User: Session created
  • Stargate: ForwardAuth / login and TOTP bind orchestration; calls herald-totp for enroll and verify.
  • herald-totp: Per-user TOTP secrets (AES-GCM in Redis), enroll/confirm, verify (TOTP or backup code), revoke, status.
  • Redis: Credentials, enrollment temp state, backup codes, rate limits.

Protocol

  • POST /v1/enroll/start – Start enrollment; returns enroll_id, otpauth_uri (and optionally secret_base32).
  • POST /v1/enroll/confirm – Submit TOTP code to confirm; returns backup_codes.
  • POST /v1/verify – Verify TOTP or backup code; returns ok, subject, amr, issued_at.
  • POST /v1/revoke – Remove TOTP and backup codes for a subject.
  • GET /v1/status?subject=... – Check if TOTP is enabled for subject.
  • GET /healthz – Service and Redis health (via health-kit).

Configuration

Variable Description Default Required
PORT Listen port (with or without leading colon) :8084 No
HERALD_TOTP_ENCRYPTION_KEY Exact 32-byte AES-256 key for secret encryption `` Yes (startup)
API_KEY If set, callers must send X-API-Key `` No
HMAC_SECRET / HERALD_TOTP_HMAC_KEYS HMAC auth `` No
REDIS_ADDR Redis address localhost:6379 Yes
EXPOSE_SECRET_IN_ENROLL If false, omit secret_base32 in enroll/start response true No
LOG_LEVEL Log level: trace, debug, info, warn, error info No

See docs/enUS/DEPLOYMENT.md for full options.

Stargate integration

  • Set HERALD_TOTP_ENABLED=true, HERALD_TOTP_BASE_URL=http://herald-totp:8084, and HERALD_TOTP_API_KEY or HERALD_TOTP_HMAC_SECRET to match herald-totp.

Quick Start

Build & run (binary)
export HERALD_TOTP_ENCRYPTION_KEY="$(openssl rand -base64 24)"
export REDIS_ADDR=localhost:6379
go build -o herald-totp .
./herald-totp

Redis must already be reachable at REDIS_ADDR. Keep the generated encryption key stable after credentials have been created; changing it makes existing TOTP secrets unreadable.

Run with Docker
export HERALD_TOTP_ENCRYPTION_KEY="$(openssl rand -base64 24)"
docker network create herald-totp
docker run -d --name herald-totp-redis --network herald-totp redis:8-alpine
docker build -t herald-totp .
docker run -d --name herald-totp --network herald-totp -p 8084:8084 \
  -e HERALD_TOTP_ENCRYPTION_KEY \
  -e REDIS_ADDR=herald-totp-redis:6379 \
  herald-totp

Optional: add -e API_KEY=your_shared_secret and set HERALD_TOTP_API_KEY to the same value on Stargate.

Released images are also available from GHCR. Use an immutable version tag for deployments, for example ghcr.io/soulteary/herald-totp:v1.0.0.

Documentation

Testing

go test ./...

Coverage:

go test -cover ./...
go test -coverprofile=coverage.out ./...
go tool cover -func=coverage.out
go tool cover -html=coverage.out

Lint: golangci-lint run.

Operation

  • Graceful shutdown: On SIGINT or SIGTERM, the server stops accepting new requests and shuts down with a 10s timeout. Logs "shutting down" and any shutdown error.
  • Logging: Structured JSON logs via logger-kit. Set LOG_LEVEL to debug for more detail.

License

See LICENSE for details.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
internal
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL