Audit log : traçabilité des actions
Toutes les actions sensibles sont tracées (qui, quand, où).
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 :
- Sécurité — détecter une compromission ou un comportement anormal
- Conformité — justifier d'une bonne gouvernance vis-à-vis du RGPD et des standards comptables
- 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
UPDATEn'est jamais émis : un évènement enregistré ne peut pas être modifié. - Aucun
DELETEn'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/DELETEsur cette table.
Schéma d'un évènement
Chaque ligne contient :
| Champ | Type | Description |
|---|---|---|
id | uuid | Identifiant unique |
created_at | timestamptz | Quand (UTC, précision microseconde) |
actor_user_id | uuid | Qui (nullable pour évènements système) |
actor_email | text | Email à l'instant T (snapshot) |
cabinet_id | uuid | Cabinet concerné |
action | enum | Action effectuée (voir liste ci-dessous) |
entity_type | text | Type d'entité ciblée (dossier, member, etc.) |
entity_id | uuid | Identifiant de l'entité |
ip | inet | Adresse IP de l'acteur |
user_agent | text | User-Agent du navigateur |
payload_after | jsonb | É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_successauth.login_failureauth.password_changeauth.password_reset_requestmfa.enrollmfa.disablemfa.reset_by_adminsession.revokesession.revoke_all
Dossiers
dossier.createdossier.updatedossier.deletedossier.duplicatedossier.export
Signature électronique
signature.sendsignature.cancelsignature.completedsignature.expired
Équipe et rôles
member.invitemember.accept_invitemember.suspendmember.deleterole.changerole.owner_transfer_outrole.owner_transfer_in
Cabinet et branding
cabinet.update_identitycabinet.update_brandingcabinet.delete
Facturation
plan.activateplan.changeplan.cancelbilling.update_detailsbilling.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
owneretmanagerdepuis 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).