waguilar33/filament-guardian

Role and permission management for Filament

Maintainers

Package info

github.com/Waguilar33/filament-guardian

pkg:composer/waguilar33/filament-guardian

Fund package maintenance!

waguilar

Statistics

Installs: 96

Dependents: 0

Suggesters: 0

Stars: 7

Open Issues: 0

v1.4.0 2026-03-04 20:26 UTC

This package is auto-updated.

Last update: 2026-04-04 20:44:41 UTC


README

Role and permission management for Filament panels using Spatie Laravel Permission.

Requirements

  • PHP 8.2+
  • Laravel 11+
  • Filament 4+
  • Spatie Laravel Permission 6+

Installation

composer require waguilar33/filament-guardian

Spatie Setup

If you haven't already configured Spatie Laravel Permission:

php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider"
php artisan migrate

Add the trait to your User model:

use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;
}

Basic Usage

Register the plugin in your panel provider:

use Waguilar\FilamentGuardian\FilamentGuardianPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            FilamentGuardianPlugin::make(),
        ]);
}

This registers a RoleResource in your panel for managing roles and permissions.

Guard Configuration

The plugin uses Filament's built-in authGuard() configuration to isolate roles between panels:

public function panel(Panel $panel): Panel
{
    return $panel
        ->authGuard('admin')  // Filament's auth guard
        ->plugins([
            FilamentGuardianPlugin::make(),
        ]);
}

Each panel can use a different guard to isolate roles and permissions.

Custom Role/Permission Models

If using custom models (e.g., for UUIDs), configure them in Spatie:

// config/permission.php
return [
    'models' => [
        'role' => App\Models\Role::class,
        'permission' => App\Models\Permission::class,
    ],
];

The plugin reads model classes from Spatie's PermissionRegistrar.

Multi-Tenancy

For panels with tenancy, roles are automatically scoped to the current tenant.

1. Enable teams in Spatie config

This must be done before running the Spatie migration:

// config/permission.php
return [
    'teams' => true,
    'column_names' => [
        'team_foreign_key' => 'tenant_id', // Match your tenant column
    ],
];

2. Create a custom Role model with tenant relationship

Create a Role model that extends Spatie's Role and adds the tenant relationship. The relationship name must match your Filament panel's getTenantOwnershipRelationshipName() (defaults to the lowercase tenant model name).

// app/Models/Role.php
namespace App\Models;

use App\Models\Tenant;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Spatie\Permission\Models\Role as SpatieRole;

class Role extends SpatieRole
{
    public function tenant(): BelongsTo
    {
        return $this->belongsTo(Tenant::class, 'tenant_id');
    }
}

Important: The relationship method name must match your Filament tenant configuration:

  • If your tenant model is Team, the method should be team()
  • If your tenant model is Tenant, the method should be tenant()
  • If your tenant model is Organization, the method should be organization()

Or configure a custom name in your panel: ->tenantOwnershipRelationshipName('tenant')

Register your custom model in Spatie's config:

// config/permission.php
return [
    'models' => [
        'role' => App\Models\Role::class,
    ],
];

3. Modify the Spatie migration for multi-panel support

If you have both tenant and non-tenant panels, modify Spatie's published migration to make tenant_id nullable:

// model_has_permissions table
if ($teams) {
    $table->uuid($columnNames['team_foreign_key'])->nullable();
    $table->index($columnNames['team_foreign_key'], 'model_has_permissions_team_foreign_key_index');

    $table->primary(
        [$pivotPermission, $columnNames['model_morph_key'], 'model_type'],
        'model_has_permissions_permission_model_type_primary'
    );

    $table->unique(
        [$columnNames['team_foreign_key'], $pivotPermission, $columnNames['model_morph_key'], 'model_type'],
        'model_has_permissions_team_unique'
    );
}

// model_has_roles table - same pattern
if ($teams) {
    $table->uuid($columnNames['team_foreign_key'])->nullable();
    $table->index($columnNames['team_foreign_key'], 'model_has_roles_team_foreign_key_index');

    $table->primary(
        [$pivotRole, $columnNames['model_morph_key'], 'model_type'],
        'model_has_roles_role_model_type_primary'
    );

    $table->unique(
        [$columnNames['team_foreign_key'], $pivotRole, $columnNames['model_morph_key'], 'model_type'],
        'model_has_roles_team_unique'
    );
}

