andika/tameng

Custom Filament plugin for role and permission management

Maintainers

Package info

github.com/andikarekatias/tameng

pkg:composer/andika/tameng

Transparency log

Fund package maintenance!

andika

Statistics

Installs: 2

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

1.0.0 2026-08-24 08:30 UTC

This package is auto-updated.

Last update: 2026-08-24 08:31:20 UTC


README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Tameng adds role & permission management to your Filament panels on top of spatie/laravel-permission.

Features

  • 🛡️ Role Management — manage roles and permissions from a single page with embedded permission cards
    • 📦 Resource Permissions
    • 📄 Page Permissions
    • 🧩 Widget Permissions
    • ✨ Custom Permissions
  • 🤖 Automatic Permission Generation — scans panels and creates permissions by convention
    • 📜 Policy generation from publishable stubs
    • 🏷️ Configurable case formatting (snake, kebab, pascal, camel, upper_snake)
    • 🔗 Entity discovery across all panels
  • 👑 Super Admin Bypass — users with the configured role skip all authorization checks
  • 🔄 Multi-tenancy Support — automatic tenant scoping with spatie teams + Filament panel tenancy
  • 🎨 Intuitive UI — Shield-inspired card grid layout with icons per entity type
  • Fine-grained CLI Tooling — install, generate, and super-admin commands

Requirements

  • PHP ^8.2
  • Laravel 11+
  • Filament 5.x (panels)
  • spatie/laravel-permission ^8.0

Installation

Install the package and run the installer:

composer require andika/tameng
php artisan tameng:install

The installer publishes Spatie's config/permission.php and the create_permission_tables migration, publishes our config/tameng.php, and asks whether you want to run php artisan migrate. After installation, it shows next steps:

tameng has been installed!

Next Steps:
  1. php artisan tameng:generate
     Generate permissions for your Filament panels
  2. php artisan tameng:super-admin user@email.com
     Assign super admin to a user
  3. php artisan permission:cache-reset
     Clear permission cache

Add the HasRoles trait to your User model:

use Spatie\Permission\Traits\HasRoles;

class User extends Authenticatable
{
    use HasRoles;
}

Register the plugin on your panel provider:

use Andika\Tameng\TamengPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugin(TamengPlugin::make());
}

Usage

Quickstart

php artisan tameng:super-admin     # create your first admin (interactive)
php artisan tameng:generate        # permissions + policies for panel entities
php artisan permission:cache-reset # refresh the spatie cache

Log in at your panel's URL (e.g. /dashboard) — the Tameng navigation item appears in the sidebar. Open it to manage roles and their permissions via embedded permission cards.

Super admin role

Users with the role configured in config/tameng.php bypass every authorization check:

'super_admin' => [
    'enabled' => false,  // set to true to enable the bypass
    'name' => 'super_admin',
],

Set enabled to true to activate the bypass — any user with this role skips all authorization checks. The role then behaves like any other when disabled.

Assign the role from the command line:

php artisan tameng:super-admin

The command picks a panel from --panel (falling back to the current or the only registered panel), then:

  • --user= — the ID of the user to promote (no prompt)
  • no users — asks for a name, email and password and creates the user before assigning the role
  • one user — promotes them automatically
  • multiple users — lists them and asks for the ID to promote
php artisan tameng:super-admin --panel=admin --user=1

With spatie teams enabled, pass the team/tenant the role should be scoped to:

php artisan tameng:super-admin --tenant=1

Or do it in code:

Role::findOrCreate('super_admin');
$user->assignRole('super_admin');

Permissions & policies

Generate permissions and policies for every entity registered in your panels:

php artisan tameng:generate

This creates permissions such as user_view_any, user_view, user_create, user_update, user_delete, user_delete_any and writes app/Policies/UserPolicy.php:

namespace App\Policies;

class UserPolicy
{
    public function viewAny($user): bool
    {
        return $user->can('user_view_any');
    }

    public function view($user, $model): bool
    {
        return $user->can('user_view');
    }

    // ...
}

Existing policies are never overwritten unless you pass --force:

php artisan tameng:generate --force

Generate permissions for a single panel only:

php artisan tameng:generate --panel=admin

