Young's Mind
Research

Security layer — 2FA and account management

Young, 2026-10-18: "Another features that we need to add as security layer, pls share your thought everyone: 2FA and account management"

Security layer — 2FA and account management

Young, 2026-10-18: "Another features that we need to add as security layer, pls share your thought everyone: 2FA and account management"

My read in one line: we do not need to build an identity system. Both halves already exist in what we are already deploying — Medusa ships MFA in core for commerce actors, and Authelia (Apache-2.0) covers the gated-static sites (docs, Pulse) that Medusa never sees. The work is wiring two existing pieces, not inventing a third.


1. The problem, stated precisely

We have three different kinds of login on the tenancy platform, and they are not the same problem:

SurfaceWho logs inExample
Commerce storefrontthe tenant's customersa shop's shopper
Commerce adminthe tenant's staffshop owner managing orders
Gated static sitesour people + the tenantdocs.youngle.au (private), Pulse (public)

A single answer does not fit all three. Attempting one would either over-build the storefront or under-protect the docs site.


2. What already exists (measured today)

2a. Medusa MFA — built into the core Auth Module

Medusa ships TOTP multi-factor authentication as part of the core Auth Module, since v2.15.5.[4]5 It requires no custom auth provider and no hosted auth service.5

The flow, as documented:

  1. The auth provider verifies the first factor (email/password, GitHub OAuth, or a custom provider).5
  2. Medusa checks whether the authenticated auth_identity has MFA enabled.5
  3. If enabled, no token is issued. Instead Medusa returns a short-lived challenge: { mfa_required: true, mfa_challenge: { id, methods: ["totp" | "recovery_code"], expires_at } }.5
  4. The user completes it with an authenticator app code (1Password, Authy, Google Authenticator, Microsoft Authenticator) or a recovery code, and only then is the token minted.5

Setup returns { mfa: {id, provider: "totp", status: "pending"}, secret, otpauth_url } — the otpauth_url renders as a QR code.5 Recovery codes are included, which is the part teams forget and then get locked out over.5

It works across actor types — the same flow protects admin users, customers, or custom actors.5 Configuration is one environment variable, AUTH_MFA_ENCRYPTION_KEY (a 64-character random string; auto-generated for apps created after v2.15.5).4

2b. Authelia — for everything Medusa does not own

docs.youngle.au is currently behind nginx basic-auth (I measured a 401 to anonymous requests). Basic-auth is a single shared password with no second factor, no user accounts, and no audit trail. For a private docs site holding our internal vault content, that is the weakest link in the whole platform.

Authelia is an open-source authentication and authorization server providing two-factor authentication and single sign-on (SSO) for applications via a web portal, acting as a companion for reverse proxies — which is exactly our nginx front door.[7]17 It is Apache-2.0 licensed.14 It integrates with a reverse proxy through a forward-auth / proxy-authorization endpoint, and the proxy must pass a defined set of headers.7

Why this is the right fit: it protects sites that have no application login of their own — a static Docus build cannot authenticate anyone. Authelia sits in front at the proxy layer, so the site needs no code change.

2c. Better Auth — already inside the eve Web Chat Agent

The eve Web Chat Agent template ships with Better Auth for per-user memory.1 Better Auth's 2FA plugin supports TOTP, OTP (email/SMS), backup codes, and trusted devices — and by default requires a password to enable 2FA.6 So the EVE receptionist product inherits an account layer without us writing one.


3. Proposed security layer — three tiers, two components

LayerComponentCoversCost
L1 — Platform gateAuthelia (Apache-2.0)docs site, Pulse, any static/private vhostA$0 software
L2 — Commerce identityMedusa Auth + MFA (core)storefront customers, tenant admin staffA$0 (in core)
L3 — Agent identityBetter Auth (in eve templates)EVE chat users, per-user memoryA$0 (in template)

All three are open-source and already in our stack. The security layer adds no licence cost — it is wiring plus configuration.