4. Configure panel with tenancy

use App\Models\Tenant;

public function panel(Panel $panel): Panel
{
    return $panel
        ->authGuard('app')
        ->tenant(Tenant::class)
        ->plugins([
            FilamentGuardianPlugin::make(),
        ]);
}

Role/Permission Scoping

Panel Config Scope
With tenancy guard_name = X AND tenant_id = current_tenant
Without tenancy guard_name = X AND tenant_id IS NULL

Super Admin

Users with the super-admin role bypass all permission checks via Laravel's Gate.

Configuration

// config/filament-guardian.php
'super_admin' => [
    'enabled' => true,
    'role_name' => 'Super Admin',
    'intercept' => 'before', // 'before' or 'after'
],
Option Description
enabled Enable/disable super-admin feature globally
role_name Name of the super-admin role
intercept before bypasses ALL gates; after only grants if no explicit denial

Per-Panel Configuration

Override global config settings per panel using the fluent API:

FilamentGuardianPlugin::make()
    ->superAdmin()                        // Enable for this panel (default: from config)
    ->superAdminRoleName('Administrator') // Custom role name for this panel
    ->superAdminIntercept('after')        // 'before' or 'after' for this panel
Method Description
superAdmin(bool) Enable/disable super-admin for this panel
superAdminRoleName(string) Set custom role name (default: from config)
superAdminIntercept(string) Set intercept mode: 'before' or 'after' (default: from config)

Auto-Created Roles for Tenant Panels

For panels with tenancy, the super-admin role is automatically created when a tenant is created.

Manual Setup for Non-Tenant Panels

# Create the super-admin role for a panel
php artisan guardian:super-admin --panel=admin

# Create role and assign to a user
php artisan guardian:super-admin --panel=admin --email=admin@example.com

Facade Methods

All methods accept an optional $panelId parameter. When omitted, they use the current Filament panel context. When provided, they use that panel's configuration.

use Waguilar\FilamentGuardian\Facades\Guardian;

// Check if super-admin is enabled
Guardian::isSuperAdminEnabled();           // Uses current panel context
Guardian::isSuperAdminEnabled('admin');    // Uses 'admin' panel config

// Get configuration values
Guardian::getSuperAdminRoleName();         // Uses current panel context
Guardian::getSuperAdminRoleName('admin');  // Uses 'admin' panel config
Guardian::getSuperAdminIntercept('admin'); // Get intercept mode for panel

// Create/get super-admin role (non-tenant panels only)
Guardian::createSuperAdminRole('admin');
Guardian::getSuperAdminRole('admin');

// Assign super-admin role to a user
Guardian::assignSuperAdminTo($user, 'admin');

// For tenant panels (role auto-created, set team context first)
setPermissionsTeamId($tenant->getKey());
$user->assignRole(Guardian::getSuperAdminRoleName());
Method Description
isSuperAdminEnabled(?string $panelId) Check if super-admin is enabled
getSuperAdminRoleName(?string $panelId) Get the role name
getSuperAdminIntercept(?string $panelId) Get intercept mode
createSuperAdminRole(?string $panelId) Create role for non-tenant panel
getSuperAdminRole(?string $panelId) Get role for non-tenant panel
assignSuperAdminTo($user, ?string $panelId) Assign role to user
createSuperAdminRoleForTenant($tenant, $guard, ?$panelId) Create role for tenant
createUserUsing(Closure $callback) Register custom user creation logic
createUser(string $userModel, array $data) Create a user (uses callback if registered)

Protection

The super-admin role is protected from modification:

  • Cannot be edited or deleted (throws SuperAdminProtectedException)
  • Edit/delete actions are hidden in the RoleResource

Checking Super Admin Status

use Waguilar\FilamentGuardian\Facades\Guardian;

Guardian::userIsSuperAdmin($user);
Guardian::isSuperAdminRole($role);

Multi-Panel Setup

Different panels can have different configurations. We recommend using different guards when panels have significantly different configurations, such as one with tenancy and one without. This ensures proper role isolation between panels.

// AdminPanelProvider.php - No tenancy, manages global roles
return $panel
    ->authGuard('admin')
    ->plugins([
        FilamentGuardianPlugin::make(),
    ]);

// AppPanelProvider.php - With tenancy, roles scoped per tenant
return $panel
    ->authGuard('app')
    ->tenant(Tenant::class)
    ->plugins([
        FilamentGuardianPlugin::make(),
    ]);

