Skip to content

Journal d'audit

Toute action mutante (POST / PUT / PATCH / DELETE) sur /admin/* est journalisée automatiquement par AdminAuditMiddleware, monté au niveau du groupe admin — aucune action n’a besoin d’être modifiée. Les GET (lectures : stats, santé, listes) ne sont pas tracés pour ne pas noyer le signal.

Le middleware enveloppe toute la pile : il observe le statut final, y compris les 403 d’auth refusée (un essai non autorisé est aussi un événement de sécurité conservé).

Stockage : base SQLite locale var/admin_audit.sqlite (hors MySQL), via AdminAuditLogger. Choix délibéré : zéro dépendance, fichier unique archivable, requêtable (contrairement à un log plat), et fonctionne même si MySQL est injoignable. Écriture best-effort : un échec d’audit n’interrompt jamais l’action admin (erreur envoyée dans error_log).

Schéma (table admin_audit, créée automatiquement au premier write) :

ColonneTypeDescription
idINTEGER PKauto-incrément
created_atTEXTISO 8601
methodTEXTPOST / PUT / PATCH / DELETE
pathTEXTchemin appelé (ex. /admin/media/{hex}/published)
queryTEXTquery string (ou null)
statusINTEGERstatut HTTP final (inclut les 403)
ipTEXTREMOTE_ADDR (pas de X-Forwarded-For)
token_fpTEXTempreinte du token (12 hex de SHA-256), jamais le token brut — null si absent
user_agentTEXTen-tête User-Agent (ou null)

Le token_fp permet de corréler les actions d’un même appelant sans stocker le secret. Quand des tokens par opérateur existeront, l’empreinte pointera vers un opérateur nommé.

Consulter le journal : via l’API, l’endpoint GET /admin/audit (filtres + pagination keyset). Ou en lecture directe SQLite (ex. les 20 dernières actions) :

Terminal window
sqlite3 var/admin_audit.sqlite \
"SELECT created_at, method, path, status, ip, token_fp FROM admin_audit ORDER BY id DESC LIMIT 20;"