You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat: self-hosted env flag to require MFA for every dashboard user #5025
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.
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 current main, 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.
Layered enforcement (requireUser + the root.tsx loader) 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.
The auth flow (/login*, /magic, /auth/*, /logout) and the enrollment endpoint are exempt, to avoid a redirect deadlock.
Disable is blocked at the service, route and UI layers.
Also fixed enableTotp orphaning a pending SecretReference when the forced-setup page is refreshed.
14 unit tests; typecheck --filter webapp 20/20, oxfmt/oxlint/knip clean. Docker-backed suites unverified locally (no container runtime here).
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