tamas1979 / laravel-permission-audit
Professional grant/revoke audit trail and capability blocks for spatie/laravel-permission
Package info
github.com/Tamas1979/laravel-permission-audit
pkg:composer/tamas1979/laravel-permission-audit
Requires
- php: ^8.2
- illuminate/database: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
- spatie/laravel-permission: ^6.0|^7.0|^8.0
Requires (Dev)
- orchestra/testbench: ^9.0|^10.0|^11.0
- pestphp/pest: ^3.0|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
This package is auto-updated.
Last update: 2026-08-13 01:59:38 UTC
README
A simple and reusable Laravel package for Spatie permission/role audit trails and capability blocks.
This package records who granted or revoked a permission or role, when, and why, and can block re-apply of a revoked capability until an admin lifts the block.
It works alongside spatie/laravel-permission — it does not replace it.
It is not a general activity log. Use it when you need audit + block semantics for Spatie abilities.
Features
- Audit trail: append-only history of grant / revoke / assign / remove / block / unblock
- Capability blocks: prevent re-grant via the Auditor API while a block is active
- Spatie event logging: optional listeners write audits for direct Spatie calls
- Facade + service:
PermissionAuditfacade or injectPermissionAuditor - Lightweight: minimal setup, depends only on Laravel + Spatie Permission
Installation
Require the package via Composer (and Spatie Permission if you do not have it yet):
composer require tamas1979/laravel-permission-audit
Configuration
Publish the config file:
php artisan vendor:publish --provider="Tamas1979\PermissionAudit\PermissionAuditServiceProvider" --tag=permission-audit-config
The default config:
return [ 'tables' => [ 'audits' => 'permission_audits', 'blocks' => 'permission_blocks', ], // Log direct Spatie givePermissionTo / assignRole / etc. 'listen_spatie_events' => true, // Callable that returns the actor model (or null). Default: auth()->user() 'actor_resolver' => null, // PermissionAuditor::grant* refuses when an active block exists 'enforce_blocks_on_grant' => true, ];
Setup
- Run migrations
The package ships migrations for permission_audits and permission_blocks.
Just run:
php artisan migrate
- Migrations load automatically from the package
- Publish them only if you need to customize:
php artisan vendor:publish --provider="Tamas1979\PermissionAudit\PermissionAuditServiceProvider" --tag=permission-audit-migrations
- Spatie Permission
Your user (or other subject) model must already use Spatie’s HasRoles (or equivalent). This package calls Spatie’s grant/revoke APIs under the hood.
For automatic event logging of direct Spatie calls (givePermissionTo, assignRole, …), Spatie 8+ also needs events turned on in config/permission.php:
'events_enabled' => true,
Without this, listen_spatie_events has nothing to listen to — Spatie does not dispatch attach/detach events by default.
Usage
Grant / revoke (preferred API)
use Tamas1979\PermissionAudit\Facades\PermissionAudit; use Tamas1979\PermissionAudit\AbilityType; // Grant with reason (audited; refuses if an active block exists) PermissionAudit::grantPermission($user, 'products.create', reason: 'Accepted creator terms'); // Revoke and block automatic re-apply PermissionAudit::revokePermission( $user, 'products.create', reason: 'Repeated bad product data', blockReapply: true, ); // Check before your own onboarding / self-service flow if (PermissionAudit::isPermissionBlocked($user, 'products.create')) { // show “suspended — contact support” } // Admin lifts the block PermissionAudit::unblock( $user, AbilityType::PERMISSION, 'products.create', reason: 'Appeal accepted', );
Roles work the same way:
PermissionAudit::assignRole($user, 'moderator', reason: 'Promoted by admin'); PermissionAudit::removeRole($user, 'moderator', reason: 'Demoted', blockReapply: false);
Automatic Spatie event logging
When listen_spatie_events is true (default) and Spatie’s permission.events_enabled is true, direct calls such as $user->givePermissionTo(...) / assignRole(...) are also written to permission_audits with source = spatie_event.
Spatie 8+ ships with events_enabled => false. Set it to true or the listener will never run.
Auditor methods silence that listener so you do not get duplicate rows.
Important: blocks vs direct Spatie
| Path | Audited? | Block enforced? |
|---|---|---|
PermissionAudit::grantPermission(...) |
yes (source = auditor) |
yes (if enforce_blocks_on_grant) |
$user->givePermissionTo(...) |
yes (if listeners on) | no — bypasses Auditor |
Use the Auditor API for any flow where blocks must stick. Gate or wrap direct Spatie calls yourself if you need hard enforcement everywhere.
Tables
| Table | Purpose |
|---|---|
permission_audits |
Append-only history |
permission_blocks |
Active / lifted blocks |
Contribution
- Open for ideas, bug fixes, and feature requests
- Supports Laravel 11, 12, and 13
- Requires PHP 8.2+ and
spatie/laravel-permission6+
License
MIT