Filtering Users in Non-Tenant Panels

When you have multiple panels with some having tenancy and others without, you may encounter an issue where the Users relation manager in non-tenant panels shows all users instead of only the relevant ones.

Why This Happens

Panel Type User Filtering
With tenancy Filament automatically scopes users via tenant ownership relationship
Without tenancy No automatic scoping - tenant_id is NULL, no way to identify which users belong to this panel

In non-tenant panels, there's no built-in mechanism to filter users because:

  • There's no tenant_id to filter by
  • Users don't have a guard column
  • The panel has no ownership relationship to users

Solution: Custom User Filtering

You need to implement your own logic to distinguish users that belong to a non-tenant panel. Common approaches:

1. Add an identifier column to users table:

// Migration
$table->boolean('is_super_admin')->default(false);
// Or
$table->string('panel_type')->nullable(); // 'admin', 'app', etc.
// Or use email domain

2. Create a scope on your User model:

// app/Models/User.php
public function scopeSuperAdmins(Builder $query): Builder
{
    return $query->where('is_super_admin', true);
}

// Or filter by email domain
public function scopeAdminUsers(Builder $query): Builder
{
    return $query->where('email', 'like', '%@yourcompany.com');
}

3. Apply the scope in your published UserResource:

// app/Filament/Admin/Resources/UserResource.php
public static function getEloquentQuery(): Builder
{
    return parent::getEloquentQuery()->superAdmins();
}

4. Override the UsersRelationManager to filter the attach dropdown:

// app/Filament/Admin/Resources/Roles/RelationManagers/UsersRelationManager.php
use Waguilar\FilamentGuardian\Base\Roles\Tables\BaseUsersTable;

class UsersRelationManager extends BaseUsersRelationManager
{
    public function table(Table $table): Table
    {
        return BaseUsersTable::configure($table)
            ->modifyQueryUsing(fn (Builder $query) => $query->superAdmins())
            ->headerActions([
                AttachAction::make()
                    ->recordSelectOptionsQuery(fn (Builder $query) => $query->superAdmins())
                    ->preloadRecordSelect()
                    ->multiple(),
            ]);
    }
}

Note: modifyQueryUsing filters users shown in the relation manager table, while recordSelectOptionsQuery filters users shown in the attach dropdown. Both are needed for complete filtering.

Configuration Priority Order

All configurable values follow this priority:

  1. Fluent API - Per-panel in panel provider
  2. Config file - Global defaults
  3. Translation file - Fallback labels
  4. Hardcoded default - Package defaults

Commands

guardian:sync

Syncs permissions to the database based on your Filament resources, pages, widgets, and custom permissions defined in config.

This command should be part of your deployment process, typically run after migrations. It ensures all permissions exist in the database for your current codebase - new resources get their permissions created, and existing permissions remain untouched.

# Run after migrations in your deployment script
php artisan migrate
php artisan guardian:sync
# Sync specific panels only
php artisan guardian:sync --panel=admin --panel=app

# Verbose output to see each permission being created
php artisan guardian:sync -v

What it creates:

Type Permissions Created
Resources ViewAny:User, Create:User, Update:User, Delete:User, etc.
Pages Access:Dashboard, Access:Settings, etc.
Widgets View:StatsOverview, View:RevenueChart, etc.
Custom Whatever you define in config/filament-guardian.php

Example deployment script:

php artisan down
php artisan migrate --force
php artisan guardian:sync
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan up

guardian:policies

Generates Laravel policy classes for your Filament resources. Policies authorize actions based on the permissions synced by guardian:sync.

Run this during development when you add new resources or need to regenerate policies.

# Interactive mode - prompts for panel and resources
php artisan guardian:policies

# Generate for all resources in a panel
php artisan guardian:policies --panel=admin --all-resources

# Generate for all panels at once
php artisan guardian:policies --all-panels

# Regenerate existing policies (overwrites)
php artisan guardian:policies --panel=admin --all-resources --force

Generated policy example:

// app/Policies/UserPolicy.php
public function viewAny(User $user): bool
{
    return $user->can('ViewAny:User');
}

public function update(User $user, User $model): bool
{
    return $user->can('Update:User');
}

guardian:create-user

Creates a user account. Essential for first deployment when your database has no users and you need an initial admin account to access the panel.

