Securing Laravel APIs with Tyro: A Comprehensive Role and Privilege Guide
Overview
Tyro provides a robust, production-ready framework for managing authentication, authorization, and granular roles in Laravel applications. Created by Hasin Hayder, it distinguishes itself from traditional permission packages by offering over 40 Artisan commands and specialized features like user suspension and built-in API authentication routes. It serves as a comprehensive alternative to Spatie Laravel Permission, specifically optimized for API-centric architectures.
Prerequisites
To follow this guide, you should have a baseline understanding of the Laravel framework, particularly Laravel Sanctum for token-based authentication. You will need a development environment running PHP 8.x and Composer installed.

Key Libraries & Tools
- Tyro: The primary authorization engine handling roles and privileges.
- Laravel Sanctum: The underlying dependency used for generating and verifying API tokens.
- Postman: An API client used to test login endpoints and protected routes.
- VS Code: The recommended code editor for managing your project files.
Code Walkthrough
1. Installation and Scaffolding
Begin by pulling the package into a fresh project and running the installation command. This process automatically sets up the necessary API infrastructure.
composer require hasinhayder/tyro
php artisan tyro:install
2. Model Configuration
Integrate the Tyro functionality into your User model by adding the HasTyroRoles trait. This enables the model to interact with the underlying role-user pivot tables.
namespace App\Models;
use Illuminate\Foundation\Auth\User as Authenticatable;
use HasinHayder\Tyro\Traits\HasTyroRoles;
class User extends Authenticatable
{
use HasTyroRoles;
}
3. Protecting Routes with Privileges
Unlike standard Sanctum protection, Tyro allows you to gate specific actions behind named privileges. In your api.php routes file, apply the privilege middleware to sensitive endpoints.
Route::middleware(['auth:sanctum', 'privilege:posts.create'])->group(function () {
Route::post('/posts', [PostController::class, 'store']);
});
Syntax Notes
Tyro uses a specific naming convention for its pivot tables, opting for user_roles rather than the traditional alphabetical role_user format. It also utilizes a "Privilege" nomenclature which is functionally equivalent to "Permissions" in other ecosystems but allows for more granular slug-based checks.
Practical Examples
In a real-world scenario, you might have an Admin role with a posts.create privilege. When an Admin logs in via /api/login, they receive a token. Sending a POST request to /api/posts with this token succeeds. However, a regular user with a valid token but lacking the specific posts.create privilege will receive a 403 Forbidden response, ensuring tight security for your data-writing endpoints.
Tips & Gotchas
When testing with Postman, always ensure your headers include Accept: application/json. Without this, Laravel might attempt to return a standard HTML login redirect rather than a clean JSON error message when access is denied. Furthermore, remember that Tyro relies on its own seeders; ensure you run php artisan db:seed --class=TyroSeeder during initial setup to populate the default admin accounts.
- Tyro
- 33%· products
- Laravel
- 17%· products
- Laravel Sanctum
- 11%· products
- Postman
- 11%· products
- Composer
- 6%· products
- Other topics
- 22%

Laravel Package Tyro: API Roles/Privileges Example
WatchLaravel Daily // 6:44