Skip to main content
Laravel Permission provides multiple methods to check if a user has specific permissions or roles. These checks work seamlessly with both direct permissions and permissions inherited through roles.

Checking Permissions

Verify if a user has specific permissions.
Check if a user has a specific permission:
$user = User::find(1);

// Check by permission name
if ($user->hasPermissionTo('edit articles')) {
    // User has the permission
}

// Check with specific guard
if ($user->hasPermissionTo('edit articles', 'api')) {
    // User has the permission on api guard
}

// Using Permission model
$permission = Permission::findByName('edit articles');
if ($user->hasPermissionTo($permission)) {
    // User has the permission
}
Throws PermissionDoesNotExist exception if the permission doesn’t exist in the database.

Checking Multiple Permissions

Check if a user has any or all of multiple permissions.
Check if user has at least one of the given permissions:
// Returns true if user has ANY of these permissions
if ($user->hasAnyPermission(['edit articles', 'delete articles'])) {
    // User can either edit OR delete articles
}

// Works with variable arguments
if ($user->hasAnyPermission('edit articles', 'delete articles')) {
    // Same as above
}

Checking Direct Permissions

Check only directly assigned permissions, ignoring role permissions.
// Check if user has direct permission (not via role)
if ($user->hasDirectPermission('edit articles')) {
    // User was directly given this permission
}

// Check multiple direct permissions (any)
if ($user->hasAnyDirectPermission('edit articles', 'delete articles')) {
    // User has at least one direct permission
}

// Check multiple direct permissions (all)
if ($user->hasAllDirectPermissions('edit articles', 'publish articles')) {
    // User has all these direct permissions
}
These methods check ONLY direct permissions and ignore permissions inherited through roles.

Checking Roles

Verify if a user has specific roles.
Check if user has a specific role:
// Check single role (string)
if ($user->hasRole('writer')) {
    // User has the writer role
}

// Check with Role model
$role = Role::findByName('writer');
if ($user->hasRole($role)) {
    // User has the role
}

// Check multiple roles (returns true if user has ANY)
if ($user->hasRole(['writer', 'editor'])) {
    // User is either a writer OR editor
}

// Using pipe separator
if ($user->hasRole('writer|editor')) {
    // Same as array
}

Method Signatures

Key method signatures from the source code:
// Check if has permission (throws exception if not found)
public function hasPermissionTo(
    string|int|Permission|BackedEnum $permission, 
    ?string $guardName = null
): bool

// Safe check (returns false if not found)
public function checkPermissionTo(
    string|int|Permission|BackedEnum $permission, 
    ?string $guardName = null
): bool

// Check any permission
public function hasAnyPermission(
    string|int|array|Permission|Collection|BackedEnum ...$permissions
): bool

// Check all permissions
public function hasAllPermissions(
    string|int|array|Permission|Collection|BackedEnum ...$permissions
): bool

// Check direct permission
public function hasDirectPermission(
    string|int|Permission|BackedEnum $permission
): bool

Understanding Permission Checks

Permission checks follow this logic:
1

Direct Permissions First

Check if user has the permission assigned directly:
$hasDirectPermission = $user->hasDirectPermission('edit articles');
2

Then Via Roles

If not found directly, check if user has it through any role:
$hasViaRole = $user->hasPermissionViaRole($permission);
3

Combined Result

The permission is granted if found in either source:
// Internal logic of hasPermissionTo()
return $this->hasDirectPermission($permission) 
    || $this->hasPermissionViaRole($permission);

Using in Controllers

Common patterns for checking permissions in controllers:
namespace App\Http\Controllers;

class ArticleController extends Controller
{
    public function edit(Article $article)
    {
        if (! auth()->user()->can('edit articles')) {
            abort(403);
        }

        return view('articles.edit', compact('article'));
    }
}

Wildcard Permissions

If wildcard permissions are enabled, you can use pattern matching:
// User has permission: 'articles.*'
$user->givePermissionTo('articles.*');

// These all return true:
$user->hasPermissionTo('articles.edit');
$user->hasPermissionTo('articles.delete');
$user->hasPermissionTo('articles.publish');
Wildcard permissions must be enabled in the config:
'enable_wildcard_permission' => true,

Checking Permissions for Other Users

Check permissions for users other than the authenticated user:
$user = User::find(5);

// Check this specific user's permissions
if ($user->hasPermissionTo('edit articles')) {
    // This user can edit
}

// Compare with authenticated user
if (auth()->user()->hasPermissionTo('delete articles') 
    && !$user->hasPermissionTo('delete articles')) {
    // I can delete but the other user cannot
}

Performance Considerations

Eager Loading: Load roles and permissions to avoid N+1 queries:
// Load relationships upfront
$users = User::with(['roles', 'permissions'])->get();

foreach ($users as $user) {
    // These checks use cached data, no additional queries
    if ($user->hasRole('admin')) {
        // ...
    }
}
Caching: The package caches permissions automatically. Permissions are only queried once per request and stored in the cache.

Next Steps

Blade Directives

Use permission checks in Blade templates

Middleware

Protect routes with middleware

Build docs developers (and LLMs) love