RBAC - v1.0.0

Events

The package emits two families of events: Eloquent observer events on the models, and pivot events on HasRoles assignment / removal.

All event names use the rbac. prefix and Laravel's string-event syntax — listen for them via Event::listen('rbac.role.created', $listener) or in EventServiceProvider::$listen.

Observer events

Dispatched by RoleObserver and PermissionObserver (attached to the configured model classes in the service provider).

Event Payload Source
rbac.role.created Role $role RoleObserver::created
rbac.role.updated Role $role RoleObserver::updated
rbac.role.deleted Role $role RoleObserver::deleted
rbac.permission.created Permission $permission PermissionObserver::created
rbac.permission.updated Permission $permission PermissionObserver::updated
rbac.permission.deleted Permission $permission PermissionObserver::deleted

Pivot events

Laravel does not fire Eloquent events on pivot operations, so these are dispatched directly from the HasRoles trait.

Event Payload Source
rbac.user.role_assigned Authenticatable $user, Role $role HasRoles::assignRole
rbac.user.role_removed Authenticatable $user, Role $role HasRoles::removeRole

These fire only when the assignment / removal actually changes state (the trait is idempotent — assigning a role a user already holds is a no-op and does not fire the event).

Listening

use Illuminate\Support\Facades\Event;

Event::listen('rbac.user.role_assigned', function ($user, $role) {
    logger()->info("User {$user->id} assigned role {$role->slug}");
});

Event::listen('rbac.role.deleted', function ($role) {
    logger()->warning("Role {$role->slug} was deleted");
});

Or in EventServiceProvider:

protected $listen = [
    'rbac.user.role_assigned' => [
        LogRoleAssignment::class,
    ],
    'rbac.role.deleted' => [
        AlertOnRoleDeletion::class,
    ],
];

Use cases

Audit loggingartisanpack-ui/security-analytics subscribes to all six observer events and both pivot events to maintain an audit trail of authorization changes.

Cache invalidation in downstream packages — if you cache derived data based on roles or permissions (e.g. a precomputed permission list per organisation), subscribe to the observer events and flush your cache there.

Notifications — listen for rbac.user.role_assigned to notify the user they've been granted a new role.

Sync to external systems — sync role assignments to an external SSO or IdP by listening for the pivot events.

Direct pivot mutations

If you mutate the role_user pivot directly (e.g. $user->roles()->attach($id) instead of $user->assignRole(...)), the pivot events do not fire. Always prefer assignRole() / removeRole() unless you have a specific reason to bypass them. When you do bypass them, call $user->flushPermissionCache() afterwards so the permission cache stays consistent.