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

Authy Laravel Package

laravel-notification-channels/authy

Send Authy push notifications and verification codes from Laravel. This channel integrates Twilio Authy with Laravel's notification system, letting you deliver one-time passwords and approval requests through a simple notification class.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The package is a delivery adapter, not an identity system. It slots into Laravel's existing notification pipeline as one more channel class, which means it inherits queueing, ShouldQueue, rate-limit middleware, Notification::fake(), and your existing audit/notification-logging path rather than introducing a parallel mechanism. That is a genuinely good architectural fit for a Laravel codebase already using Notifiable models — the integration surface is one toAuthy() method, one routeNotificationForAuthy() method, and one config file.

The critical architectural caveat is that the package is roughly half of an MFA feature. It sends challenges. It does not verify returned codes, enforce attempt limits, track session state, rate-limit, or manage fallback factors. Those are the security-critical halves, and they are ours to build. The correct architecture is to treat the package as an implementation detail behind a first-party VerificationService interface from day one — send on one side, verify against the Authy check endpoint on the other — so the package is replaceable without touching call sites. If we instead let AuthyChannel leak into controllers and Livewire components, we've coupled our security surface to an unmaintained MIT package with 57 stars.

Integration feasibility. Low build cost, moderate total cost. Composer install, config publish, AUTHY_KEY in .env, service provider discovered automatically. The non-obvious prerequisite is provisioning: the channel routes by Authy ID, not phone number. Every user needs an Authy ID created and persisted before a single notification works, which means a schema migration, a registration-path change, and a backfill command for existing users. That backfill is the real scheduling item — it gates any rollout to the existing user base.

Technical risk. Four risks dominate, in order:

  1. Vendor EOL. Twilio has signaled Authy API deprecation in favor of Twilio Verify. This is the risk with no in-app signal — the integration works perfectly until it doesn't. Adopting Authy is a bet against the vendor's own roadmap, defensible only as a tactical move with a funded migration already scoped.
  2. Ecosystem trust. 57 stars, 0 dependents, single maintainer. There is no production-validation signal to point at in a security review. The answer must be a fork plan, not reassurance. The mitigating factor is that the whole channel is one small class plus a message builder — a competent Laravel dev can repoint it in an afternoon.
  3. Fire-and-forget semantics. The notification carries no state; Authy generates and holds the token. You cannot "resend the same code," every send is a new challenge. This is a UX constraint that must be designed around, not patched over.
  4. Queue retries re-send real tokens. A retried queued notification dispatches a second SMS — real money, and a user now holding two codes. $tries = 1 is mandatory, not a tuning parameter.

Adjacent risk: exceptions propagate out of notify(). A vendor 5xx during login becomes a 500 to the end user unless we wrap it. And nothing in the package prevents SMS pumping or toll fraud — per-user attempt caps, velocity rules, and Twilio-side spend alerting are entirely ours.

Key questions for the team before committing:

  • Are we already a Twilio/Authy customer with contract, credentials, and billing in place? If yes, this is a sprint-sized deliverable. If no, the real decision is vendor selection, and Authy is the wrong default given its EOL.
  • Does the package's composer.json support our Laravel/PHP version, verified against the last commit date rather than assumed? Does it pin twilio/sdk in a way that conflicts with our existing SDK dependency?
  • Who owns the verification half — attempt limits, session flag, authy_verified_at, rate limiter — and is that estimated and scheduled, or is it hiding inside the MFA estimate?
  • What is our fallback factor when a user has no authy_id or Authy is down? If the answer is "hard failure at login," we have built an outage amplifier.
  • Is passkeys/WebAuthn on the horizon? If enterprise questionnaires are heading toward phishing-resistant auth, OTP-only is a dead end and we should say so now rather than after the build.

Integration Approach

Stack fit. Requires a Laravel app using the native notification system with Notifiable models. Composer install with package discovery — no config/app.php registration. The entire configuration surface is config/authy.php plus AUTHY_KEY. Provisioning the Authy ID is the first real work: a nullable unique authy_id column on users (plus any other notifiable model that needs verification), populated on registration via the Authy register call, and exposed to the pipeline through routeNotificationForAuthy(): ?string.

The single most common integration bug is returning $this->phone from that route method instead of the Authy ID. It produces a valid-looking call that Authy rejects with an opaque error. Call this out in the PR review checklist explicitly.

Compatibility. Two dimensions to verify rather than assume: Laravel/PHP version support against composer.json and the last commit date, and twilio/sdk pin conflicts with anything already in our dependency tree. Pin the package version and treat upstream updates as frozen rather than expected — this is a fork-if-you-need-changes dependency, not a track-the-release-notes dependency.

Migration path. Two tracks, and they should be planned together:

  • Adopting Authy: ship the channel behind VerificationService, run a provisioning backfill artisan command for existing users, detect null/stale IDs on the login path, and degrade to a fallback factor (email OTP or TOTP) rather than hard-failing.
  • Leaving Authy: only VerificationService's implementation changes. The interface, the rate limiter, the session flag, the notification classes, and every call site stay put. If we get the seam right, the migration to Twilio Verify is an afternoon of work plus a credential swap. If we get it wrong, it's a re-implementation.