# Interactive mode - prompts for name, email, password
php artisan guardian:create-user

# Non-interactive (useful for CI/CD or scripts)
php artisan guardian:create-user --name="Admin" --email="admin@example.com" --password="secret"

Customizing user creation:

If your User model has additional required fields (e.g., is_super_admin, tenant_id), register a callback in your AppServiceProvider:

use Waguilar\FilamentGuardian\Facades\Guardian;
use Illuminate\Support\Facades\Hash;

public function boot(): void
{
    Guardian::createUserUsing(function (string $userModel, array $data) {
        return $userModel::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
            'is_super_admin' => true, // custom field
        ]);
    });
}

First deployment example:

php artisan migrate
php artisan guardian:sync
php artisan guardian:create-user --name="Admin" --email="admin@example.com" --password="changeme"
php artisan guardian:super-admin --panel=admin --email="admin@example.com"

guardian:super-admin

Creates the super-admin role and optionally assigns it to a user. Required for non-tenant panels where you want a user to bypass all permission checks.

For tenant panels, the super-admin role is automatically created when tenants are created.

# Create the super-admin role for a panel
php artisan guardian:super-admin --panel=admin

# Create role AND assign to existing user
php artisan guardian:super-admin --panel=admin --email=admin@example.com

When to use:

Panel Type Super-Admin Role Creation
Non-tenant Run this command manually
Tenant Automatic when tenant is created

Publishing

Config

php artisan vendor:publish --tag="filament-guardian-config"

Translations

php artisan vendor:publish --tag="filament-guardian-translations"

Role Resource UI

The RoleResource provides a tabbed interface for managing permissions.

Navigation

FilamentGuardianPlugin::make()
    ->navigationLabel('Roles')
    ->navigationIcon('heroicon-o-shield-check')
    ->activeNavigationIcon('heroicon-s-shield-check')
    ->navigationGroup('Settings')
    ->navigationSort(10)
    ->navigationBadge(fn () => Role::count())
    ->navigationBadgeColor('success')
    ->navigationParentItem('settings')
    ->cluster(\App\Filament\Clusters\Settings::class)
    ->registerNavigation(true)

Cluster

Place the Role resource inside a cluster so it appears under that cluster's sub-navigation.

FilamentGuardianPlugin::make()
    ->cluster(\App\Filament\Clusters\Settings::class)

Closures are supported:

FilamentGuardianPlugin::make()
    ->cluster(fn () => auth()->user()->isAdmin()
        ? \App\Filament\Clusters\Settings::class
        : null
    )

Or via config:

// config/filament-guardian.php
'role_resource' => [
    'navigation' => [
        'cluster' => \App\Filament\Clusters\Settings::class,
    ],
],

Defaults to null (no cluster).

Resource Labels & Slug

FilamentGuardianPlugin::make()
    ->modelLabel('Role')
    ->pluralModelLabel('Roles')
    ->slug('access-roles')  // URL: /admin/access-roles

Section Configuration

FilamentGuardianPlugin::make()
    ->roleSectionLabel('Role Information')
    ->roleSectionDescription('Configure basic role settings')
    ->roleSectionIcon(Heroicon::OutlinedIdentification)
    ->roleSectionAside()
    ->permissionsSectionLabel('Access Control')
    ->permissionsSectionDescription('Select which actions this role can perform')
    ->permissionsSectionIcon(Heroicon::OutlinedLockClosed)

Pass false to remove an icon:

FilamentGuardianPlugin::make()
    ->roleSectionIcon(false)

All methods accept closures for dynamic values.

Tab Configuration

FilamentGuardianPlugin::make()
    ->showResourcesTab()           // default: true
    ->showPagesTab()               // default: true
    ->showWidgetsTab()             // default: true
    ->showCustomPermissionsTab()   // default: true
    // Or hide specific tabs
    ->hidePagesTab()
    ->hideWidgetsTab()

Tab Icons

use Filament\Support\Icons\Heroicon;

FilamentGuardianPlugin::make()
    ->resourcesTabIcon(Heroicon::OutlinedRectangleStack)
    ->pagesTabIcon(Heroicon::OutlinedDocument)
    ->widgetsTabIcon(Heroicon::OutlinedPresentationChartBar)
    ->customTabIcon(Heroicon::OutlinedWrench)