3a. Why Authelia rather than something else

  • It solves the problem nginx basic-auth cannot: real accounts, TOTP second factor, SSO across multiple gated vhosts, and an audit trail.
  • It is proxy-level, so it protects static sites with zero application changes — critical because Docus is a static build.
  • Apache-2.0 — resellable and self-hostable, consistent with our licence-clean rule.

3b. Account management — what "management" should mean here

"Account management" is three distinct jobs; conflating them is how systems get built twice:

  1. Self-service — the user enrols their own TOTP, generates recovery codes, and revokes a lost device. Medusa MFA and Better Auth both provide this; it should be the user's job, not a support ticket.
  2. Tenant administration — the tenant's own admin invites/removes their staff and resets their access. Medusa's admin layer carries this.
  3. Platform administration — we provision a tenant, issue their first admin, and can revoke at the platform level. This is our job and should be a documented runbook, not an ad-hoc shell command.

The rule I would set: the tenant owns their users; we own the tenant's existence. We should never be in the business of holding a tenant's staff passwords.


4. Where 2FA should be mandatory vs offered

Not every login deserves the same friction. My recommendation:

Surface2FA postureReason
Tenant admin / staffMandatorythey can see orders, customers, money
Platform admin (us)Mandatorywe hold every tenant's keys
Private docs siteMandatory (Authelia)holds our internal vault content
Storefront customersOffered, not forcedforced 2FA on shoppers measurably costs sales
Public sites (Pulse)Nonepublic by design

This is the defensible middle: protect what holds money and private data, do not put friction in front of a shopper's checkout.


5. What I would flag before we build

  1. Basic-auth on the docs site is the current weakest link. It is one shared password in front of our internal vault mirror, with no second factor and no audit trail. Authelia is the fix, and it is the highest-value item here.
  2. AUTH_MFA_ENCRYPTION_KEY is a new secret to manage. It encrypts MFA factors — losing it locks every enrolled user out. It belongs in the tenant's env file at mode 600, never in a unit file (see the credential finding in my vault verification — prod currently inlines API keys in a world-readable unit).
  3. Recovery codes are not optional. Both Medusa and Better Auth ship them; if we do not surface them during enrolment, our support load becomes password resets forever.
  4. Do not build a fourth auth system. We already have three; the discipline is to use each for the surface it owns.

Honest limits

  • I verified capability from the vendors' own docs, not by deploying and exercising each flow. Medusa MFA requires v2.15.5+ — confirm our pinned version satisfies it before promising the feature. Update 2026-10-21: the Authelia half of this is no longer a proposal — it is live on prod aarch64 (deployed by sol). I re-probed from LAB: auth.youngle.au returns 200 on a Let's Encrypt SAN cert covering all 11 youngle.au subdomains (tls_verify=0), and docs.youngle.au + solos.youngle.au return 302 → auth.youngle.au, so the L1 platform gate is real. What remains unproven is the Medusa MFA flow itself (deployed, but I have not enrolled a TOTP actor).
  • No penetration testing has been done. This study proposes an architecture; it is not a security audit of the current platform.
  • The 401 on docs.youngle.au confirms something gates it; I read the nginx config to confirm basic-auth, and did not attempt to authenticate.

Sources

Sources

1 https://eve.dev/templates — eve — Templates (agent catalogue) 4 https://docs.medusajs.com/resources/commerce-modules/auth/mfa — Medusa — Multi-Factor Authentication (Auth Module) 5 https://medusajs.com/blog/announcing-mfa — Medusa — Announcing multi-factor authentication (2026-06-04) 6 https://better-auth.com/docs/plugins/2fa — Better Auth — Two-Factor Authentication plugin 7 https://www.authelia.com/integration/proxies/introduction — Authelia — Proxies integration 8 https://hub.docker.com/r/authelia/authelia — Authelia — Docker image 14 https://github.com/authelia/authelia — Authelia — Apache-2.0 License (repo) 17 https://www.authelia.com — Authelia — authentication & authorization server

Copyright © 2026