Control access to audit logs with fine-grained permissions
The role checker controls access to audit logs, allowing you to restrict who can view audits for specific entities.
The role checker is a callback that is invoked when someone attempts to read audit entries. It determines whether the current user has permission to view the requested audits.
[!WARNING] If access is denied, an
AccessDeniedExceptionis thrown.
<?php
use DH\Auditor\Configuration;
$configuration = new Configuration(['enabled' => true]);
$configuration->setRoleChecker(function (string $entity, string $scope): bool {
// $entity - The fully qualified class name of the entity being audited
// $scope - The action being performed (e.g., 'view')
// Return true to allow access, false to deny
return true;
});
<?php
use App\Entity\User;
use App\Entity\Payment;
use Symfony\Component\Security\Core\Security;
$configuration->setRoleChecker(function (string $entity, string $scope) use ($security): bool {
// Admins can view all audits
if ($security->isGranted('ROLE_ADMIN')) {
return true;
}
// Managers can view most audits
if ($security->isGranted('ROLE_MANAGER')) {
// But not User audits (sensitive)
return $entity !== User::class;
}
// Accountants can only view Payment audits
if ($security->isGranted('ROLE_ACCOUNTANT')) {
return $entity === Payment::class;
}
// Deny all other users
return false;
});
The role checker receives two parameters:
| Parameter | Type | Description |
|---|---|---|
$entity |
string |
The FQCN of the entity being queried |
$scope |
string |
The action scope (currently only 'view') |
| Scope | Constant | Description |
|---|---|---|
view |
Security::VIEW_SCOPE |
Viewing audit entries |
You can also define view permissions directly on entities using the #[Security] attribute:
<?php
use DH\Auditor\Attribute\Auditable;
use DH\Auditor\Attribute\Security;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[Auditable]
#[Security(view: ['ROLE_ADMIN', 'ROLE_AUDIT_VIEWER'])]
class SensitiveEntity
{
// ...
}
The role checker should then verify these roles:
<?php
$configuration->setRoleChecker(function (string $entity, string $scope) use ($security, $provider): bool {
// Get entity configuration (including security roles from attributes)
$configuration = $provider->getConfiguration();
$entities = $configuration->getEntities();
if (!isset($entities[$entity]['roles'][$scope])) {
// No specific roles defined, allow access
return true;
}
$requiredRoles = $entities[$entity]['roles'][$scope];
// Check if user has any of the required roles
foreach ($requiredRoles as $role) {
if ($security->isGranted($role)) {
return true;
}
}
return false;
});
<?php
$configuration->setRoleChecker(function (string $entity, string $scope) use ($security, $em): bool {
$user = $security->getUser();
if (null === $user) {
return false;
}
// Check ownership-based access for certain entities
switch ($entity) {
case Order::class:
// Users can view their own orders' audits
// Admins can view all
if ($security->isGranted('ROLE_ADMIN')) {
return true;
}
// This would need additional context about which order is being queried
return $security->isGranted('ROLE_ORDER_AUDITOR');
case User::class:
// Only super admins can view user audits
return $security->isGranted('ROLE_SUPER_ADMIN');
default:
// Default: allow managers and above
return $security->isGranted('ROLE_MANAGER');
}
});
<?php
$configuration->setRoleChecker(function (string $entity, string $scope) use ($security): bool {
// Only allow audit viewing during business hours for non-admins
if (!$security->isGranted('ROLE_ADMIN')) {
$hour = (int) date('H');
if ($hour < 9 || $hour > 17) {
return false;
}
}
return $security->isGranted('ROLE_AUDITOR');
});
When the role checker returns false, an AccessDeniedException is thrown:
<?php
use DH\Auditor\Exception\AccessDeniedException;
use DH\Auditor\Provider\Doctrine\Persistence\Reader\Reader; // from auditor-doctrine-provider
$reader = new Reader($provider);
try {
$query = $reader->createQuery(SensitiveEntity::class);
$audits = $query->execute();
} catch (AccessDeniedException $e) {
// Handle access denied
// $e->getMessage() contains details about the denial
}
[!CAUTION] If no role checker is configured (
null), all users have access to all audit logs. This is not recommended for production environments.
// This allows everyone to view all audits
$configuration = new Configuration([
'role_checker' => null, // No access control
]);
How can I help you explore Laravel packages today?