Default icons:

  • Resources: Heroicon::OutlinedSquare3Stack3d
  • Pages: Heroicon::OutlinedDocumentText
  • Widgets: Heroicon::OutlinedChartBar
  • Custom: Heroicon::OutlinedCog6Tooth

Checkbox Layout

use Filament\Support\Enums\GridDirection;

FilamentGuardianPlugin::make()
    // Global defaults for all tabs
    ->permissionCheckboxColumns(3)                        // default: 4
    ->permissionCheckboxGridDirection(GridDirection::Row) // default: Column
    // Override per tab
    ->resourceCheckboxColumns(3)
    ->resourceCheckboxGridDirection(GridDirection::Column)
    ->pageCheckboxColumns(2)
    ->pageCheckboxGridDirection(GridDirection::Row)
    ->widgetCheckboxColumns(2)
    ->widgetCheckboxGridDirection(GridDirection::Row)
    ->customCheckboxColumns(1)
    ->customCheckboxGridDirection(GridDirection::Row)

Supports responsive arrays:

FilamentGuardianPlugin::make()
    ->permissionCheckboxColumns([
        'sm' => 2,
        'md' => 3,
        'lg' => 4,
    ])

Resource Sections

FilamentGuardianPlugin::make()
    ->collapseResourceSections()       // Start collapsed
    ->resourceSectionColumns(2)        // Grid layout
    ->showResourceSectionIcon()        // Show navigation icon

Search & Permission Icons

FilamentGuardianPlugin::make()
    ->searchIcon(Heroicon::OutlinedMagnifyingGlass)
    ->permissionAssignedIcon(Heroicon::OutlinedCheckCircle)

Pass false to hide the icon.

Select All Toggle

The permissions form includes a "Select All" toggle to quickly select or deselect all permissions.

FilamentGuardianPlugin::make()
    ->selectAllOnIcon(Heroicon::OutlinedCheckCircle)   // default
    ->selectAllOffIcon(Heroicon::OutlinedXCircle)      // default

Or via config:

// config/filament-guardian.php
'role_resource' => [
    'select_all_toggle' => [
        'on_icon' => 'heroicon-o-check',
        'off_icon' => 'heroicon-o-x-mark',
    ],
],

Pass false to hide the icons.

Permission Labels

Type Label Source
Resources Resource::getPluralModelLabel()
Pages Page::getNavigationLabel()
Widgets Widget::getHeading() or humanized class name
Custom Translation file or permission key

Users Relation Manager

The Role resource includes a Users relation manager out of the box, allowing you to attach/detach users directly from a role.

Features

  • Displays users assigned to the role with name and email columns
  • Attach action filters out users who already have the super-admin role
  • Supports bulk attach and detach operations

Customization

When you publish the Role resource, a UsersRelationManager stub is included. You can customize it by:

Custom table configuration:

// App\Filament\Resources\Roles\Tables\UsersTable.php
use Waguilar\FilamentGuardian\Base\Roles\Tables\BaseUsersTable;

class UsersTable extends BaseUsersTable
{
    public static function configure(Table $table): Table
    {
        return parent::configure($table)
            ->modifyQueryUsing(fn ($query) => $query->where('active', true));
    }
}

Custom relation manager:

// App\Filament\Resources\Roles\RelationManagers\UsersRelationManager.php
use Waguilar\FilamentGuardian\Base\Roles\RelationManagers\BaseUsersRelationManager;

class UsersRelationManager extends BaseUsersRelationManager
{
    protected static BackedEnum|string|null $icon = 'heroicon-o-user-group';

    public function table(Table $table): Table
    {
        return UsersTable::configure($table);
    }

    public static function getTitle(Model $ownerRecord, string $pageClass): string
    {
        return 'Team Members';
    }
}

User Direct Permissions

The package provides a table action for managing user-specific permissions directly, separate from role-based permissions.

Adding the Action

use Waguilar\FilamentGuardian\Actions\ManageUserPermissionsAction;

public function table(Table $table): Table
{
    return $table
        ->columns([...])
        ->recordActions([
            ViewAction::make(),
            ManageUserPermissionsAction::make(),
        ]);
}

Behavior

