AstroBaaS

Customers & accounts

Two-Factor Authentication

Free — GPL coresize Mplanned, not built

Generated from docs/plan/core/two-factor-authentication/PLAN.md in the AstroBaaS repository. Nothing described below is implemented — it is the written plan for it.

Two-Factor Authentication (2FA) requires staff to verify a second factor — usually a time-based one-time password (TOTP) from an authenticator app — in addition to their password.

The problem

Merchants’ accounts get hacked via password guessing; attackers delete content or steal customer data.

What it does

  • TOTP (time-based one-time password) via authenticator app
  • Optional SMS-based OTP (backup, not primary)
  • Backup codes (10 one-time codes for recovery)
  • Enforce 2FA for Admin role (mandatory); optional for others
  • User can enable/disable 2FA (except Admins, always on)
  • Admin can force 2FA on a user (revoke, force re-enrollment on next login)
  • 2FA grace period: 30 days to enroll
  • Audit log for enrollment, disable, failed attempts
  • Rate limiting: 3 failed OTPs causes 5-minute lock

What it deliberately does NOT do

Each boundary carries its reason. A boundary without a reason gets crossed by the next person who reads this.

  • WebAuthn/FIDO2 (hardware keys) — complexity; TOTP covers 95%
  • Biometric 2FA — not applicable to web staff
  • SMS as primary 2FA — costs money; TOTP is free/secure
  • Push notifications (approve login attempts) — requires device infrastructure
  • Passwordless login — 2FA is supplementary

Data model

TwoFactorAuth: id, user_id, method (totp/sms), secret_key (encrypted), is_enabled, enrolled_at, last_used_at, backup_codes (encrypted, JSON). Migration: add two_factor_auth table; add is_2fa_required to Role table.

API

  • POST /auth/2fa/enroll
  • POST /auth/2fa/verify-enrollment
  • POST /auth/2fa/verify-login
  • POST /auth/2fa/disable
  • POST /auth/2fa/backup-codes
  • POST /auth/2fa/use-backup-code
  • GET /auth/2fa/status
  • POST /admin/team/{user_id}/2fa/force-reset

Every route added here must also appear in src/pages/openapi.json.ts — a test fails the build if it does not.

Admin

2FA enrollment during invite: checkbox require 2FA, option to force on next login. Staff profile: show 2FA status (enabled/disabled), method, date enrolled; Admin can force reset. Enrollment flow: QR code, verify with code, show backup codes. Grace period: notification banner.

The seam — why this is core

Core owns: 2FA table, TOTP/SMS verification, secret encryption, backup code generation, grace period enforcement. Paid module owns: SMS gateway (if SMS is premium); core provides TOTP (free).

Core owns the interface + honest TOTP/SMS implementation; security is infrastructure, not a support commitment or credential.

Dependencies

  • admin-user-management

Acceptance checks

Each of these must be able to fail. Before claiming this is done, break the code deliberately and watch each one go red.

  • Enrolling in TOTP: QR scanned, OTP submitted, 2FA enabled; next login prompts for OTP
  • Login without 2FA: correct user/pass but wrong/missing OTP returns 401, prompt again
  • Admin forces reset: secret deleted, is_enabled=false; next login bypasses 2FA
  • Using backup code: valid once, removed from list; second use fails
  • 3 failed OTPs in 5min causes lock; 4th attempt within lock period rejected immediately
  • Exporting backup codes shows obfuscated in logs, never plaintext

Risks

Secret key leaked causes attacker to generate valid OTPs. Backup codes lost locks user out. TOTP clock skew (needs ±30s tolerance). Enrollment incomplete causes false sense of protection. Rate limiting not enforced. Mandatory 2FA enforced before grace expires.

Commercial context

Suggested pricefree (core)
Rival anchorShopify: included; Magento: included

The anchor is what the nearest equivalent charges on Shopify or Magento today. It is context for a pricing decision, not the decision.


Generated from the commerce plan. See docs/COMMERCE-PLAN.md for the full catalogue and ../../AI-GUIDE.md for how to work on this repository.