laravel-rebel-channels
GitHub repository · Composer: padosoft/laravel-rebel-channels · MIT
One verification API, every provider behind it.
-channelsis the abstraction that routes
phone verification and message delivery across SMS, WhatsApp and voice — with provider fallback,
cooldown, multi-dimensional rate limiting and anti toll-fraud defenses baked in. Swap or add a
provider and your call sites never change.
This package defines the contract and the routing. The actual sending happens in a provider
package (-channel-twilio, -channel-vonage, -channel-bird) that plugs in behind it. Install at
least one provider to deliver anything.
What it is
-channels is the seam between “I need to verify this phone number” and “which vendor actually sent
the SMS.” It owns the decisions that should never be re-implemented per provider:
- a
VerificationRouterthat picks a provider, applies cooldown and rate limits, and falls back
to the next provider when one fails, - a
FraudGuardthat defends against toll-fraud / IRSF abuse before a single message is billed, - a registry of pluggable providers and delivery channels (
ProviderRegistry,
DeliveryChannelRegistry), - typed results (
VerificationResult,DeliveryResult) and enums (Channel,
VerificationStatus,DeliveryStatus) so every provider speaks the same language.
The problem it solves
A single-provider SMS SDK ties your whole auth flow to one vendor’s uptime, pricing and country
coverage — and gives you nothing against international revenue-share fraud, where an attacker pumps
OTPs to premium-rate ranges and you pay the bill. Switching providers later means rewriting call
sites. -channels inverts that: routing, fallback, cooldown, rate limiting and fraud defense live
once, above the provider, and vendors become interchangeable plug-ins.
What you get
| Area | What you get |
|---|---|
| Routing & fallback | VerificationRouter — selects a provider, retries with the next provider on failure, enforces cooldown. |
| Rate limiting | CacheRateLimiter — multi-dimensional limits to throttle abuse without blocking legitimate users. |
| Fraud defense | FraudGuard + FraudDecision — anti toll-fraud / IRSF gating before any message is billed. |
| Provider registry | ProviderRegistry, DeliveryChannelRegistry — register and resolve pluggable providers/channels. |
| Contracts | VerificationProvider, MessageDeliveryChannel — the two interfaces every provider implements. |
| Typed results | VerificationResult, DeliveryResult — never confuse a delivery outcome with authentication success. |
| Enums | Channel (SMS | WhatsApp | voice), VerificationStatus, DeliveryStatus. |
| Test doubles | FakeVerificationProvider, FakeMessageDeliveryChannel — verify your flows without sending a real OTP. |
When to use it
- You send phone/WhatsApp/voice OTPs and want vendor independence with automatic fallback.
- You need toll-fraud / IRSF protection and rate limiting in front of every provider, not bolted
on per vendor. - You’re writing a provider package and need the
VerificationProvider/MessageDeliveryChannel
contracts to plug into.
Worked example
composer require padosoft/laravel-rebel-channels
# plus at least one provider, e.g.:
composer require padosoft/laravel-rebel-channel-twilio
php artisan vendor:publish
A delivery result is not an authentication result. -channels keeps the two separate: a sent SMS
means the message went out; assurance is decided only when the user returns a valid code. Telemetry
for every send, delivery receipt, cost and country flows into the Rebel audit trail via the core
AuditLogger — never logging the OTP itself.
How it fits
-channels sits on top of laravel-rebel-core (it speaks the core’s contracts and feeds the audit
trail) and underneath the provider packages that implement actual delivery. The host app talks to the
router; the router talks to whichever provider is configured — and to the next one if that fails.
One single-provider SMS SDK can’t give you cross-vendor fallback, shared rate limiting and IRSF
defense in one place — see Why Rebel → “Rebel channels vs. a single-provider SMS SDK”.
Reference
Runtime files
src\Contracts\MessageDeliveryChannel.phpsrc\Contracts\VerificationProvider.phpsrc\Enums\Channel.phpsrc\Enums\DeliveryStatus.phpsrc\Enums\VerificationStatus.phpsrc\Fraud\FraudDecision.phpsrc\Fraud\FraudGuard.phpsrc\Results\DeliveryResult.phpsrc\Results\VerificationResult.phpsrc\Routing\DeliveryChannelRegistry.phpsrc\Routing\ProviderRegistry.phpsrc\Routing\VerificationRouter.phpsrc\Support\CacheRateLimiter.phpsrc\Support\NullBotProtection.phpsrc\Testing\FakeMessageDeliveryChannel.phpsrc\Testing\FakeVerificationProvider.phpsrc\RebelChannelsServiceProvider.php
Service providers
src\Contracts\VerificationProvider.phpsrc\Routing\ProviderRegistry.phpsrc\Testing\FakeVerificationProvider.phpsrc\RebelChannelsServiceProvider.php
Services and managers
src\Fraud\FraudGuard.phpsrc\Routing\DeliveryChannelRegistry.phpsrc\Routing\ProviderRegistry.phpsrc\RebelChannelsServiceProvider.php
Contracts
src\Contracts\MessageDeliveryChannel.phpsrc\Contracts\VerificationProvider.php
Controllers
None detected in the package tree.
Middleware
None detected in the package tree.
Models
None detected in the package tree.
Config
config\rebel-channels.php
Migrations
None detected in the package tree.
Routes
None detected in the package tree.
Commands
None detected in the package tree.
Composer requirements
| Dependency | Constraint |
|---|---|
illuminate/contracts |
`^12.0 |
illuminate/support |
`^12.0 |
padosoft/laravel-rebel-core |
^0.1 |
php |
^8.3 |
spatie/laravel-package-tools |
^1.92 |
Development requirements
| Dependency | Constraint |
|---|---|
larastan/larastan |
^3.0 |
laravel/pint |
^1.18 |
orchestra/testbench |
`^10.0 |
pestphp/pest |
^4.0 |
pestphp/pest-plugin-laravel |
^4.0 |
ADR
Problem: keep laravel-rebel-channels replaceable
Decision: document its public responsibility and use Rebel core contracts at integration boundaries.
Consequences: applications can adopt the package without coupling every other Rebel module to its internals.
Problem: package-specific behavior must remain auditable
Decision: all security-significant outcomes should emit or feed audit events through the core vocabulary.
Consequences: admin API, admin UI and AI guard can reason across packages without bespoke parsers for every provider.
Test and verification surface
tests\Feature\DeliveryChannelRegistryTest.phptests\Feature\FraudGuardTest.phptests\Feature\VerificationRouterTest.phptests\Pest.phptests\TestCase.php
Do not copy internal test-only classes into an application. Treat file lists as a source map for maintainers and auditors, not as an installation recipe by themselves.