Sequencing. Roughly an afternoon to a token on a phone; 3–5 days to production-worthy. Order of work:

  1. Vendor diligence and EOL date on the roadmap before code — this determines whether we're doing this at all.
  2. Install, config, AUTHY_KEY in every environment including staging (a missing staging key fails silently and uniformly).
  3. Schema migration + registration-path provisioning + backfill command.
  4. routeNotificationForAuthy() and one notification class for the first use case — login step-up MFA, not signup verification or password reset. Login MFA is the shortest path to a security review clearance.
  5. VerificationService implementation: check endpoint, RateLimiter at 5 attempts / 10 minutes keyed on user:{id}, authy_verified_at, short-lived signed session flag.
  6. Fallback and channel routing policy encoded in one place.
  7. database channel added to via() for a free delivery audit record.

Channel strategy without a second integration. Because SMS, voice, and push share one interface, fallback is plain PHP — push for push-enabled users, SMS for web-only, voice after repeated SMS failures. Encode the ordering in one location: push is effectively free per attempt, SMS is metered, voice is materially more expensive. That's a cost decision as much as a UX one.

Operational Impact

Maintenance. Low ongoing code maintenance, high ongoing ownership awareness. The package is ~one class, MIT-licensed, and we should treat it as frozen — pin it and don't chase upstream. What requires real maintenance is everything around it: the VerificationService implementation, the rate limiter, the provisioning backfill, fallback logic, and the vendor relationship. Budget the EOL calendar reminder at adoption time, not at sunset; the failure mode here has zero in-app signal.

Support. No SLA, no enterprise support, no security questionnaire answered by the package author. Our support path splits cleanly: Twilio supports the Authy service, our team supports the adapter. For a security review, the honest framing is "MIT connector, one class, forkable in an afternoon, vendor is Twilio" — and back it with the actual fork plan. Do not offer reassurance without the plan.

Support-ticket volume will also come from UX, not just outages: users who received a code, missed it, and expect a "resend the same code" button that cannot exist. Design the copy and the flow around new-challenge-every-send.

Scaling. Scales the way Laravel queues scale — ShouldQueue keeps the vendor round-trip off the request path, which is the main throughput concern. Two real scaling constraints are commercial, not technical:

  • Cost shape. Push is effectively free, SMS metered, voice materially more expensive. At volume, the routing policy is a cost-control mechanism. Model per-verification pricing and set a spend cap before launch.
  • Fraud exposure. Nothing in the package prevents SMS pumping or toll fraud. Per-user attempt caps, IP/geo velocity rules, and Twilio-side spend alerting are ours. A leaked endpoint that triggers SMS with no cap is a direct billing incident, and it is the failure mode most likely to actually happen.

Failure modes to design against, in priority order:

Failure User-visible symptom Mitigation
Wrong route column (phone, not Authy ID) Valid-looking call, opaque vendor rejection Explicit PR checklist item; test the missing-authy_id branch
AUTHY_KEY missing in staging/env Uniform silent failure for all users Config check at boot; alert on aggregate delivery-failure rate, not individual errors
Vendor 5xx/timeout during login 500 returned to user try/catch around notify(), log, degrade to fallback factor
Queue retry Second SMS, second charge, user holds two codes $tries = 1 or tight retryUntil; handle failure as a manual re-send prompt
config:cache staleness Config edits have no effect, ~1 hour lost in staging Documented in runbook; re-cache step in deploy
Notification::fake() masking breakage Green test suite, broken prod key One integration test or scheduled smoke check against the real sandbox
Null/stale authy_id at login User locked out Backfill command + graceful fallback factor (email OTP/TOTP)
Authy API EOL Total, sudden loss of verification Migration ticket scoped and funded on day one

Ramp-up. Plan on an afternoon to get a token onto a phone and 3–5 days to make it production-worthy, plus a named workstream for the verification half. That workstream is the thing that makes MFA look cheaper and smaller than it is if left implicit — scope it explicitly or the estimate will be wrong by the largest single component.

Ramp order should be: one engineer owns VerificationService and the seam; login step-up MFA ships first as a time-boxed increment to clear the security review or enterprise blocker; signup verification, account recovery, and re-verification before sensitive changes (password, email, payout details, admin grants) follow on the same primitive. Those recovery and step-up flows are frequently higher value than login MFA on both support-ticket volume and fraud loss, and they cost almost nothing extra once the seam exists.

The PM framing for stakeholders: this is a small, free connector that turns "gate login behind two-factor" into a sprint-sized deliverable and defers the platform work — a legitimate unblock-the-deal trade, provided the migration to Twilio Verify is scoped and funded in the same planning cycle rather than discovered at sunset. Scrutinize the vendor contract, pricing, and EOL timeline. The package is replaceable; the vendor decision is not.

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