feat: self-hosted env flag to require MFA for every dashboard user #5025
Copy link
Copy link
Open
Description
Is your feature request related to a problem? Please describe.
Self-hosted instances can't require multi-factor authentication. TOTP MFA is opt-in for each user, magic-link login is always available, and users can turn MFA off themselves. Operators under compliance programs (FedRAMP, SOC 2, HIPAA) need to require a second factor for every dashboard user, not just recommend one.
Describe the solution you'd like to see
An opt-in MFA_REQUIRED webapp env var, off by default. When it's set:
- A signed-in user without MFA is sent to a setup page. Other dashboard requests are refused until they enable it.
- Users can't disable MFA.
Describe alternate solutions
- Put an authenticating proxy (such as OIDC at the load balancer) in front of the dashboard. This adds infrastructure, and the MFA it enforces sits outside Trigger.dev.
- Report users without MFA and follow up with them manually. This catches gaps but doesn't prevent access.
Additional information
I have an implementation ready and will open a PR that references this issue.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels
Activity
feat(webapp): add MFA_REQUIRED env flag to enforce MFA for all dashbo…
MauryaQbit commentedon Oct 17, 2026
For reference, I'd written an implementation of this before I saw the vouch workflow. The branch is public in case it's useful alongside your own:
feat/mfa-required-webapp(7b3b8672b) on MauryaQbit/trigger.dev — rebased on currentmain, 14 files, +646/−16. My PR #5034 was auto-closed by the vouch gate, so this is offered as a reference implementation rather than a request for review.Design, if it's helpful to compare:
MFA_REQUIRED: BoolEnv.default(false); no-op when unset.requireUser+ theroot.tsxloader) because there's no single guard for all authenticated routes; the root loader does not run for action-only resource routes, so those actions check separately./login*,/magic,/auth/*,/logout) and the enrollment endpoint are exempt, to avoid a redirect deadlock.enableTotporphaning a pendingSecretReferencewhen the forced-setup page is refreshed.typecheck --filter webapp20/20,oxfmt/oxlint/knipclean. Docker-backed suites unverified locally (no container runtime here).refs #5025