PHPackages                             padosoft/laravel-rebel-bridge-laragear-2fa - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. padosoft/laravel-rebel-bridge-laragear-2fa

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

padosoft/laravel-rebel-bridge-laragear-2fa
==========================================

Bridge between laragear/two-factor and Laravel Rebel: exposes TOTP as an AAL2 step-up driver, integrates recovery codes, and emits full audit telemetry into the Rebel audit trail. Part of padosoft/laravel-rebel-\*.

v0.1.1(1mo ago)02MITPHPPHP ^8.3CI failing

Since Jun 4Pushed 1mo agoCompare

[ Source](https://github.com/padosoft/laravel-rebel-bridge-laragear-2fa)[ Packagist](https://packagist.org/packages/padosoft/laravel-rebel-bridge-laragear-2fa)[ Docs](https://github.com/padosoft/laravel-rebel-bridge-laragear-2fa)[ RSS](/packages/padosoft-laravel-rebel-bridge-laragear-2fa/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (2)Dependencies (24)Versions (4)Used By (0)

> Official documentation:

[![Laravel Rebel](resources/screenshoots/Laravel-Rebel-banner.png)](resources/screenshoots/Laravel-Rebel-banner.png)

laravel-rebel-bridge-laragear-2fa
=================================

[](#laravel-rebel-bridge-laragear-2fa)

**TOTP step-up authentication for Laravel Rebel, powered by laragear/two-factor.**

[![Latest Version on Packagist](https://camo.githubusercontent.com/0466f1687da7d87bdabaf5de14ff9fb68f8093ce227328f5adb47d52cce0f81b/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f7061646f736f66742f6c61726176656c2d726562656c2d6272696467652d6c617261676561722d3266612e737667)](https://packagist.org/packages/padosoft/laravel-rebel-bridge-laragear-2fa)[![CI](https://github.com/padosoft/laravel-rebel-bridge-laragear-2fa/actions/workflows/ci.yml/badge.svg)](https://github.com/padosoft/laravel-rebel-bridge-laragear-2fa/actions/workflows/ci.yml)[![PHPStan Level Max](https://camo.githubusercontent.com/b6d441ad4fe8332cb16c72aa27f22cc685181dfd74ae34964afc92c6c1146b3c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048505374616e2d6c6576656c2532306d61782d627269676874677265656e2e737667)](https://phpstan.org/)[![License: MIT](https://camo.githubusercontent.com/fdf2982b9f5d7489dcf44570e714e3a15fce6253e0cc6b5aa61a075aac2ff71b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d79656c6c6f772e737667)](LICENSE)

---

What this package does
----------------------

[](#what-this-package-does)

This package bridges **laragear/two-factor** — the popular on-premises TOTP library for Laravel — into the **Laravel Rebel** enterprise authentication control plane.

It exposes laragear's Time-based One-Time Password (TOTP) two-factor authentication as a Rebel **step-up driver**. Once installed, a Rebel step-up policy can require a user to confirm a TOTP code (or a single-use recovery code) before accessing a sensitive resource. The result is stored in the Rebel audit trail with full compliance metadata (AAL2, AMR, channel, purpose) so your dashboards, funnel analytics, and GDPR audit explorer all populate correctly.

### Where it fits in the Laravel Rebel suite

[](#where-it-fits-in-the-laravel-rebel-suite)

```
+------------------------------------------+
|            Your Application              |
|  Route::middleware('rebel.stepup:pay')   |
+--------------------+---------------------+
                     | requires step-up
+--------------------v---------------------+
|       laravel-rebel-step-up              |
|  DriverRegistry   [
    Padosoft\Rebel\Bridge\Laragear2fa\RebelLaragear2faBridgeServiceProvider::class,
],
```

### 2. Install laragear/two-factor

[](#2-install-larageartwo-factor)

```
composer require laragear/two-factor
```

Publish and run laragear's migration:

```
php artisan vendor:publish --provider="Laragear\TwoFactor\TwoFactorServiceProvider" --tag="migrations"
php artisan migrate
```

This creates the `two_factor_authentications` table (laragear stores 2FA data in a related table, not on the users table itself).

### 3. Add the trait to your User model

[](#3-add-the-trait-to-your-user-model)

```
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laragear\TwoFactor\TwoFactorAuthentication;
use Laragear\TwoFactor\Contracts\TwoFactorAuthenticatable;

class User extends Authenticatable implements TwoFactorAuthenticatable
{
    use TwoFactorAuthentication;
    // ...
}
```

### 4. Publish the bridge config (optional)

[](#4-publish-the-bridge-config-optional)

```
php artisan vendor:publish --tag="rebel-bridge-laragear-2fa-config"
```

---

Configuration
-------------

[](#configuration)

After publishing, edit `config/rebel-bridge-laragear-2fa.php`:

KeyDefaultEnv varDescription`drivers.laragear_totp``true``REBEL_LARAGEAR_DRIVER_TOTP`Register the TOTP step-up driver into the Rebel `DriverRegistry`. Set to `false` to completely disable TOTP step-up without uninstalling the package. The driver is only registered when this is `true` AND laragear is installed.`use_recovery_codes``true``REBEL_LARAGEAR_USE_RECOVERY_CODES`Accept a single-use recovery code as an alternative to a TOTP code. Set to `false` to restrict step-up strictly to live TOTP codes (e.g. for high-security contexts where recovery codes are managed out-of-band).---

How it works — step by step
---------------------------

[](#how-it-works--step-by-step)

```
1. User is authenticated and tries to access a sensitive route.
2. The rebel.stepup:pay middleware checks if the purpose 'pay' is confirmed.
3. It is not — the step-up manager picks the laragear_totp driver.
4. start() returns null — no server-side challenge. The user opens their
   authenticator app and reads the current 6-digit code.
5. The user submits the code.
6. verify() calls LaragearTwoFactorValidator which calls:
     $user->validateTwoFactorCode($code, useRecoveryCodes: false)
   - TOTP match: returns true. Laragear checks the code against the user's TOTP
     secret, using a cache to prevent replay within the same 30-second window.
   - TOTP miss: if use_recovery_codes is true, calls validateTwoFactorCode again
     with useRecoveryCodes: true, which checks the single-use recovery code list
     and marks the matching code consumed on match.
7. On success: AuditLogger records 'stepup.laragear_totp.verified' (and optionally
   'stepup.laragear_totp.recovery_code.used') to rebel_auth_events.
8. On failure: AuditLogger records 'stepup.laragear_totp.failed'.
   The step-up manager rejects the request. Any Throwable is caught and treated
   as failure (fail-closed).

```

---

Usage examples
--------------

[](#usage-examples)

### Example 1 — Protecting a route with step-up middleware

[](#example-1--protecting-a-route-with-step-up-middleware)

```
// routes/web.php
Route::post('/account/payment-method', [PaymentController::class, 'store'])
    ->middleware('auth', 'rebel.stepup:change-payment');
```

Define the purpose in your step-up config:

```
// config/rebel-step-up.php
'purposes' => [
    'change-payment' => [
        'required_assurance' => 'aal2',
        'drivers' => ['laragear_totp'],
        'always_require' => true,
    ],
],
```

### Example 2 — Manual step-up in a controller

[](#example-2--manual-step-up-in-a-controller)

```
use Padosoft\Rebel\StepUp\RebelStepUp;
use Padosoft\Rebel\StepUp\StepUpContext;
use Padosoft\Rebel\Core\Context\SecurityContext;
use Padosoft\Rebel\Core\Contracts\KeyedHasher;

class TransferController extends Controller
{
    public function confirm(Request $request, RebelStepUp $stepUp, KeyedHasher $hasher): JsonResponse
    {
        $ctx = new StepUpContext(
            subject: $request->user(),
            purpose: 'bank-transfer',
            security: SecurityContext::fromRequest($request, $hasher),
        );

        // Start the step-up challenge (returns null for TOTP — no server-side challenge).
        $start = $stepUp->start($ctx);

        // ... send the challengeId back to the browser, user enters their TOTP code ...

        // When the user submits the code:
        $result = $stepUp->confirm($start->challengeId, $request->input('code'), $ctx);

        if (! $result->success) {
            return response()->json(['error' => 'Step-up failed. Please check your authenticator app.'], 403);
        }

        // Proceed with the sensitive operation.
        return response()->json(['status' => 'transferred']);
    }
}
```

### Example 3 — Mobile / Sanctum API with step-up check

[](#example-3--mobile--sanctum-api-with-step-up-check)

```
use Padosoft\Rebel\StepUp\RebelStepUp;
use Padosoft\Rebel\StepUp\StepUpContext;

class AccountController extends Controller
{
    public function deleteAccount(Request $request, RebelStepUp $stepUp, KeyedHasher $hasher): JsonResponse
    {
        $ctx = new StepUpContext(
            subject: $request->user(),
            purpose: 'delete-account',
            security: SecurityContext::fromRequest($request, $hasher),
        );

        if (! $stepUp->isConfirmed($ctx)) {
            return response()->json([
                'step_up_required' => true,
                'driver' => 'laragear_totp',
                'message' => 'Please confirm with your authenticator app to continue.',
            ], 403);
        }

        // Safe to proceed.
        $request->user()->delete();

        return response()->json(['status' => 'account deleted']);
    }
}
```

### Example 4 — Using the FakeTwoFactorValidator in feature tests (offline, no DB)

[](#example-4--using-the-faketwofactorvalidator-in-feature-tests-offline-no-db)

```
use Padosoft\Rebel\Bridge\Laragear2fa\Contracts\TwoFactorValidator;
use Padosoft\Rebel\Bridge\Laragear2fa\Testing\FakeTwoFactorValidator;

beforeEach(function (): void {
    $this->user = User::factory()->create();

    // Bind the fake: this user has 2FA enabled, '123456' is the valid TOTP code.
    app()->instance(TwoFactorValidator::class, new FakeTwoFactorValidator(
        enabled: [(string) $this->user->getAuthIdentifier()],
        validCodes: ['123456'],
        validRecoveryCodes: ['AAAA-BBBB'],
    ));
});

it('allows access after a valid TOTP code', function (): void {
    $this->actingAs($this->user)
        ->postJson('/account/confirm-step-up', ['code' => '123456'])
        ->assertOk();
});

it('rejects access with an invalid code', function (): void {
    $this->actingAs($this->user)
        ->postJson('/account/confirm-step-up', ['code' => '000000'])
        ->assertForbidden();
});

it('accepts a recovery code', function (): void {
    $this->actingAs($this->user)
        ->postJson('/account/confirm-step-up', ['code' => 'AAAA-BBBB'])
        ->assertOk();

    // Second use of the same recovery code must fail (single-use).
    $this->actingAs($this->user)
        ->postJson('/account/confirm-step-up', ['code' => 'AAAA-BBBB'])
        ->assertForbidden();
});
```

---

Audit telemetry
---------------

[](#audit-telemetry)

Every step-up attempt writes one or more rows to `rebel_auth_events`. The bridge produces three event types:

Event typeWhen emittedChannelAMR`stepup.laragear_totp.verified`TOTP code OR recovery code accepted`totp``['otp','totp']``stepup.laragear_totp.failed`Code wrong, 2FA not enabled, or any error`totp``['otp','totp']``stepup.laragear_totp.recovery_code.used`Recovery code redeemed (emitted before `.verified`)`totp``['recovery_code']`All events include `subject_type`, `subject_id`, `aal` (`aal2` on verified), `channel`, and `amr`.

The TOTP code, any TOTP secret, and recovery codes are **never** written to the audit trail or any log.

---

Card-battle: TOTP step-up comparison
------------------------------------

[](#card-battle-totp-step-up-comparison)

Feature**laravel-rebel-bridge-laragear-2fa**Laravel Fortify (built-in 2FA)Authy SDKShopify (platform MFA)TOTP step-up (not just login 2FA)YesNo — only at loginNo step-up APINo developer APISingle-use recovery codesYesYesNoNoAAL2 assurance declarationYesNoNoNoAMR `['otp','totp']` telemetryYesNoNoNoAudit trail (`rebel_auth_events`)YesNoNoNoCompliance-ready (PSD2 / NIST 800-63)YesNoNoNoOffline tests (no DB/TOTP engine needed)Yes — `FakeTwoFactorValidator`No — needs Google2FA + CryptNoNoPHPStan level maxYesNoNoNoConfig-gated driver registrationYesNoNoNoFail-closed on any ThrowableYesNoNoNoRecovery-code single-use enforcementYesYesNoNoPhishing-resistantNo (by design — TOTP is not)NoNoNoLaravel 12 / 13 supportYesYesNoNoOpen source / self-hostedYesYesNo — SaaSNo — closed---

🔋 Vibe coding with batteries included
-------------------------------------

[](#-vibe-coding-with-batteries-included)

This package ships everything you need to develop, extend, and test it with an AI coding assistant:

- **`CLAUDE.md`** — working guide for Claude Code and other AI agents: conventions, architecture, laragear API methods, config keys, Definition of Done.
- **`AGENTS.md`** — operational rules: branching strategy, local loop, GitHub gate, security guardrails.
- **`.claude/skills/rebel-package-dev/`** — an invocable skill that encodes the TDD loop, PHPStan-max recipes, security rules, and the release procedure. Invoke it with `/rebel-package-dev` before non-trivial work.
- **`Testing\FakeTwoFactorValidator`** — deterministic offline fake: configure which users have 2FA enabled, which TOTP codes pass (not consumed), and which recovery codes are available (single-use). Tests run in under 2 seconds with no external dependencies.

Drop into the project directory and start with `/rebel-package-dev` for a guided dev session.

---

Contributing
------------

[](#contributing)

See [AGENTS.md](AGENTS.md) for the full contributing workflow (branch naming, Definition of Done, CI gates). PRs are welcome; please keep the PHPStan level max green and include Pest tests.

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

Credits
-------

[](#credits)

Built by [Padosoft](https://www.padosoft.com). Part of the [Laravel Rebel](https://github.com/padosoft/laravel-rebel-auth) enterprise authentication suite.

Uses [laragear/two-factor](https://github.com/Laragear/TwoFactor) by Italo Israel Baeza Cabrera.

###  Health Score

37

—

LowBetter than 81% of packages

Maintenance91

Actively maintained with recent releases

Popularity2

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

51d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/10467699?v=4)[Lorenzo](/maintainers/lopadova)[@lopadova](https://github.com/lopadova)

---

Top Contributors

[![lopadova](https://avatars.githubusercontent.com/u/10467699?v=4)](https://github.com/lopadova "lopadova (5 commits)")

---

Tags

laraveltotpAuthenticationtwo-factorlaragearpadosoftRebelstep-up

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/padosoft-laravel-rebel-bridge-laragear-2fa/health.svg)

```
[![Health](https://phpackages.com/badges/padosoft-laravel-rebel-bridge-laragear-2fa/health.svg)](https://phpackages.com/packages/padosoft-laravel-rebel-bridge-laragear-2fa)
```

###  Alternatives

[defstudio/telegraph

A laravel facade to interact with Telegram Bots

813336.8k3](/packages/defstudio-telegraph)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3914.8k](/packages/rawilk-profile-filament-plugin)[harris21/laravel-fuse

Circuit breaker for Laravel queue jobs. Protect your workers from cascading failures.

45955.7k](/packages/harris21-laravel-fuse)[masterix21/laravel-licensing

Laravel licensing package with polymorphic assignment to any model, activation keys, expirations/renewals, and seat control via LicenseUsage. Supports offline verification with public-key–signed tokens, a CLI to generate/rotate/revoke keys, and an extensible architecture via config and contracts.

1613.3k4](/packages/masterix21-laravel-licensing)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5022.6k](/packages/simplestats-io-laravel-client)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
