Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nova Two Factor Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package is narrowly and correctly scoped: it adds a second factor to the Laravel Nova admin panel only, via a Nova tool page (enrollment QR, TOTP secret, recovery codes) plus a middleware layer on the Nova route group and a trait on the user model. For a team already running Nova as its back-office surface, this slots into existing architecture rather than introducing a new identity system — no IdP, no SAML/OIDC, no new service to operate. That is the core appeal: a small, well-understood control closing an "is MFA enforced on administrative access?" gap. It is explicitly not end-user authentication, SSO, SCIM, WebAuthn/passkeys, or adaptive access, and should not be positioned as a step toward those on the roadmap.

Integration feasibility. The install path is conventional and low-ceremony — composer require, publish, migrate, add a trait to User, register the tool in NovaServiceProvider::tools(), and set an enforce flag. The real integration work is not installation but the surrounding workflow: onboarding nudges (the tool is opt-in and buried in the sidebar until enforcement is on), a recovery-code capture and regeneration story, an audit trail we own (the package's per-user enable/disable is a UI convenience, not a log), and a break-glass admin reset path the package does not provide. Estimated engineering effort is small for the happy path and materially larger for the reset runbook, testing, and rollout rehearsal.

Technical risk. This is a security control sourced from an unmaintained-looking dependency: zero stars, zero dependents, and no visible adoption. In an auth path, that means upstream deletion or a force-push is a live risk, so the effective decision is "review, pin, fork, and own" rather than "buy." Three risks dominate beyond supply chain:

  • Fail-open behaviour. A 500 is loud; a silently skipped challenge is not. The fail-open/fail-closed logic lives entirely in the middleware's catch blocks, so that class must be read line by line before enforcement is considered.
  • APP_KEY rotation coupling. If the TOTP secret is stored with an encrypted cast, a routine key rotation invalidates every enrolled admin simultaneously, mid-incident. This must be confirmed from the migration before enrollment scales.
  • Coverage gaps. Enforcement must be verified against every Nova entry point, not just /nova/login — custom tools, package routes on the Nova middleware group, actions, and impersonation. Any route that authenticates a Nova user without clearing the challenge is a bypass.

Secondary risks: no built-in rate limiting on a six-digit code (we add RateLimiter ourselves, 5 attempts / 1-minute decay, keyed on user + IP, with the counter not resetting on a correct password plus bad code); config cache making the enforce flag inert until the next deploy, which breaks it as a rollback mechanism; and duplicate enrollment UX if Fortify/Jetstream already writes two_factor_secret to the same model.

Key questions for the review. Which Nova guard does the middleware resolve, and is our Nova guard web? Is the secret encrypted, and what is our key-rotation procedure if it is? What is the exact session key asserted by the middleware (needed for tests)? Does a "remember this device" cookie exist, and what is its lifetime and revocation story? Which Nova-registered routes authenticate users outside the challenge? Who on the platform team owns this dependency, and does a second super-admin with 2FA enabled exist to invoke a reset?

Integration Approach

Stack fit. Appropriate only where the stack matches the stated profile: Laravel 9–10 with Nova already serving internal/admin access, a standard session guard, and no existing MFA on the same user model. Poor fit for multi-guard or tenant-scoped user resolution (needs a spike, not an assumption), and a hard no where the organization requires vendor SLA and certification — there is no vendor to call.

Migration path. There is no data migration burden — this is greenfield enrollment, not a cutover. The migration path that matters is the enforcement path: off → on → (simulated incident) → off in staging, rehearsed at least once so rollback is an action rather than an improvisation. php artisan config:clear is part of that rehearsal, given config cache. Before enforcement, the plan should include a database-driven enforcement setting or an explicit config-cache rebuild step in the rollback runbook — decide which, deliberately.

Compatibility. Pin the package version and the Nova version as an explicit, tested pair in the dependency register; thin packages typically break on the next Nova/Laravel cycle, not on install day. Vendor or fork into our own registry before enforcement is switched on. Budget roughly one engineering day per upgrade cycle to carry the fork, plus the risk of a rushed patch on security-sensitive code.

Sequencing. The ordering is non-negotiable and should be written into the delivery plan as gates:

  1. Read the four files first — migration (column types, encryption), routes (which middleware group), middleware (fail-open paths), config (the knobs we can actually rely on).
  2. Enroll a single engineer in staging; log out, log in with a code, delete the 2FA row, confirm re-challenge.
  3. Enroll a second admin so no one is a single point of lockout.
  4. Put the package behind a TwoFactorProvider interface with exactly one implementation calling Visanduma\NovaTwoFactor — this is the highest-value day-to-day decision, because replacing the package or patching a Nova break becomes one class, not every call site.
  5. Build the artisan reset command and gated Nova action (super-admin only, explicit --force plus reason, logged with operator, subject, timestamp, incident reference).
  6. Write the negative-assertion feature test — an enrolled or non-enrolled session must not reach /nova before a valid code is posted — and keep it in our repo, not the package's.
  7. Enforce in staging with comms on and an enrollment dashboard showing who remains exposed; then production.

Operational Impact

Maintenance. An unowned auth dependency is an unmaintained control. This needs a named owner on the platform team, a forked source in our registry, a pinned version pair, and a standing line item for upgrade tax. The package's UI is unlikely to evolve; our fork will accumulate the patches.

Support. Two support surfaces are created and neither is delivered by the package: helpdesk triage for device loss (scripted, with an escalation path to the break-glass operator) and the reset runbook itself, tested end to end before enforcement. The reset command is only useful if someone other than the locked-out user can run it, which implies a second super-admin with 2FA enabled and a documented contact.

Scaling. Enrollment scales trivially; the operational cost is per-user support, not per-request traffic. Two scaling limits to note: the control is admin-only, so it does not scale to or substitute for customer-facing MFA; and recovery-code handling (shown once, regeneration path) is the most likely source of recurring tickets. Rate limiting on the challenge endpoint must be added by us and reviewed as enrollment grows.

Failure modes. Rank them by silence, not by severity of error:

  • Silent non-enforcement — the worst outcome is MFA that stopped enforcing weeks ago and nobody noticed. Mitigate with a scheduled synthetic check that logs in as a known enrolled test account and asserts the challenge redirect; our own test suite will drift, a check against the running app will not.
  • Fail-open under exception — missing row, null secret, malformed recovery code, null config() after a cache warm, exception in middleware. Each must be tested deliberately; each must not reach the dashboard.
  • Mass lockout on APP_KEY rotation — confirm encryption, then pre-plan either column re-encryption as a rotation step or a reset-all-and-re-enroll script. key:generate should never be run casually on an enforced install.
  • Bypass via uncovered Nova routes, especially impersonation — decide explicitly whether an impersonated session must clear 2FA and encode that decision.
  • Upstream disappearance or force-push — mitigated only by the fork.

Ramp-up. Roughly a week of elapsed time for a competent Laravel engineer, dominated by reading the middleware, writing the seam and reset command, and the staging rehearsal — not by installation. Add helpdesk training on device-loss triage and 48 hours of watching challenge-endpoint error rate immediately after enforcement. The decision framing for stakeholders: this is a fast, cheap way to demonstrate MFA on privileged accounts where compliance pressure exists, and a deferred item where it does not — because the true cost of adoption is the ownership burden (fork upkeep, reset runbook, break-glass coverage, key-rotation coupling), not the composer require.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource