DÉMO
dev only

Journal d'audit

Traçabilité complète des actions utilisateur, persistée en base et exposée via l'API REST.

Vue d'ensemble

Le journal d'audit enregistre chaque action significative dans la table audit_logs. Chaque entrée capture l'acteur (l'utilisateur), l'action, la cible (type + UUID), des métadonnées contextuelles et l'adresse IP.

Le système est piloté par le pattern Event Subscriber — les subscribers d'audit écoutent les événements métier existants sans modifier la logique applicative.

FichierRôle
src/Entity/Audit/AuditLog.phpEntité (UUID, actor, action enum, target_type, target_id, metadata JSON, ip_address)
src/Enum/AuditAction.php11 actions prédéfinies (auth, profil, organisation)
src/Service/Audit/AuditService.phpService central — méthode log() injectable partout
src/EventSubscriber/Audit/AuditAuthSubscriber.phpÉcoute les événements Auth + LoginSuccessEvent
src/EventSubscriber/Audit/AuditOrganizationSubscriber.phpÉcoute les événements Organisation
src/ApiResource/AuditLogResource.phpDTO API Platform
src/State/Api/AuditLogProvider.phpProvider — filtré sur l'org, Owner/Admin uniquement

Actions tracées

ActionDéclencheurMétadonnées
user_registeredUserRegisteredEventemail
user_loginLoginSuccessEventfirewall
user_email_verifiedUserEmailVerifiedEvent
password_reset_requestedPasswordResetRequestedEventemail
email_change_requestedEmailChangeRequestedEventnew_email
twofa_enabledÀ déclencher manuellement
twofa_disabledÀ déclencher manuellement
organization_createdOrganizationCreatedEventname, slug
member_invitedMemberInvitedEventemail, role, organization
member_joinedMemberJoinedEventorganization, role
profile_updatedÀ déclencher manuellement

Endpoint API

MéthodeURIAccès
GET /api/organizations/{id}/audit Owner ou Admin de l'organisation

Exemple de réponse

[
  {
    "id": "019e...",
    "actorId": "018f...",
    "actorName": "Benjamin Manguet",
    "action": "member_joined",
    "targetType": "organization",
    "targetId": "018e...",
    "metadata": { "organization": "Acme", "role": "member" },
    "ipAddress": "127.0.0.1",
    "createdAt": "2026-04-19T11:00:00+00:00"
  }
]

Les membres simples (member) reçoivent une 403 s'ils tentent d'accéder au journal — seuls les Owner et Admin peuvent lire l'audit de leur organisation.

Ajouter une action

1 — Ajouter un case dans AuditAction :

case ProfileUpdated = 'profile_updated';

2 — Appeler AuditService::log() depuis un subscriber ou un service :

$this->auditService->log(
    action: AuditAction::ProfileUpdated,
    actor: $user,
    targetType: 'user',
    targetId: (string) $user->getId(),
    metadata: ['fields' => 'firstName, lastName'],
    ipAddress: $request->getClientIp(),
);

3 — Ajouter la traduction dans translations/boilerplate.*.yaml sous la clé audit.action.profile_updated.

Loading…
Loading the web debug toolbar…
Attempt #