Journal d’audit
Ce que le journal d’audit enregistre, ce qu’il n’enregistre pas, qui peut le lire et quelles garanties il offre.
Ce qui est enregistré
Le journal est alimenté de quatre façons.
1. Les modifications de données. Les créations, modifications et suppressions faites par un utilisateur de l’organisation produisent une entrée (hors sessions, jetons, historique des mots de passe et appareils de double authentification ; les réaffectations en masse lors de la suppression d’un utilisateur ne sont tracées que par l’événement user.deleted), avec :
- l’action, sous la forme
<type>.created,<type>.updatedou<type>.deleted(par exemplecontrol.updated) ; - le type et l’identifiant de la ressource, son nom ou titre lorsqu’elle en a un, l’entité concernée ;
- l’identifiant et l’e-mail de l’utilisateur, son adresse IP et son navigateur (User-Agent) ;
- la date et l’heure (UTC) ;
- les modifications : les valeurs créées, les valeurs avant et après des seuls champs modifiés, ou les valeurs supprimées.
Les valeurs sensibles (mots de passe, jetons, secrets, codes de double authentification, clés) sont remplacées par ***. Dans les modifications, les énumérations apparaissent sous leur valeur numérique (par exemple le statut d’un contrôle).
2. Chaque requête d’écriture réussie. Une seconde entrée, plus sommaire, est ajoutée pour chaque requête POST, PUT, PATCH ou DELETE réussie : action create, update ou delete, type de ressource déduit de l’adresse, adresse IP. Seules les requêtes à l’API (/api/…) en produisent : la connexion aux notifications en temps réel n’en produit plus (les entrées « create negotiate » enregistrées avant cette évolution restent au journal). Ces entrées enregistrent l’identifiant de l’utilisateur, mais pas son e-mail. Elles portent l’entité lorsque la requête vise une adresse d’entité (/api/v1/entities/{entityId}/…) ; les entrées enregistrées avant cette évolution n’en portent aucune. Pour les éléments qui n’ont pas d’entité propre (actions de traitement d’un risque, journal et notifications d’un incident…), l’entrée de type 1 n’a pas d’entité : cette entrée sommaire est alors la seule rattachée à l’entité.
3. Des événements métier, par exemple framework.upgrade.accepted (mise à jour de référentiel acceptée), gap_analysis.responses_saved, control_definition.custom_created, ou les événements liés aux invitations, aux utilisateurs et à leurs rôles.
4. Le renouvellement des clés de double authentification, les changements et la réinitialisation des mots de passe, seuls événements de la catégorie « Authentification » :
auth.2fa_reenrolled: le renouvellement obligatoire d’une clé de double authentification à la connexion (utilisateur, adresse IP, navigateur, motif).auth.password_reset_requested: une demande de lien « mot de passe oublié » pour un compte de l’organisation. Les modifications indiquent si l’e-mail est parti (EmailSent:truepour un compte actif,falsepour un compte désactivé, qui ne reçoit pas de lien). Une demande pour une adresse qui ne correspond à aucun compte n’est enregistrée nulle part.auth.password_reset: le mot de passe a été réinitialisé avec un lien ; les modifications indiquent le nombre de sessions fermées (RevokedSessions).auth.password.changed: un mot de passe a changé, quel que soit le parcours, indiqué parSource:profile(depuis le profil),forced(à l’étape de changement imposée à la connexion, avec sa raisonReason) oureset(lien « mot de passe oublié », en plus deauth.password_reset). Pourprofileetforced,RevokedSessionsindique le nombre d’autres sessions fermées. Filtrer sur cette action donne donc tous les changements de mot de passe.auth.password.change_required: une connexion a été arrêtée à l’étape de changement de mot de passe, après tous les facteurs ;Reasonvautexpired(mot de passe expiré selon la politique de l’organisation) ounoncompliant(mot de passe qui ne respecte plus cette politique). Une entrée est écrite à chaque connexion qui atteint l’étape.auth.session.started: une session a été ouverte (connexion réussie, inscription ou acceptation d’une invitation par un nouveau compte) ; les modifications indiquent son identifiant (SessionId) et la politique de session alors en vigueur (MaxDurationHours,InactivityTimeoutMinutes).auth.session.ended: la plateforme a fermé une session, avec sa raisonReason:idle(délai d’inactivité dépassé),max_duration(durée maximale atteinte),token_expired(le renouvellement est arrivé trop tard : le jeton de renouvellement avait expiré avant la durée maximale),password_expired(mot de passe expiré),sign_in_step_required(renouvellement de la clé de double authentification dû) outoken_reuse(jeton de renouvellement réutilisé après avoir été remplacé, signe possible d’un vol : la session est fermée). L’entrée est écrite quand la fin est constatée, c’est-à-dire à la première requête refusée ou au premier renouvellement refusé qui présente la session (elle n’est écrite qu’une fois, et un assouplissement ultérieur de la politique ne rouvre pas la session) ; une session abandonnée dont plus personne ne présente de jeton n’en laisse pas.auth.refresh.superseded: un jeton de renouvellement venait d’être remplacé par une autre requête du même navigateur (même adresse IP et même user agent, moins de 30 secondes), typiquement deux onglets qui renouvellent en même temps ; rien n’est révoqué. Une rafale d’entrées isolées, ou répétée à un rythme anormal, mérite un coup d’œil. Le même jeton présenté depuis une autre adresse ou un autre navigateur ferme la session (token_reuse).auth.session.revoked: l’utilisateur a fermé l’une de ses sessions depuis son profil (SessionId).auth.logout: l’utilisateur s’est déconnecté (SessionId).
Pour ces événements, l’utilisateur et la ressource sont le compte concerné ; l’adresse IP et le navigateur sont ceux de la personne qui a fait la demande, suivi le lien ou changé le mot de passe.
Les modifications de la politique de mots de passe de l’organisation (Paramètres › Sécurité) sont tracées par l’événement organization.password_policy.updated, avec les valeurs avant et après (MinLength, ExpirationDays, HistoryCount) ; un enregistrement qui ne change aucune valeur n’en écrit pas. Celles de la politique de session le sont par organization.session_policy.updated (MaxDurationHours, InactivityTimeoutMinutes), selon la même règle.
Ce qui n’est pas enregistré
- Les consultations : les lectures ne sont pas tracées, notamment les téléchargements de rapports et l’export CSV du journal. En revanche, la génération et l’aperçu d’un rapport laissent une entrée, ainsi que l’export JSON d’une version de référentiel personnalisé ou de modèle de questionnaire.
- Les échecs d’authentification : un mot de passe ou un code refusé n’est pas tracé. La catégorie « Authentification » du filtre renvoie les sessions ouvertes, fermées, révoquées et les déconnexions, les renouvellements de clé de double authentification (
auth.2fa_reenrolled), les changements et la réinitialisation des mots de passe, et les changements imposés à la connexion. Les sessions fermées par un changement ou une réinitialisation de mot de passe sont comptées dans ces événements (RevokedSessions), sans entrée par session. - Les traitements automatiques (tâches planifiées, génération des instantanés mensuels) et les actions effectuées depuis les pages publiques (portail fournisseur, Trust Center public).
- Les actions des administrateurs de la plateforme Conformitly sur les catalogues maîtres : elles sont tracées dans un journal propre à la plateforme, qui n’apparaît pas dans celui de l’organisation.
Identifier l’auteur
Le nom et l’e-mail de l’utilisateur sont retrouvés à partir de son identifiant, dans la liste, le détail d’une entrée et l’export CSV, y compris pour les entrées de type 2 (requêtes d’écriture). Il s’agit du nom actuel de l’utilisateur, pas de celui qu’il portait au moment de l’action. L’interface n’affiche « Système » que pour une entrée sans utilisateur. Le Rapport d’Audit retrouve lui aussi le nom de l’utilisateur à partir de son identifiant.
Qui peut le lire
| Rôle | Entrées visibles |
|---|---|
| Administrateur, RSSI | toute l’organisation : un Administrateur ou un RSSI, même d’une seule entité, voit les entrées de toutes les entités et les entrées de niveau organisation |
| Auditeur | les entrées rattachées aux entités sur lesquelles il est Auditeur, et seulement celles-là |
| Contributeur | aucun accès |
Pour l’Auditeur :
- Les entrées de niveau organisation ne sont pas visibles : celles qui ne portent aucune entité, c’est-à-dire les comptes utilisateurs, les invitations, les paramètres de l’organisation, la configuration du Trust Center, les référentiels et modèles personnalisés, les événements d’authentification, ainsi que les entrées sommaires (type 2) enregistrées sans entité. Elles concernent toute l’organisation et d’autres utilisateurs. La catégorie « Authentification » ne lui est donc pas proposée.
- Une entrée hors de son périmètre n’existe pas pour lui : son détail répond « introuvable ». La recherche, les filtres (y compris
entityIdpar l’API) et l’export CSV s’appliquent au même périmètre. - Un rôle Contributeur sur une autre entité n’élargit pas ce périmètre. Un rôle Administrateur ou RSSI sur n’importe quelle entité de l’organisation donne en revanche accès au journal entier.
- Les entrées d’une entité auditée montrent, comme pour l’Administrateur, le nom, l’e-mail, l’adresse IP et le navigateur de l’utilisateur qui a agi, ainsi que les attributions de rôles sur cette entité.
- Les entités archivées restent dans le périmètre tant que le rôle d’Auditeur y est conservé.
La piste d’audit d’une entité figure aussi dans le Rapport d’Audit (voir Rapports et exports).
Consulter et exporter
Dans l’application : Paramètres › Journal d’audit. L’onglet n’est proposé qu’aux Administrateurs, RSSI et Auditeurs ; un Auditeur y voit un rappel de son périmètre.
- Filtres : catégorie (Authentification, Utilisateurs, Entités, Contrôles, Risques, Incidents, Politiques, Actifs, Fournisseurs, Tâches, RGPD ; « Utilisateurs » regroupe les comptes, les rôles et les invitations, quelle que soit la forme de l’entrée), date de début, date de fin, recherche (insensible à la casse, sur l’action, le type, le nom de la ressource, le nom ou l’e-mail de l’utilisateur). La date de fin est comparée à minuit : pour inclure un jour entier, choisissez le lendemain.
- Le détail d’une entrée montre la date, l’action, l’utilisateur, le type, la ressource, l’entité, l’adresse IP, le navigateur et les modifications.
- Exporter CSV produit un fichier UTF-8 avec les colonnes
Date, User, Email, Action, ResourceType, ResourceName, Entity, IP, UserAgent. Les modifications (avant/après) et l’identifiant de la ressource ne sont pas exportés ; l’export tient compte des filtres de catégorie et de dates, mais pas de la recherche.
Par l’API : GET /api/v1/audit-logs (filtres entityId, category, userId, dateFrom, dateTo, search), GET /api/v1/audit-logs/{id}, GET /api/v1/audit-logs/export.
Garanties
- Pas de modification par l’application : aucune fonction de l’interface ni de l’API ne modifie ou ne supprime une entrée.
- Pas d’inaltérabilité prouvable : le journal est une table de la base de données de l’application, sans chaînage ni signature des entrées. Il trace les actions faites par l’application ; il ne prouve pas l’absence de modification directe en base.
- Conservation : aucune purge n’est programmée dans l’application.
Mise à jour : 10 octobre 2026. Signaler une inexactitude