Policies are rendered from a stub. To customize the generated policy shape, publish the stub and edit it (placeholders: {namespace}, {class}, {methods}):

php artisan vendor:publish --tag="tameng-stubs"

After changing permissions, refresh the permission cache:

php artisan permission:cache-reset

Configuration

All options live in config/tameng.php. Publish it with:

php artisan vendor:publish --tag="tameng-config"

Permission builder

'permission' => [
    'separator' => '_',
    'case' => 'snake',       // snake|kebab|pascal|camel|upper_snake|lower_snake
    'generate' => true,      // false skips permission creation (policies still written)
    'name_max_length' => 255,
],

Separator + case constraint: _ cannot pair with snake/upper_snake, - cannot pair with kebab. Examples: pascal + :User:ViewAny; kebab + -user-view-any.

Slug

The URL path for the role management page. Defaults to tameng (e.g. /dashboard/tameng):

'slug' => 'tameng',   // → /dashboard/tameng

Excludes

Skip entities from permission generation:

'resources' => [
    'subject' => 'model',    // 'model' uses the resource's model class name
    'exclude' => [
        // \App\Filament\Resources\FooResource::class,
    ],
],

'pages' => [
    'exclude' => [
        \Filament\Pages\Dashboard::class,
    ],
],

'widgets' => [
    'exclude' => [
        \Filament\Widgets\AccountWidget::class,
        \Filament\Widgets\FilamentInfoWidget::class,
    ],
],

Custom permissions

Extra permission keys created by tameng:generate alongside entity-derived permissions:

'custom_permissions' => [
    'system_backup',
    'audit_log',
],

Policies

'policies' => [
    'path' => app_path('Policies'),
    'namespace' => 'App\\Policies',
    'methods' => [
        'view_any', 'view', 'create', 'update', 'delete',
        'delete_any', 'restore', 'restore_any',
        'force_delete', 'force_delete_any',
    ],
    'single_parameter_methods' => [
        'view_any', 'create', 'delete_any',
        'restore_any', 'force_delete_any',
    ],
],

Methods in single_parameter_methods generate ($user) signatures; others generate ($user, $model).

Set register_role_policy to true to generate a RolePolicy for the spatie Role model and register it with Gate::policy:

'register_role_policy' => true,

Tenant model

Tameng integrates with Filament's multi-tenancy system and spatie teams. When both are enabled:

  1. A SyncTenant middleware automatically syncs the spatie team ID from the current Filament tenant
  2. The role list is scoped to the current tenant
  3. New roles are automatically associated with the current tenant
  4. Permission cache is only invalidated when the tenant changes

Setup:

  1. Enable spatie teams in config/permission.php:
'teams' => true,
  1. Set your tenant model in config/tameng.php:
'tenant_model' => App\Models\Team::class,
  1. Register the tenant on your Filament panel:
use App\Models\Team;

return $panel
    ->tenant(Team::class)
    ->plugin(TamengPlugin::make());
  1. Make your User model implement Filament\Models\Contracts\HasTenants:
use Filament\Models\Contracts\HasTenants;
use Filament\Panel;

class User extends Authenticatable implements HasTenants
{
    use HasRoles;

    public function tenants(Panel $panel): Collection
    {
        return $this->teams;
    }

    public function canAccessTenant(Model $tenant): bool
    {
        return true;
    }
}
  1. Assign roles scoped to a tenant via CLI:
php artisan tameng:super-admin --user=1 --tenant=1

Entity discovery

When enabled (default), tameng:generate scans every registered panel and generates permissions and policies for all of its resources, pages and widgets. Disable globally via config or per-panel via the plugin API:

'entity_discovery' => true,
TamengPlugin::make()
    ->entityDiscovery(false);   // disable for this panel only

Localization

Translated permission labels in the role editor:

'localization' => [
    'enabled' => false,
    'key' => 'tameng::tameng.permissions',
],

Publish translations:

php artisan vendor:publish --tag="tameng-translations"

Plugin configuration

Per-panel overrides via the plugin API:

TamengPlugin::make()
    ->superAdminRole('super_admin')   // per-panel role name override
    ->entityDiscovery(false);         // disable entity scanning in tameng:generate

Testing

composer test

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.