Why Laravel Rebel
The short version: there is no drop-in package that gives a Laravel app a first-class NIST
assurance model, GDPR-safe keyed hashing with rotation, a redacting audit trail,
per-action step-up with PSD2/SCA, and anti-fraud multi-provider channels — all self-hosted,
all composable. Rebel is that layer.
This page is for the person doing the evaluation. It lays out, matrix by matrix, exactly where Rebel
wins, where the alternatives are genuinely fine, and where you’d be reinventing a very subtle wheel.
We keep it honest. Fortify, the Spatie packages and the hosted IdPs are excellent at what they
do. Rebel doesn’t compete on their turf — it provides the assurance/audit/hashing/channel substrate
they don’t, and stays unopinionated so you can layer them (or Fortify itself, via bridge-fortify)
on top.
The five moats
These are the capabilities that are hard to copy and that compound across the whole suite.
A typed NIST AAL/AMR model with a satisfies() guard. An email-OTP session (AAL1) cannot
satisfy an action that demands a phishing-resistant passkey. This is a framework invariant, not a
convention you have to remember in every controller.
IP, User-Agent and identifiers are stored as keyed HMACs with a versioned pepper and
rotation. You can rotate the secret without losing the ability to match historical records — and
there is no cleartext PII to leak in the first place.
A Redactor removes OTPs, recovery codes, provider tokens and webhook secrets before the event
is written. Audit is sync or queue (Horizon-ready), always persisted to rebel_auth_events —
never just the session.
Per-action step-up with dynamic linking: the confirmation is bound to amount + payee. Change the
order total and it expires. This is exactly what EU SCA requires for B2B credit orders — and almost
nobody ships it.
The channel layer adds IRSF / toll-fraud defenses, cooldowns, multi-dimensional rate limiting and
provider fallback on top of Twilio/Vonage/Bird — with full delivery-receipt telemetry feeding the
admin panel.
Matrix 1 — Rebel vs. Fortify (framework-native)
Fortify is the right baseline: it’s Laravel’s own auth scaffolding. Rebel is built to sit on top
of it, not replace it.
| Capability | Laravel Rebel | Fortify alone |
|---|---|---|
| Login / registration / password reset screens | via bridge-fortify |
✅ |
| TOTP 2FA / passkeys | ✅ (as step-up drivers) | ✅ |
| Passwordless email-OTP login (anti-enumeration, rate-limited) | ✅ | ❌ |
| First-class NIST AAL/AMR assurance model | ✅ | ❌ |
| Per-action step-up (not just per-login) | ✅ | ❌ |
| PSD2 / SCA dynamic linking | ✅ | ❌ |
| SMS / WhatsApp / voice channels with fallback + anti-fraud | ✅ | ❌ |
| GDPR-safe keyed-HMAC PII storage with rotation | ✅ | ❌ |
| Audit trail with automatic secret redaction | ✅ | ❌ |
| Multi-tenant isolation | ✅ | ❌ |
| Session/device governance + logout-everywhere | ✅ | ➖ |
| Web admin panel + control-plane API | ✅ | ❌ |
| Anomaly detection + AI copilot | ✅ | ❌ |
Verdict: keep Fortify for the screens and credential storage. Add Rebel for everything an
enterprise product needs around them.bridge-fortifywires the two together and maps Fortify
events into the Rebel audit trail.
Matrix 2 — Rebel vs. rolling it yourself
The honest alternative most teams reach for: build the primitives by hand. Here’s what that actually
costs you, line by line.
| Capability | Laravel Rebel | Hand-rolled |
|---|---|---|
| OTP flow with anti-enumeration & atomic single-use verify | ✅ | ⚠️ easy to get subtly wrong |
| Multi-dimensional rate limiting (IP + identifier + tenant + purpose) | ✅ | ⚠️ rarely done fully |
| Typed assurance model that blocks weak factors on strong actions | ✅ | ❌ usually a boolean |
| Keyed HMAC hashing with versioned pepper + rotation | ✅ | ❌ |
| Constant-time comparison everywhere it matters | ✅ | ⚠️ |
| Audit trail with secret redaction + country/device enrichment | ✅ | ❌ |
| PSD2/SCA dynamic linking | ✅ | ❌ |
| Provider fallback + toll-fraud/IRSF defense | ✅ | ❌ |
| Tested to PHPStan max, Pest, PHP 8.3–8.5 × Laravel 12/13 | ✅ | up to you |
| Maintenance, CVE response, standards drift (NIST/PSD2) | maintained | on you, forever |
Verdict: you can build this. The question is whether you want to own the edge cases,
the rotation strategy, the redaction rules and the standards tracking for the life of the product.
Matrix 3 — laravel-rebel-core vs. the substrate alternatives
The core specifically is a shared contracts + assurance + hashing + audit layer. Nothing
mainstream occupies that exact slot.
| Capability | Rebel Core | Hand-rolled primitives | Fortify | Spatie permission / multitenancy |
|---|---|---|---|---|
| First-class NIST AAL/AMR assurance model | ✅ | ❌ | ❌ | ❌ |
satisfies() guard (blocks email-OTP on phishing-resistant purposes) |
✅ | ❌ | ❌ | ❌ |
| Keyed HMAC hashing with versioned pepper + rotation | ✅ | ❌ | ❌ | ❌ |
| Audit trail with automatic secret redaction | ✅ | ❌ | ❌ | ❌ |
| GDPR-safe IP/UA stored as keyed HMAC (never cleartext) | ✅ | ❌ | ❌ | ❌ |
Web/mobile LoginResult + Sanctum TokenPair contract |
✅ | ❌ | ❌ | ❌ |
| Per-tenant isolation trait + safe queue-worker reset | ✅ | ❌ | ❌ | ✅ |
PSR-20 testable Clock for OTP/step-up expirations |
✅ | ❌ | ❌ | ❌ |
| Stable contracts to swap implementations | ✅ | ❌ | ❌ | ❌ |
validate-config fail-fast command for CI |
✅ | ❌ | ❌ | ❌ |
| Zero hard dependency on Fortify/Twilio/AI | ✅ | ✅ | ❌ | ✅ |
| Login / registration / password-reset screens | ❌ (by design) | ❌ | ✅ | ❌ |
Legend: ✅ built-in · ➖ partial · ❌ not available · ⚠️ possible but error-prone.
Matrix 4 — Rebel vs. hosted IdPs (Auth0 / Okta / WorkOS)
Hosted identity providers are great when you want to outsource identity. Rebel is for teams that
want to own it — inside their own Laravel app and database.
| Dimension | Laravel Rebel | Hosted IdP |
|---|---|---|
| Where users & audit live | your DB, your control | vendor cloud |
| Self-hosted / data residency | ✅ full | ➖ region tiers, extra cost |
| Per-MAU pricing | none | grows with users |
| Native to your Laravel domain model | ✅ | ➖ via API/webhooks |
| NIST AAL/AMR assurance you can reason about in code | ✅ | ➖ opaque |
| PSD2/SCA dynamic linking for B2B credit orders | ✅ | ➖ rarely |
| Channel anti-fraud you can tune | ✅ | ➖ vendor-managed |
| Vendor lock-in / migration risk | low (MIT, your code) | high |
| Enterprise SSO (SAML/OIDC IdP federation) | ➖ bring your own | ✅ |
| Offloaded ops / SOC2 by the vendor | ❌ (you run it) | ✅ |
Verdict: choosing Rebel over a hosted IdP is choosing ownership and cost control over
outsourced operations. If you need to federate dozens of external enterprise IdPs, a hosted
IdP still wins on that one axis — and you can run both.
Matrix 5 — Rebel vs. commerce-platform auth (e.g. Shopify)
A common reference point for “passwordless that just works”. The difference is control.
| Capability | Laravel Rebel | Shopify (hosted commerce) |
|---|---|---|
| Passwordless email-OTP login | ✅ | ✅ |
| Self-host / own the auth internals | ✅ | ❌ black box |
| Extend / customize the assurance logic | ✅ | ❌ |
| Reuse the primitives in your own app | ✅ | ❌ |
| Keyed-HMAC PII storage you control | ✅ | ➖ hosted-only |
| PSD2/SCA dynamic linking you can wire to your flows | ✅ | ➖ |
| Runs on your stack (Laravel, your DB) | ✅ | ❌ |
Note: Shopify is a hosted, closed commerce platform — you can’t self-host it, extend its auth
internals, or reuse its primitives in your own Laravel app. It’s a black box you don’t control.
Matrix 6 — Rebel channels vs. a single-provider SMS SDK
Most teams start by calling the Twilio SDK directly. That’s fine until the first outage, the first
toll-fraud bill, or the first “why didn’t the code arrive?” support ticket.
| Capability | Rebel channels | Raw provider SDK |
|---|---|---|
| Send OTP / verification | ✅ | ✅ |
| Provider fallback (Twilio → Vonage → Bird) | ✅ | ❌ |
| Anti toll-fraud / IRSF defenses | ✅ | ❌ |
| Cooldown + multi-dimensional rate limiting | ✅ | ❌ |
| Signed delivery-receipt webhooks normalized across providers | ✅ | ➖ per-vendor |
| Cost / country / device telemetry into one audit trail | ✅ | ❌ |
| Swap or add a provider without touching call sites | ✅ | ❌ |
| Bot gate (Turnstile/reCAPTCHA/hCaptcha) before spending an SMS | ✅ | ❌ |
Verdict: the SDK sends a message; Rebel runs a resilient, audited, anti-fraud verification
channel. The cost difference shows up the first time a provider has a bad day.
Standards & compliance, by design
Rebel is built against recognized standards rather than retrofitted to them:
The AAL/AMR model: email-OTP = AAL1; SMS = “restricted”; only passkeys are phishing-resistant. The
satisfies() guard enforces it in code.
Dynamic linking binds confirmations to amount + payee for B2B credit orders. (It complements, not
replaces, your PSP’s 3DS2 for cards.)
IP/identifiers as keyed HMAC with key_version rotation, log redaction, and no PII in cleartext —
data-minimization built into the storage layer.
When Rebel might be overkill
Intellectual honesty cuts both ways. Reach for something simpler if:
- You have a tiny internal tool where Fortify alone (or even Laravel’s starter kits) is plenty.
- You want to fully outsource identity and are happy with a hosted IdP’s pricing and lock-in.
- You have no sensitive actions, no regulated payments, no SMS, and no compliance audit on the horizon.
Rebel earns its keep the moment you have real users, real money, real regulators, or real
attackers — which, for most products that grow, is sooner than you think.
Next steps
Convinced? Head to the Quickstart or the Install Matrix.
Still mapping the pieces? See the Package Map and
Capability Matrix. Want the theory? Read
Assurance Theory and the Risk Model.