Audit log : traçabilité des actions

Toutes les actions sensibles sont tracées (qui, quand, où).

Mis à jour le 1 mai 2026

PV-Express maintient un journal d'audit immuable de toutes les actions sensibles effectuées sur la plateforme. Cette traçabilité répond à trois objectifs :

  1. Sécurité — détecter une compromission ou un comportement anormal
  2. Conformité — justifier d'une bonne gouvernance vis-à-vis du RGPD et des standards comptables
  3. Support — investiguer un incident utilisateur (« qui a supprimé ce dossier ? »)

Stockage technique

Les évènements sont enregistrés dans la table pv_express.audit_log, en append-only :

  • Aucun UPDATE n'est jamais émis : un évènement enregistré ne peut pas être modifié.
  • Aucun DELETE n'est émis hors de la purge automatique d'expiration (voir Conservation).
  • Les permissions Postgres restreignent l'écriture aux services back-end ; aucun rôle utilisateur n'a INSERT/UPDATE/DELETE sur cette table.

Schéma d'un évènement

Chaque ligne contient :

ChampTypeDescription
iduuidIdentifiant unique
created_attimestamptzQuand (UTC, précision microseconde)
actor_user_iduuidQui (nullable pour évènements système)
actor_emailtextEmail à l'instant T (snapshot)
cabinet_iduuidCabinet concerné
actionenumAction effectuée (voir liste ci-dessous)
entity_typetextType d'entité ciblée (dossier, member, etc.)
entity_iduuidIdentifiant de l'entité
ipinetAdresse IP de l'acteur
user_agenttextUser-Agent du navigateur
payload_afterjsonbÉtat de l'entité après l'action (si pertinent)

Le payload before n'est volontairement pas stocké pour limiter le volume et éviter de dupliquer des données personnelles. Le payload after est un snapshot ciblé (uniquement les champs modifiés ou critiques), pas un dump complet.

Liste des actions tracées

Authentification et compte

  • auth.login_success
  • auth.login_failure
  • auth.password_change
  • auth.password_reset_request
  • mfa.enroll
  • mfa.disable
  • mfa.reset_by_admin
  • session.revoke
  • session.revoke_all

Dossiers

  • dossier.create
  • dossier.update
  • dossier.delete
  • dossier.duplicate
  • dossier.export

Signature électronique

  • signature.send
  • signature.cancel
  • signature.completed
  • signature.expired

Équipe et rôles

  • member.invite
  • member.accept_invite
  • member.suspend
  • member.delete
  • role.change
  • role.owner_transfer_out
  • role.owner_transfer_in

Cabinet et branding

  • cabinet.update_identity
  • cabinet.update_branding
  • cabinet.delete

Facturation

  • plan.activate
  • plan.change
  • plan.cancel
  • billing.update_details
  • billing.payment_method_update

Conservation

Les évènements sont conservés 1 an glissant (365 jours) à compter de leur création. Une tâche cron quotidienne (audit_log_purge) supprime les lignes dont created_at < now() - interval '365 days'.

Cette durée a été choisie comme équilibre entre :

  • Utilité forensique (la grande majorité des investigations remonte à moins de 6 mois)
  • Volume de données (un cabinet Pro génère ~50K lignes/an)
  • Conformité RGPD (principe de minimisation, art. 5.1.e)

Sur demande motivée (litige en cours, contrôle URSSAF, etc.), PV-Express peut prolonger la conservation ponctuellement pour un cabinet — voir le DPA.

Consultation

L'audit log d'un cabinet est consultable :

  • Côté cabinet : par les rôles owner et manager depuis Settings → Cabinet → Audit log. Filtres disponibles : période, acteur, type d'action, entité ciblée. Export CSV possible.
  • Côté PV-Express : par les super-admins uniquement, dans le cadre du support. Tout accès super-admin à un audit log de cabinet est lui-même tracé dans un audit log méta (consultable par le DPO PV-Express).

Les collaborator n'ont pas accès à l'audit log : c'est un outil de gouvernance réservé aux responsables du cabinet.

Cas d'usage typiques

« Qui a supprimé ce dossier ? » Filtrer par action = dossier.delete et entity_id = <uuid du dossier>. Vous obtenez l'utilisateur, l'horodatage et l'IP.

« Y a-t-il eu des connexions depuis l'étranger ce mois-ci ? » Filtrer par action = auth.login_success et croiser avec la géolocalisation des IP (export CSV + traitement Excel).

« Mon collaborateur a quitté le cabinet, que s'est-il passé sur son dernier mois ? » Filtrer par actor_user_id = <uuid du collaborateur> sur les 30 derniers jours.

« Le cabinet est-il bien revenu en plan Starter après l'essai Pro ? » Filtrer par action IN (plan.activate, plan.change, plan.cancel) pour reconstituer l'historique des changements de plan.

Garanties d'intégrité

  • Tous les évènements sont écrits dans la même transaction que l'action métier qu'ils décrivent. Si l'action est rollback, l'évènement audit l'est aussi (cohérence garantie).
  • Les évènements sont répliqués en quasi-temps réel sur le réplica Postgres en lecture (RPO < 5 secondes).
  • Les sauvegardes quotidiennes incluent l'audit log au même titre que les autres tables (rétention 30 jours, voir DPA).