Complete Authentication, Authorization, and Role & Privilege Management. 40+ CLI commands, 7 Blade directives, middleware, and optional REST API. Your Swiss Army knife for Laravel security.
composer require hasinhayder/tyro
The complete auth & access control toolkit for Laravel applications.
Full authentication with Sanctum, role-based access control, fine-grained privileges, and Laravel Gate integration out of the box.
Sanctum tokens mirror role + privilege slugs, suspension workflows revoke tokens instantly, battle-tested middleware stack.
Manage reusable privileges per role via HTTP or CLI, then reuse them in middleware or $user->can() calls.
Manage users, roles, privileges, and tokens from the terminal. Perfect for automation, CI/CD, and incident response.
Use @usercan, @hasrole, @hasanyrole, @hasroles, @hasprivilege, @hasanyprivilege, @hasprivileges in your views. Clean, readable templates.
Need API endpoints? They're included. Don't need them? Disable with one config flag. Tyro adapts to your needs.
From zero to production-ready API in under 60 seconds
composer require hasinhayder/tyro
php artisan tyro:install
Wraps install:api + migrate + seed + prepare-user-model
That's it! You now have complete authentication, authorization, roles, privileges, 7 Blade directives, middleware, and 40+ CLI commands.
Read Full DocumentationCheck permissions anywhere in your application with a clean, Laravel-style API
if ($request->user()->can('reports.run')) {
// User has the privilege through their roles
}
if ($request->user()->hasRole('admin')) {
// Check specific role
}
if ($request->user()->hasPrivileges(['billing.view', 'reports.run'])) {
// Require multiple privileges
}
// Suspend a user and revoke all tokens
$user->suspend('Policy violation');
// Check suspension status
if ($user->isSuspended()) {
return response()->json([
'error' => $user->getSuspensionReason()
], 423);
}
Freeze accounts instantly, revoke tokens, and manage suspensions with a clean API
// Suspend a user with reason
$user->suspend('Policy violation');
// All tokens are automatically revoked
// User cannot access protected routes
// Check suspension status
if ($user->isSuspended()) {
$reason = $user->getSuspensionReason();
return response()->json([
'error' => 'Account suspended',
'reason' => $reason
], 423);
}
// Unsuspend when ready
$user->unsuspend();
// CLI: php artisan tyro:suspend-user --user=1
// CLI: php artisan tyro:unsuspend-user --user=1
Use powerful middleware to protect your routes based on roles, privileges, and abilities
Restrict routes to users with specific roles using role: for a single role or roles: for multiple roles.
role:admin - Require single role
roles:admin,editor - Require any of multiple roles
use Illuminate\Support\Facades\Route;
// Single role protection
Route::middleware(['auth:sanctum', 'role:admin'])->group(function () {
Route::get('/admin/dashboard', [AdminController::class, 'dashboard']);
Route::get('/admin/settings', [AdminController::class, 'settings']);
});
// Multiple roles - user needs ANY of these roles
Route::middleware(['auth:sanctum', 'roles:admin,editor,moderator'])->group(function () {
Route::get('/manage/posts', [PostController::class, 'index']);
Route::post('/manage/posts', [PostController::class, 'store']);
});
// Single route with role middleware
Route::get('/super-admin/logs', [LogController::class, 'index'])
->middleware(['auth:sanctum', 'role:super-admin']);
Protect routes based on specific privileges using privilege: for a single privilege or privileges: for multiple privileges.
privilege:reports.view - Require single privilege
privileges:billing.view,invoices.create - Require any privilege
use Illuminate\Support\Facades\Route;
// Single privilege protection
Route::middleware(['auth:sanctum', 'privilege:reports.view'])->group(function () {
Route::get('/reports', [ReportController::class, 'index']);
Route::get('/reports/{id}', [ReportController::class, 'show']);
});
// Multiple privileges - user needs ANY of these privileges
Route::middleware(['auth:sanctum', 'privileges:billing.view,billing.edit'])->group(function () {
Route::get('/billing', [BillingController::class, 'index']);
Route::put('/billing/{id}', [BillingController::class, 'update']);
});
// Protect sensitive operations
Route::delete('/users/{id}', [UserController::class, 'destroy'])
->middleware(['auth:sanctum', 'privilege:users.delete']);
Use Laravel Sanctum's built-in ability: and abilities: middleware for token-based ability checks.
ability:admin - Check single token ability
abilities:posts.create,posts.edit - Require ALL abilities
use Illuminate\Support\Facades\Route;
// Single ability check (role or privilege slug)
Route::middleware(['auth:sanctum', 'ability:admin'])->group(function () {
Route::get('/admin/stats', [StatsController::class, 'index']);
});
// Multiple abilities - user token must have ALL specified abilities
Route::middleware(['auth:sanctum', 'abilities:posts.create,posts.publish'])->group(function () {
Route::post('/posts', [PostController::class, 'store']);
Route::post('/posts/{id}/publish', [PostController::class, 'publish']);
});
// Combine with other middleware
Route::middleware([
'auth:sanctum',
'ability:reports.run',
'throttle:60,1'
])->get('/reports/generate', [ReportController::class, 'generate']);
Tip: When using Tyro, Sanctum tokens automatically include all role slugs and privilege slugs as abilities. This means ability:admin works just like role:admin for API token authentication.
Conditionally render content based on user permissions with clean, readable syntax
{{-- Check if user can perform action via can() --}}
@usercan('admin')
<div class="admin-panel">
<h2>Admin Dashboard</h2>
<p>Welcome to the admin area!</p>
</div>
@endusercan
@usercan('edit-posts')
<button class="btn btn-primary">
Edit Post
</button>
@endusercan
Uses the can() method to check if user has a role or privilege. Works with both role slugs and privilege slugs.
{{-- Check if user has a specific role --}}
@hasrole('admin')
<p>Welcome, Admin!</p>
<a href="/admin/settings">Settings</a>
@endhasrole
@hasrole('editor')
<a href="/dashboard/editor" class="nav-link">
Editor Dashboard
</a>
@endhasrole
@hasrole('super-admin')
<button class="btn-danger">
Critical Actions
</button>
@endhasrole
Checks if the authenticated user has a specific role by its slug. Returns false if not authenticated.
{{-- Check if user has ANY of the roles --}}
@hasanyrole('admin', 'editor', 'moderator')
<div class="management-tools">
<h3>Management Tools</h3>
<p>You have access to management features</p>
<a href="/manage">Open Dashboard</a>
</div>
@endhasanyrole
@hasanyrole('author', 'contributor')
<div class="content-section">
<button>Create New Post</button>
</div>
@endhasanyrole
Renders content if the user has at least one of the specified roles. Great for showing shared features across multiple roles.
{{-- Require ALL specified roles --}}
@hasroles('admin', 'super-admin')
<div class="super-admin-panel">
<h2>Super Admin Controls</h2>
<p>You have both admin and super-admin roles</p>
<button class="btn-danger">
System Configuration
</button>
<button class="btn-warning">
Delete All Data
</button>
</div>
@endhasroles
Renders content only if the user has ALL of the specified roles. Use for features requiring multiple role assignments.
{{-- Check for a specific privilege --}}
@hasprivilege('delete-users')
<button class="btn btn-danger" onclick="deleteUser()">
Delete User
</button>
@endhasprivilege
@hasprivilege('view-reports')
<a href="/reports" class="nav-link">
<i class="icon-reports"></i> View Reports
</a>
@endhasprivilege
@hasprivilege('manage-settings')
<a href="/settings">System Settings</a>
@endhasprivilege
Checks if the user has a specific privilege through any of their assigned roles. More granular than role checks.
{{-- Check for ANY of the privileges --}}
@hasanyprivilege('edit-posts', 'delete-posts', 'publish-posts')
<div class="post-actions">
<h4>Post Management</h4>
@hasprivilege('edit-posts')
<button>Edit</button>
@endhasprivilege
@hasprivilege('delete-posts')
<button>Delete</button>
@endhasprivilege
@hasprivilege('publish-posts')
<button>Publish</button>
@endhasprivilege
</div>
@endhasanyprivilege
Shows content if user has at least one of the listed privileges. Perfect for showing action panels with conditional buttons.
{{-- Require ALL specified privileges --}}
@hasprivileges('create-invoices', 'approve-invoices')
<button class="btn btn-success">
Create and Approve Invoice
</button>
@endhasprivileges
@hasprivileges('view-reports', 'export-reports')
<div class="reports-section">
<a href="/reports">View Reports</a>
<button onclick="exportReport()">
Export to PDF
</button>
</div>
@endhasprivileges
Renders content only if the user has ALL specified privileges. Use for actions requiring multiple permissions.
All directives automatically return false when no user is authenticated. They're registered automatically when Tyro is loaded.
40+ Artisan commands for complete Role and Privilege management and inspection without touching the database or writing raw SQL
tyro:install
Run Laravel's install:api, migrate, and optionally seed or prepare user model
tyro:prepare-user-model
Automatically add HasApiTokens and HasTyroRoles to your User model
tyro:seed
Run the full TyroSeeder (roles + bootstrap admin)
tyro:publish-config
Drop config/tyro.php into your app
tyro:publish-migrations
Copy Tyro's migrations into your database/migrations directory
tyro:create-user
Prompt for name/email/password and attach the default role
tyro:users
Inspect users with their role slugs and suspension status
tyro:users-with-roles
Display users with their role slugs and suspension column
tyro:suspend-user
Suspend a user with optional reason or lift with --unsuspend
tyro:unsuspend-user
Dedicated shortcut to lift user suspensions
tyro:suspended-users
Show every suspended user, when locked, and why
tyro:update-user
Update user details while ensuring you don't remove the last admin
tyro:delete-user
Delete a user while ensuring you don't remove the last admin
tyro:user-privileges
Display the real-time privilege table a user inherits through their roles
tyro:roles
Display all roles with user counts
tyro:roles-with-privileges
Display roles alongside their attached privilege slugs and user counts
tyro:create-role
Manage custom roles (protected slugs cannot be renamed or deleted)
tyro:update-role
Update existing role details
tyro:delete-role
Delete a role (protected slugs cannot be deleted)
tyro:assign-role
Attach a role to a user by email/ID
tyro:delete-user-role
Detach a role from a user
tyro:role-users
List all users currently attached to a given role
tyro:user-roles
Display a specific user's roles and attached privileges
tyro:seed-roles
Reapply the default role catalogue
tyro:flush-roles
Truncate the roles + pivot tables without re-seeding
tyro:privileges
List every privilege and which roles currently own it
tyro:add-privilege
Create new privilege records
tyro:update-privilege
Edit existing privilege records
tyro:delete-privilege
Remove privilege records
tyro:attach-privilege
Attach privileges to roles via slug or ID
tyro:detach-privilege
Detach privileges from roles
tyro:login
Mint a Sanctum token using user ID or email (respects suspensions)
tyro:quick-token
Mint a Sanctum token by user ID/email without password prompt
tyro:me
Paste a Sanctum token and see which user/abilities it belongs to
tyro:logout
Revoke a single token for a given user
tyro:logout-all
Revoke every token for a given user
tyro:logout-all-users
Revoke every Sanctum token for every user (emergency rotation)
tyro:seed-privileges
Reapply Tyro's default privilege catalog and role mappings
tyro:purge-privileges
Remove all privileges and detach them from every role
tyro:version
Echo the current Tyro version from configuration
tyro:postman-collection
Open (or print) the official Postman collection URL
tyro:star
Opens the GitHub repo so you can give Tyro a ⭐
tyro:doc
Opens the documentation site (or prints the URL with --no-open)
tyro:about
Summarises Tyro's mission, author, and useful links
All commands support --help flag and non-interactive mode for automation
Everything you need to know about Tyro
Tyro is the ultimate Authentication, Authorization, and Role & Privilege Management solution for Laravel 12. It provides complete RBAC, user suspension workflows, 40+ CLI commands, 7 Blade directives (@usercan, @hasrole, @hasanyrole, @hasroles, @hasprivilege, @hasanyprivilege, @hasprivileges), middleware for route protection, and optional REST API endpoints. It works for APIs, traditional web apps, and hybrid applications—saving you weeks of development time.
Tyro requires PHP 8.2 or higher, Laravel 12.0 or higher, and Laravel Sanctum 4.0 or higher. It's designed to work seamlessly with fresh Laravel installations and can be integrated into existing projects.
Installation is simple: run composer require hasinhayder/tyro followed by php artisan tyro:install. The install command automatically sets up Sanctum, runs migrations, seeds default roles and privileges, and prepares your User model. That's it—your API is ready!
Tyro ships with 40+ artisan commands for managing users, roles, privileges, tokens, and more. Key commands include: tyro:create-user, tyro:assign-role, tyro:suspend-user, tyro:add-privilege, tyro:attach-privilege, tyro:quick-token, and tyro:logout-all-users. Every command supports non-interactive flags for automation.
Tyro uses a flexible role-privilege system. Roles (like "admin", "editor") can have multiple privileges (like "reports.run", "billing.view"). Users are assigned roles, and they inherit all privileges from those roles. You can check permissions using $user->can('privilege.name'), $user->hasRole('role-slug'), or middleware like ability:admin,reports.run. Sanctum tokens automatically include all role and privilege slugs as abilities.
Absolutely! Publish the config file with php artisan vendor:publish --tag=tyro-config to customize route prefixes, middleware, table names, default roles, and more. You can also publish migrations and disable built-in routes or commands via environment variables. Tyro is designed to be extensible without friction.
Use php artisan tyro:suspend-user --user=email@example.com --reason="Policy violation" or call $user->suspend('reason') in your code. Suspension automatically revokes all Sanctum tokens and prevents login. To lift a suspension, use php artisan tyro:unsuspend-user or $user->unsuspend(). Check suspension status with $user->isSuspended().
Yes! Tyro is battle-tested and ships with the same security hardening, middleware stack, and authorization logic used in production applications. It includes comprehensive tests, factories, seeders, and follows Laravel best practices. You can disable commands in production via TYRO_DISABLE_COMMANDS=true for additional security.
Visit the GitHub repository to read the full documentation, open issues, or submit pull requests. The README includes detailed examples, API references, and troubleshooting guides. You can also use php artisan tyro:doc to open the documentation directly from your terminal.
Join developers who save weeks on authentication and authorization with Tyro
composer require hasinhayder/tyro