visanduma/nova-two-factor
visanduma/nova-two-factor adds two-factor authentication to Laravel Nova. It lets users enable TOTP-based 2FA with QR code setup and recovery codes, helping protect Nova access with an extra verification step at login.
Closing an "MFA on admin access" gap without funding an identity project. This package adds TOTP two-factor authentication to the Laravel Nova admin panel specifically — the surface where support, finance, and ops staff see customer and business data. If a security questionnaire, SOC 2-style audit, or internal policy asks whether privileged access is protected by MFA, this is the shortest credible path from "no" to "yes" for teams already on Nova. Scope it as an admin access security line item, not an identity platform initiative.
Buy-vs-build for one well-understood control. Enrollment (QR code), recovery codes, per-user enable/disable, and a config flag for enforcement arrive Nova-native, saving the team from writing custom middleware, a settings screen, and the associated tests. The honest reframing of the "buy" decision: with zero stars, zero dependents, and no visible maintenance, you are not buying a vendor dependency — you are acquiring source code and taking ownership of it. That changes the build-vs-buy math into "install, review, pin, fork, and staff ~1 day per Nova/Laravel upgrade cycle."
Roadmap scoping and portfolio placement. Forces an explicit answer to whether "admin MFA" is its own small milestone or bundled into a broader identity roadmap. It belongs only in an admin-access workstream — it is explicitly not end-user 2FA, SSO/SAML/OIDC, SCIM, WebAuthn/passkeys, device trust, or adaptive/risk-based access. Presenting it as part of an "identity" program overstates scope to stakeholders and sets up a credibility problem at the next review.
Feature prioritization under compliance pressure. Where customer trust reviews or internal policy create dated, concrete pressure to demonstrate MFA on privileged accounts, this compresses time-to-demonstrable-control dramatically and is easy to justify. Where that pressure is absent or soft, the low maintenance signal plus the ownership burden it creates — fork upkeep, admin-reset runbook, break-glass procedure, APP_KEY rotation coupling, helpdesk training — argue for deferring until the pressure is real.
Use-case validation / fit gating. Strong fit: a team already running Laravel Nova for internal access, on a standard session guard, with no existing MFA. Poor fit: multi-guard admin setups, apps already using Fortify/Jetstream on the same users model (duplicate enrollment UX and two contradictory sources of truth for "is this user MFA'd"), and organizations that require vendor SLA, certification, or a security review of upstream provenance.
Total-cost-of-adoption budgeting in the same decision as the install. Makes visible the work that isn't in the README but is required before enforcement: forking and pinning the source, writing and rehearsing the admin-reset / device-loss runbook, designating a platform owner, and adding a synthetic check that proves the challenge screen still enforces. This matters because the worst failure mode isn't a 500 — it's MFA that silently stopped enforcing weeks ago and nobody noticed.
Rollout design and risk management. Supports a staged, reversible launch: enroll platform engineers first, drill device loss on a real phone, soft-launch with enforcement off and an exposure dashboard, then enforce and watch the challenge-endpoint error rate. Also surfaces that the enforcement config flag is not a live rollback lever if the deploy pipeline runs config:cache — decide deliberately whether rollback means a redeploy or a runtime DB-backed setting.
Consider it when:
web guard, a single users model, no existing MFA on that model, and Laravel/Nova versions you're willing to pin as an explicitly tested pair.APP_KEY rotation procedure if the TOTP secret is stored under an encrypted cast.Look elsewhere when:
web, or user resolution is tenant-scoped, assume this needs a spike before it needs a decision. Don't adopt on the assumption that it just works.Also treat as decision-blocking unknowns to resolve before commitment: whether the TOTP secret is encrypted (and therefore coupled to APP_KEY rotation), whether the middleware fails open or closed on missing/null/errored state, whether the challenge endpoint is rate-limited, and whether enforcement actually covers every Nova entry point — custom tools, package-registered routes, and especially impersonation.
One-liner for executives: "A small, free Laravel Nova add-on that puts an authenticator-app second step on the admin panel, so we can answer 'is MFA enforced on privileged access?' with a yes — in days, not a quarter. It is a gap-filler, not an identity strategy, and we will own the code."
What it does. Adds TOTP two-factor authentication to Nova: users scan a QR code with any authenticator app, confirm a code, and receive recovery codes. There's a native security settings screen, per-user enable/disable/reset, and a config switch to enforce enrollment. It is scoped to Nova — it does not touch customer-facing login.
Why now (the business case). Administrative accounts are where the most sensitive data is reachable and where audits, security questionnaires, and customer trust reviews focus. This closes the "MFA on admin access" finding quickly and cheaply, and the result is demonstrable in a review — screenshots, an enforcement flag, and a test that proves the challenge blocks the dashboard.
What it costs — be explicit, this is the honest part. License cost is zero; ownership cost is not. Expect: a fork and pin into our own registry (upstream is a single-maintainer package with no visible adoption), roughly one engineer-day per Nova/Laravel upgrade to keep it working, an admin reset / break-glass procedure the other super-admin can run, helpdesk triage steps for lost devices, and a synthetic check that alerts if enforcement silently stops. If the TOTP secret is encrypted, APP_KEY rotation becomes a mass-lockout event and needs a written procedure before we enforce.
What it is not. Not SSO, not SCIM, not passkeys, not adaptive access, not customer MFA. Positioning it as an "identity" investment will mislead the board and undercut the next roadmap conversation. It's a targeted control on one surface.
Ask. Approve a time-boxed pilot in staging: fork, pin, and review the source; enroll two engineers; rehearse device loss and the reset runbook; verify fail-closed behavior on missing/null/error state and coverage across all Nova entry points including impersonation. Then return with a go/no-go on production enforcement and a named owner. Explicitly do not turn enforcement on in production until the reset runbook has been executed end to end.
For engineering, the three things that will bite us: (1) config caching means the enforcement flag isn't a live rollback lever — decide now whether rollback is a redeploy or a runtime setting; (2) fail-open is the real risk, so negative tests matter more than happy-path ones; (3) any route that authenticates a Nova user without passing the challenge — custom tools, package routes, impersonation — is a bypass, so we audit our own route registrations, not just the package's.
How can I help you explore Laravel packages today?