The action opens a slide-over modal showing only permissions that can be assigned directly to the user:

  • Role permissions are excluded - Permissions inherited from roles are not shown (they're managed via roles)
  • Warning alert - Shows how many permissions the user has from roles
  • Super-admin users - The action is hidden entirely for super-admin users
  • Automatic cleanup - When saved, direct permissions that are now also granted via roles are automatically removed

Customization

The action uses standard Filament action methods:

ManageUserPermissionsAction::make()
    ->label('Custom Label')
    ->icon('heroicon-o-key')
    ->color('primary')

Custom Permissions

Define permissions that don't map to resources, pages, or widgets:

// config/filament-guardian.php
'custom_permissions' => [
    'impersonate-user' => 'Impersonate User',
    'export-orders' => 'Export Orders',
    'manage-settings' => 'Manage Settings',
],

The key is the permission name stored in the database, the value is the display label. For multi-language support, add translations under the custom key in the lang file.

Permission Key Format

// config/filament-guardian.php
'permission_key' => [
    'separator' => ':',
    'case' => 'pascal',
],
Case Example
pascal ViewAny:User
camel viewAny:user
snake view_any:user
kebab view-any:user

Policy Configuration

'policies' => [
    'path' => app_path('Policies'),
    'merge' => true,
    'methods' => [
        'viewAny', 'view', 'create', 'update', 'delete',
        'restore', 'forceDelete', 'deleteAny', 'restoreAny',
        'forceDeleteAny', 'replicate', 'reorder',
    ],
    'single_parameter_methods' => [
        'viewAny', 'create', 'deleteAny', 'restoreAny',
        'forceDeleteAny', 'reorder',
    ],
],

Per-Resource Configuration

'resources' => [
    'subject' => 'model',
    'manage' => [
        App\Filament\Resources\Blog\CategoryResource::class => [
            'subject' => 'BlogCategory',
        ],
        App\Filament\Resources\RoleResource::class => [
            'methods' => ['viewAny', 'view', 'create'],
        ],
    ],
    'exclude' => [
        App\Filament\Resources\SettingsResource::class,
    ],
],

Publishing RoleResource

php artisan filament-guardian:publish-role-resource {panel?}

Published resources extend base classes from the package. You only override what you actually need - the base classes handle all the standard logic.

Available Base Classes

Base Class Purpose
BaseRoleResource Resource definition, navigation, model binding
BaseListRoles List page with create action
BaseCreateRole Create page with permission sync
BaseEditRole Edit page with permission hydration and sync
BaseViewRole View page with header actions
BaseRoleForm Form schema with tabbed permissions
BaseRoleInfolist Infolist schema for view page
BaseRolesTable Table columns and record actions

Example: Custom Table Actions

namespace App\Filament\Admin\Resources\Roles\Tables;

use Filament\Actions\ViewAction;
use Filament\Tables\Table;
use Waguilar\FilamentGuardian\Base\Roles\Tables\BaseRolesTable;

class RolesTable extends BaseRolesTable
{
    public static function configure(Table $table): Table
    {
        return parent::configure($table)
            ->recordActions([
                ViewAction::make(),
            ]);
    }
}

Example: Custom View Page

namespace App\Filament\Admin\Resources\Roles\Pages;

use App\Filament\Admin\Resources\Roles\RoleResource;
use Filament\Actions\ActionGroup;
use Filament\Actions\EditAction;
use Filament\Actions\DeleteAction;
use Waguilar\FilamentGuardian\Base\Roles\Pages\BaseViewRole;

class ViewRole extends BaseViewRole
{
    protected static string $resource = RoleResource::class;

    protected function getHeaderActions(): array
    {
        return [
            ActionGroup::make([
                EditAction::make(),
                DeleteAction::make(),
            ]),
        ];
    }
}

Using the Facade

use Waguilar\FilamentGuardian\Facades\Guardian;

TextInput::make('name')
    ->required()
    ->unique(
        ignoreRecord: true,
        modifyRuleUsing: Guardian::uniqueRoleValidation(),
    )

Translations

Filament Guardian ships with English and Spanish translations. To customize labels, publish the translation files:

php artisan vendor:publish --tag=filament-guardian-translations

This publishes to lang/vendor/filament-guardian/{locale}/filament-guardian.php.

The translation file includes:

  • roles.* - Role resource labels, sections, tabs, and messages
  • users.permissions.* - User direct permissions modal labels
  • actions.* - Permission action labels (viewAny, create, update, etc.)
  • custom.* - Custom permission label overrides
  • super_admin.* - Super admin role messages

Testing

composer test
composer analyse
composer lint

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.