feat(cron): purge de retention audit_log + throttle (mlt 13.4/13.5)
All checks were successful
CI / secret-scan (push) Successful in 9s
CI / php-lint (push) Successful in 19s
CI / static-tests (push) Successful in 45s
CI / php-lint (pull_request) Successful in 25s
CI / static-tests (pull_request) Successful in 35s
CI / auto-merge (push) Has been skipped
CI / secret-scan (pull_request) Successful in 9s
CI / auto-merge (pull_request) Successful in 7s
All checks were successful
CI / secret-scan (push) Successful in 9s
CI / php-lint (push) Successful in 19s
CI / static-tests (push) Successful in 45s
CI / php-lint (pull_request) Successful in 25s
CI / static-tests (pull_request) Successful in 35s
CI / auto-merge (push) Has been skipped
CI / secret-scan (pull_request) Successful in 9s
CI / auto-merge (pull_request) Successful in 7s
Les vars de retention (AUDIT_LOG_RETENTION_DAYS, THROTTLE_PURGE_AFTER_HOURS) etaient documentees comme purges cron mais aucun script/job n'existait, et les vars n'etaient pas injectees au conteneur wakdo-cron (faux-semblant de conformite). - purge-audit-log.sh : DELETE audit_log au-dela de AUDIT_LOG_RETENTION_DAYS (defaut 365). Unique exception documentee a l'append-only (RG-T14) : purge de retention planifiee, pas une mutation applicative. - purge-throttle.sh : DELETE login_throttle + pin_throttle sans verrou actif et plus vieux que THROTTLE_PURGE_AFTER_HOURS (defaut 24), predicat mlt.md 13.5. - crontab : jobs actives (15 4 audit, 45 4 throttle), fenetre de maintenance. - docker-compose.yml : injection des 2 vars (avec defaut) au conteneur cron ; commentaire env aligne sur le user en moindre privilege. Hors scope : la purge de customer_order (ORDER_RETENTION_DAYS) reste differee tant que le domaine commande n'existe pas (RGPD = anonymisation a definir avec le domaine, pas un simple DELETE). Verifie : scripts lances dans l'image cron rebuildee contre la base dev (user scope) -> exit 0 ; test positif/negatif sur login_throttle : la ligne stale sans verrou est purgee, la ligne a verrou actif est conservee.
This commit is contained in:
parent
ad5203d3fc
commit
b9264f4ed7
4 changed files with 87 additions and 3 deletions
|
|
@ -263,14 +263,18 @@ services:
|
||||||
init: true
|
init: true
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
# Credentials BDD pour mysqldump (lecture seule via USER applicatif,
|
# Credentials BDD pour mysqldump et les purges. Le user applicatif est en
|
||||||
# PAS le root password). Le user applicatif doit avoir SELECT +
|
# moindre privilege (DML + SELECT/SHOW VIEW/TRIGGER/LOCK TABLES, jamais le
|
||||||
# LOCK TABLES + SHOW VIEW sur la BDD (migrations P2).
|
# root password ; cf. db/init/10-scope-app-user.sh).
|
||||||
DB_HOST: ${DB_HOST}
|
DB_HOST: ${DB_HOST}
|
||||||
DB_PORT: ${DB_PORT}
|
DB_PORT: ${DB_PORT}
|
||||||
DB_NAME: ${DB_NAME}
|
DB_NAME: ${DB_NAME}
|
||||||
DB_USER: ${DB_USER}
|
DB_USER: ${DB_USER}
|
||||||
DB_PASSWORD: ${DB_PASSWORD}
|
DB_PASSWORD: ${DB_PASSWORD}
|
||||||
|
# Retention des donnees (mlt.md 13.4/13.5). Defaut applique par les scripts
|
||||||
|
# ET ici, pour rester coherent si la var manque du .env.
|
||||||
|
AUDIT_LOG_RETENTION_DAYS: ${AUDIT_LOG_RETENTION_DAYS:-365}
|
||||||
|
THROTTLE_PURGE_AFTER_HOURS: ${THROTTLE_PURGE_AFTER_HOURS:-24}
|
||||||
TZ: ${CRON_TIMEZONE:-Europe/Paris}
|
TZ: ${CRON_TIMEZONE:-Europe/Paris}
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,12 @@
|
||||||
# 03h00 : dump BDD complet, compresse et rotate (garde 14 derniers).
|
# 03h00 : dump BDD complet, compresse et rotate (garde 14 derniers).
|
||||||
0 3 * * * /scripts/backup-db.sh 2>&1
|
0 3 * * * /scripts/backup-db.sh 2>&1
|
||||||
|
|
||||||
|
# 04h15 : purge de retention du journal d'audit (mlt.md 13.4, AUDIT_LOG_RETENTION_DAYS).
|
||||||
|
15 4 * * * /scripts/purge-audit-log.sh 2>&1
|
||||||
|
|
||||||
|
# 04h45 : purge des compteurs de throttle sans verrou actif (mlt.md 13.5, THROTTLE_PURGE_AFTER_HOURS).
|
||||||
|
45 4 * * * /scripts/purge-throttle.sh 2>&1
|
||||||
|
|
||||||
# Toutes les 15 min pendant la fenetre de maintenance : purge des sessions
|
# Toutes les 15 min pendant la fenetre de maintenance : purge des sessions
|
||||||
# PHP expirees cote BDD (pas les sessions systeme qui sont en /tmp du conteneur
|
# PHP expirees cote BDD (pas les sessions systeme qui sont en /tmp du conteneur
|
||||||
# wakdo-app, donc ephemeres par nature). A activer quand la table sessions
|
# wakdo-app, donc ephemeres par nature). A activer quand la table sessions
|
||||||
|
|
|
||||||
34
docker/cron/scripts/purge-audit-log.sh
Executable file
34
docker/cron/scripts/purge-audit-log.sh
Executable file
|
|
@ -0,0 +1,34 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Wakdo - purge de retention du journal d'audit (mlt.md 13.4).
|
||||||
|
#
|
||||||
|
# Supprime les lignes audit_log plus anciennes que AUDIT_LOG_RETENTION_DAYS
|
||||||
|
# (interet legitime / tracabilite fiscale, configurable). L'imputabilite recente
|
||||||
|
# est preservee. C'est l'unique exception documentee a l'append-only de audit_log
|
||||||
|
# (RG-T14) : une purge de retention planifiee, jamais une mutation applicative.
|
||||||
|
#
|
||||||
|
# Variables d'env (injectees par docker-compose depuis .env) :
|
||||||
|
# DB_HOST DB_PORT DB_NAME DB_USER DB_PASSWORD
|
||||||
|
# AUDIT_LOG_RETENTION_DAYS (defaut 365)
|
||||||
|
#
|
||||||
|
# Exit codes : 0 OK | 1 env manquant/invalide | 2 requete SQL echouee
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
log() { echo "[purge-audit-log $(date -Iseconds)] $*" >&2; }
|
||||||
|
|
||||||
|
for var in DB_HOST DB_PORT DB_NAME DB_USER DB_PASSWORD; do
|
||||||
|
if [ -z "${!var:-}" ]; then log "ERROR: variable $var vide ou non definie"; exit 1; fi
|
||||||
|
done
|
||||||
|
|
||||||
|
DAYS="${AUDIT_LOG_RETENTION_DAYS:-365}"
|
||||||
|
case "$DAYS" in
|
||||||
|
''|*[!0-9]*) log "ERROR: AUDIT_LOG_RETENTION_DAYS non entier ('$DAYS')"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if ! n="$(mariadb --host="$DB_HOST" --port="$DB_PORT" --user="$DB_USER" --password="$DB_PASSWORD" \
|
||||||
|
--default-character-set=utf8mb4 -N -B "$DB_NAME" \
|
||||||
|
-e "DELETE FROM audit_log WHERE created_at < NOW() - INTERVAL ${DAYS} DAY; SELECT ROW_COUNT();")"; then
|
||||||
|
log "ERROR: purge audit_log a echoue"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
log "audit_log: ${n} ligne(s) purgee(s) (> ${DAYS} jours)"
|
||||||
40
docker/cron/scripts/purge-throttle.sh
Executable file
40
docker/cron/scripts/purge-throttle.sh
Executable file
|
|
@ -0,0 +1,40 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Wakdo - purge des compteurs de throttle sans verrou actif (mlt.md 13.5).
|
||||||
|
#
|
||||||
|
# Borne la croissance de login_throttle (per-IP, RG-8) et pin_throttle
|
||||||
|
# (per-acteur, RG-T22) : supprime les lignes dont le verrou n'est plus actif
|
||||||
|
# ET dont la derniere tentative est plus ancienne que THROTTLE_PURGE_AFTER_HOURS.
|
||||||
|
# Les lignes servant encore un verrou actif sont conservees.
|
||||||
|
#
|
||||||
|
# Variables d'env (injectees par docker-compose depuis .env) :
|
||||||
|
# DB_HOST DB_PORT DB_NAME DB_USER DB_PASSWORD
|
||||||
|
# THROTTLE_PURGE_AFTER_HOURS (defaut 24)
|
||||||
|
#
|
||||||
|
# Exit codes : 0 OK | 1 env manquant/invalide | 2 requete SQL echouee
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
log() { echo "[purge-throttle $(date -Iseconds)] $*" >&2; }
|
||||||
|
|
||||||
|
for var in DB_HOST DB_PORT DB_NAME DB_USER DB_PASSWORD; do
|
||||||
|
if [ -z "${!var:-}" ]; then log "ERROR: variable $var vide ou non definie"; exit 1; fi
|
||||||
|
done
|
||||||
|
|
||||||
|
HOURS="${THROTTLE_PURGE_AFTER_HOURS:-24}"
|
||||||
|
case "$HOURS" in
|
||||||
|
''|*[!0-9]*) log "ERROR: THROTTLE_PURGE_AFTER_HOURS non entier ('$HOURS')"; exit 1 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
db() {
|
||||||
|
mariadb --host="$DB_HOST" --port="$DB_PORT" --user="$DB_USER" --password="$DB_PASSWORD" \
|
||||||
|
--default-character-set=utf8mb4 -N -B "$DB_NAME" -e "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# login_throttle et pin_throttle partagent le meme predicat (mlt.md 13.5).
|
||||||
|
for table in login_throttle pin_throttle; do
|
||||||
|
if ! n="$(db "DELETE FROM ${table} WHERE (lockout_until IS NULL OR lockout_until < NOW()) AND last_attempt_at < NOW() - INTERVAL ${HOURS} HOUR; SELECT ROW_COUNT();")"; then
|
||||||
|
log "ERROR: purge ${table} a echoue"
|
||||||
|
exit 2
|
||||||
|
fi
|
||||||
|
log "${table}: ${n} ligne(s) purgee(s) (sans verrou actif, > ${HOURS}h)"
|
||||||
|
done
|
||||||
Loading…
Add table
Reference in a new issue