laravel-rbac maintained by paramsoftware
Laravel RBAC & Dynamic Authentication Settings
An enterprise-grade, independent Laravel Composer package unifying Spatie-Powered Role-Based Access Control (RBAC) and Dynamic Multi-Factor Authentication Settings with administrative UI, permission matrix, dynamic SMTP, SMS/WhatsApp OTP gateways, Google2FA TOTP, hardware MAC/device restrictions, dynamic registration controls, and password complexity enforcement.
Package Overview
paramsoftware/laravel-rbac delivers a cohesive security and authorization suite for modern Laravel applications:
-
Module A: Enterprise RBAC Engine
- Built upon the battle-tested
spatie/laravel-permissionfoundation. - Interactive 2D Module-Operation Permission Cross Matrix (
{module}-{operation}). - Encrypted Route Keys on all administrative URLs to prevent ID enumeration.
- Role management with system role protections (
Adminprotection guardrails). - Authenticatable User Role assignment management.
- Dual-layer caching (in-memory request caching + versioned persistent store invalidation).
- Full Laravel integration: Route Middleware (
role,permission,role_or_permission),Gate::before()authorization hook, Blade Directives, and Artisan CLI tooling.
- Built upon the battle-tested
-
Module B: Dynamic Authentication & Multi-Factor Security
- Dynamic SMTP Configuration: Runtime mailer configuration injection, credential encryption (AES-256), unsaved change detection, test email dispatching, and connection error handling.
- Multi-Channel OTP Challenges: Flexible Email OTP, Mobile SMS OTP, and WhatsApp OTP verification pipelines with configurable attempt limits, expiry intervals, and cooldown throttling.
- Two-Factor Authentication (TOTP): Google2FA-compatible time-based one-time passwords with self-contained, offline SVG QR code generation (zero external third-party API tracking).
- Hardware MAC & Device Restrictions: Client fingerprinting, normalized MAC address matching, and device authorization tokens.
- Dynamic Registration Controls: Real-time registration enablement toggling,
EnsureRegistrationIsOpenmiddleware, and conditional@rbacCanRegisterBlade directive. - Dynamic Password Complexity Rules: Configurable runtime validation for minimum length, uppercase characters, digits, and special symbols via
ConfiguredPasswordRule. - GD Mathematical CAPTCHA: Lightweight mathematical challenge generator with anti-replay session verification.
Requirements & Compatibility Matrix
| Dependency | Supported Versions | Verification Status |
|---|---|---|
| PHP | ^8.2 || ^8.3 |
PASS (Tested on PHP 8.3.31) |
| Laravel Framework | ^10.0 || ^11.0 || ^12.0 || ^13.0 |
PASS (Tested on Laravel 11.x, Testbench 9/10/11) |
| Spatie Laravel Permission | ^6.0 |
PASS (Core RBAC foundation) |
| PragmaRX Google2FA | ^8.0 |
PASS (TOTP authentication) |
| BaconQrCode | ^2.0 || ^3.0 |
PASS (Vector QR code rendering) |
PHP Extension ext-gd |
* |
PASS (Required for CAPTCHA image generation) |
Installation
Via Composer
Once published to Packagist:
composer require paramsoftware/laravel-rbac
Via Public GitHub VCS Repository (Direct Installation)
To install directly from the public GitHub repository prior to Packagist indexation:
composer config repositories.rbac vcs https://github.com/pinal-paramsoftware/Rbac-Package.git
composer require paramsoftware/laravel-rbac:1.0.0
Or add directly to your composer.json:
{
"repositories": [
{
"type": "vcs",
"url": "https://github.com/pinal-paramsoftware/Rbac-Package.git"
}
],
"require": {
"paramsoftware/laravel-rbac": "1.0.0"
}
}
(During local path-repository development:)
{
"repositories": [
{
"type": "path",
"url": "packages/paramsoftware-laravel-rbac",
"options": {
"symlink": true
}
}
],
"require": {
"paramsoftware/laravel-rbac": "@dev"
}
}
Auto-Discovery
The package auto-registers its service provider and facade:
- Service Provider:
ParamSoftware\Rbac\RbacServiceProvider - Facade:
ParamSoftware\Rbac\Facades\Rbac
Quick Setup & Publishing
1. Unified Installer Command
Run the all-in-one setup command to publish assets, run idempotent migrations, and seed default roles, permissions, auth settings, and password rules:
php artisan rbac:install --migrate --seed
To create your initial administrator account during installation:
php artisan rbac:install --migrate --seed --admin=admin@example.com --password=YourSecurePassword
2. Manual Publishing Options
If you prefer granular control over what gets published into your host application:
# 1. Publish configuration (config/rbac.php)
php artisan vendor:publish --tag=rbac-config
# 2. Publish database migrations (RBAC tables + Dynamic Auth Settings tables)
php artisan vendor:publish --tag=rbac-migrations
php artisan vendor:publish --tag=rbac-auth-migrations
# 3. Publish Minible Admin Panel static assets (CSS, JS, Fonts, Images to public/assets)
php artisan vendor:publish --tag=rbac-assets
# 4. Optional: Publish Minible Blade layouts (to resources/views/layouts)
php artisan vendor:publish --tag=rbac-layouts
# 5. Optional: Publish editable package Blade views (to resources/views/vendor/rbac)
php artisan vendor:publish --tag=rbac-views
Run migrations:
php artisan migrate
Seed defaults idempotently:
php artisan db:seed --class="ParamSoftware\\Rbac\\Database\\Seeders\\RbacDatabaseSeeder"
Note on Migration Safety: All migration stubs use idempotent
if (! Schema::hasTable(...))guards. They safely skip existing tables without altering schema or deleting existing user data.
Admin Panel Modules & Navigation
Once installed, the complete Minible Admin Panel is accessible under the configurable admin prefix (default /admin):
| Module | URL | Description |
|---|---|---|
| Dashboard | /admin/dashboard (or /admin) |
Minible KPI dashboard with metrics, charts, and activity overview |
| Roles Management | /admin/access-control/roles |
DataTables role listing, create/edit, permission assignment, and modal inspection |
| Permissions Management | /admin/access-control/permissions |
Module-centric permission listing, dynamic operation repeater, and CRUD |
| Permission Matrix | /admin/access-control/matrix |
Real-time 2D cross-matrix with column/row toggles and protected role guardrails |
| User Roles Assignment | /admin/access-control/users |
Authenticatable user list, role assignment, and access scope inspection |
| Authentication Settings | /admin/auth-settings |
Centralized tabs for CAPTCHA, Email OTP, SMS/WhatsApp gateways, 2FA, and Password Criteria |
| Change Password | /admin/change-password |
Dynamic complexity-validated password change modal and endpoint |
| Locale Switcher | /admin/lang/{locale} |
Session-backed dynamic language and translation switcher |
Host Application Integration
0. Authentication Routes Prerequisite
The package seamlessly aligns with Laravel's standard authentication mechanisms. Ensure your application has standard named authentication routes defined (e.g. via Laravel Breeze, Jetstream, Fortify, or custom routes in routes/web.php):
route('login'): Needed for unauthenticated redirects and when registration is disabled.route('register'): Needed if you expose public user self-registration.
1. Authenticatable User Model Setup
Attach the HasRolesAndPermissions trait to your User model:
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use ParamSoftware\Rbac\Contracts\HasRbacPermissions;
use ParamSoftware\Rbac\Traits\HasRolesAndPermissions;
class User extends Authenticatable implements HasRbacPermissions
{
use HasRolesAndPermissions;
// ...
}
2. Login Flow Multi-Factor Authentication Pipeline
Attach the EnforcesDynamicAuth trait to your authentication controller (e.g. LoginController):
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use ParamSoftware\Rbac\Traits\EnforcesDynamicAuth;
class LoginController extends Controller
{
use AuthenticatesUsers, EnforcesDynamicAuth;
// The trait automatically intercepts the authenticated() hook
// and enforces configured MFA challenges (Device/MAC, Email OTP, Mobile OTP, WhatsApp OTP, 2FA)
}
3. Dynamic Registration Route Guard
Protect your public registration route with the ensure_registration_is_open middleware:
Route::get('/register', [RegisterController::class, 'showRegistrationForm'])
->middleware('ensure_registration_is_open')
->name('register');
Route::post('/register', [RegisterController::class, 'register'])
->middleware('ensure_registration_is_open');
Configuration (config/rbac.php)
Key configuration sections:
return [
// Model Bindings
'models' => [
'user' => App\Models\User::class,
'role' => ParamSoftware\Rbac\Models\Role::class,
'permission' => ParamSoftware\Rbac\Models\Permission::class,
'auth_setting' => ParamSoftware\Rbac\Models\AuthSetting::class,
'password_rule' => ParamSoftware\Rbac\Models\PasswordRule::class,
'auth_provider_setting' => ParamSoftware\Rbac\Models\AuthProviderSetting::class,
'user_two_factor' => ParamSoftware\Rbac\Models\UserTwoFactor::class,
'email_login_otp' => ParamSoftware\Rbac\Models\EmailLoginOtp::class,
'user_device' => ParamSoftware\Rbac\Models\UserDevice::class,
],
// Superadmin bypass
'superadmin' => [
'gate_bypass' => false,
'role_name' => 'Admin',
'guard' => 'web',
],
// Route configuration
'routes' => [
'enabled' => true,
'prefix' => 'admin/access-control',
'middleware' => ['web', 'auth'],
],
// Dynamic Auth Settings Module
'auth_settings' => [
'routes' => [
'prefix' => 'admin/auth-settings',
'middleware' => ['web', 'auth'],
],
'otp' => [
'default_attempts' => 3,
'default_reset_time' => 2, // minutes cooldown
'default_expiry_time' => 10, // minutes validity
],
],
];
Core RBAC Usage & API
Role Management
use ParamSoftware\Rbac\Facades\Rbac;
// Create role
$role = Rbac::createRole([
'name' => 'Editor',
'display_name' => 'Content Editor',
'description' => 'Can manage articles',
]);
// Find role
$role = Rbac::findRole('editor');
// Assign permissions
Rbac::assignPermissionsToRole($role, 'post-publish', 'post-edit');
Module Permissions
// Create module with standard operations (view, create, edit, delete)
Rbac::createModule('invoices');
// Create module with custom operations
Rbac::createModule('reports', ['view', 'generate', 'export']);
Permission Checking & Cache Management
// User checks
$user->hasRole('Admin');
$user->hasPermissionTo('reports-generate');
$user->can('invoices-create');
// Facade checks
Rbac::userHasRole($user, 'Admin|Editor');
Rbac::userHasPermission($user, 'invoices-view');
// Clear cached permissions
Rbac::forgetCachedPermissions();
Blade Directives
{{-- RBAC Roles --}}
@role('Admin')
<a href="/admin">Admin Panel</a>
@endrole
@hasanyrole('Admin|Editor')
<span>Staff Member</span>
@endhasanyrole
{{-- RBAC Permissions --}}
@permission('invoices-create')
<button>Create Invoice</button>
@endpermission
{{-- Dynamic Registration Visibility --}}
@rbacCanRegister
<a href="{{ route('register') }}">Create Account</a>
@endrbacCanRegister
{{-- Dynamic Setting Condition --}}
@authSettingIsEnabled('CAPTCHA')
<div id="captcha-container">...</div>
@endauthSettingIsEnabled
Dynamic Authentication Settings Module
Administrative Endpoints
The package exposes authenticated administrative AJAX endpoints under both /admin/auth-settings and /AuthPasswordSetting (for seamless backward compatibility):
| Endpoint | Method | Functionality |
|---|---|---|
/GetAuthenticationSettings |
GET |
Retrieve status of all authentication toggles |
/UpdateAuthenticationSettings |
POST |
Bulk update authentication settings |
/GetSmtpSettings |
GET |
Retrieve masked SMTP configuration |
/UpdateSmtpSettings |
POST |
Save encrypted SMTP settings and reconfigure mailer |
/SendTestEmail |
POST |
Send test verification email to confirm SMTP connectivity |
/GetMobileOtpGatewaySettings |
GET |
Retrieve masked SMS gateway parameters |
/UpdateMobileOtpGatewaySettings |
POST |
Save SMS gateway URL, token, template, and timeout |
/GetWhatsAppGatewaySettings |
GET |
Retrieve masked WhatsApp gateway parameters |
/UpdateWhatsAppGatewaySettings |
POST |
Save WhatsApp gateway URL, credentials, and template |
/GetCaptchaSettings |
GET |
Retrieve CAPTCHA configuration |
/UpdateCaptchaSettings |
POST |
Update CAPTCHA configuration |
/GetTwoFactorSettings |
GET |
Retrieve Two-Factor Authentication parameters |
/UpdateTwoFactorSettings |
POST |
Update 2FA attempt limits and expiry |
/GetPasswordRules |
GET |
Retrieve active password complexity rules |
/UpdatePasswordRules |
POST |
Update min length, uppercase, number, and special char rules |
/GetRegistrationSettings |
GET |
Retrieve registration status |
/UpdateRegistrationSettings |
POST |
Enable or disable public user registration |
Programmatic Service APIs
You can also interact programmatically with the security and authentication services:
use ParamSoftware\Rbac\Models\AuthSetting;
use ParamSoftware\Rbac\Services\Auth\AuthSettingsManager;
use ParamSoftware\Rbac\Services\Auth\CaptchaService;
use ParamSoftware\Rbac\Services\Auth\OtpChallengeService;
use ParamSoftware\Rbac\Services\Auth\TwoFactorAuthService;
// Check if MFA method is enabled
$settings = app(AuthSettingsManager::class);
$isEmailOtpActive = $settings->isEnabled(AuthSetting::CODE_EMAIL_OTP);
// Issue & verify OTP challenge (Email / Mobile / WhatsApp)
$otpService = app(OtpChallengeService::class);
$challenge = $otpService->issueChallenge($user->id, $user->email, AuthSetting::CODE_EMAIL_OTP);
$result = $otpService->verifyChallenge($user->id, AuthSetting::CODE_EMAIL_OTP, $submittedCode);
// TOTP 2FA secret and offline QR generation
$twoFactor = app(TwoFactorAuthService::class);
$secret = $twoFactor->generateSecretKey();
$svgQr = $twoFactor->generateQrCodeSvg('My App', $user->email, $secret);
$isValid = $twoFactor->verifyKey($secret, $submittedCode);
// Mathematical / GD CAPTCHA
$captcha = app(CaptchaService::class);
$pngResponse = $captcha->renderImageResponse();
$isValid = $captcha->validateCaptcha($submittedText)['valid'];
Artisan Console Commands
| Command | Purpose |
|---|---|
php artisan rbac:install |
Publish config, migrations, and optionally seed default roles |
php artisan rbac:module {name} [--ops=] |
Automatically generate module permissions and assign to Admin |
php artisan rbac:assign {userId} {role} |
Assign an RBAC role to a user via CLI |
php artisan rbac:clear-cache |
Clear RBAC permission cache across drivers |
Testing & Quality Assurance
Run Package Unit & Feature Tests
cd packages/paramsoftware-laravel-rbac
vendor/bin/phpunit
Current test suite: 234 tests, 856 assertions, 100% PASS.
Run Code Formatter
vendor/bin/pint --format agent
Troubleshooting & FAQ
1. Table 'users' has no column named...
When testing in isolation, ensure your test fixture user model specifies the expected database schema. The package test fixture handles both id and emp_id identifiers.
2. SMTP Test Email fails with Connection refused
Ensure outbound port 587 (TLS) or 465 (SSL) is open in your server firewall. In local development environments, test using Mailtrap, MailHog, or Herd Mail.
3. "Registration is currently disabled"
If users receive a 403 or redirect on /register, verify that the REGISTRATION setting is enabled in the Authentication Settings dashboard or run:
\ParamSoftware\Rbac\Models\AuthSetting::where('AuthCode', 'REGISTRATION')->update(['IsEnabled' => 1]);
app(\ParamSoftware\Rbac\Services\Auth\AuthSettingsManager::class)->clearCache();
Security Vulnerability Reporting
If you discover a security vulnerability within this package, please contact Param Software Security at security@paramsoftware.com. All security vulnerabilities will be promptly addressed.
License
This software is open-sourced under the MIT License.