Aller au contenu

RGPD en self-service (export / effacement)

Repod expose deux endpoints RGPD en self-service pour les données personnelles associées à un compte utilisateur : l'Article 15 (droit d'accès — export) et l'Article 17 (droit à l'effacement). Les deux sont utilisables directement par le titulaire du compte, ou par un administrateur agissant sur un autre compte.


1. Prérequis

  • Une session Repod connectée. Aucun rôle spécial n'est requis pour exporter ou effacer vos propres données.
  • Pour agir sur le compte de quelqu'un d'autre, l'appelant doit avoir le rôle admin.

2. Article 15 — Exporter vos propres données

Étape 1 — Appeler l'endpoint d'export

curl -H "Authorization: Bearer $JWT" \
  https://repod.example.com/api/v1/auth/users/alice/export
{
  "user": {
    "username": "alice",
    "full_name": "Alice Martin",
    "email": "[email protected]",
    "role": "maintainer",
    "created_at": "2025-11-02 09:14:00",
    "last_login": "2026-08-19 17:03:11",
    "auth_source": "local",
    "mfa_enabled": true
  },
  "api_tokens": [
    {"name": "ci-runner", "role": "uploader", "created_at": "...", "expires_at": null, "last_used": "..."}
  ],
  "audit_entries": [
    {"timestamp": "...", "action": "UPLOAD", "result": "SUCCESS", "user": "alice", "package": "nginx", "detail": "..."}
  ],
  "decisions": [
    {"package": "openssl", "version": "3.0.2", "action": "accept_risk", "justification": "...", "decided_at": "..."}
  ],
  "groups": [
    {"name": "security-team", "added_at": "..."}
  ]
}

L'export couvre : les champs du profil de compte, les jetons API que vous avez créés, chaque entrée du journal d'audit dont vous êtes l'utilisateur agissant, les décisions CVE que vous avez enregistrées, et les appartenances à des groupes. Il n'inclut pas votre empreinte de mot de passe ni votre secret MFA.

Qui peut appeler cet endpoint

requesting_user["username"] == username (exporter vos propres données) ou requesting_user["role"] == "admin" (un admin exportant les données de n'importe qui). Toute autre combinaison renvoie 403.


3. Article 17 — Effacer vos propres données (self-service)

L'effacement anonymise le compte plutôt que de supprimer purement et simplement la ligne — cela préserve la trace d'audit légalement requise tout en supprimant chaque champ identifiant personnellement.

Étape 1 — Appeler l'endpoint d'effacement avec votre mot de passe

curl -X DELETE https://repod.example.com/api/v1/auth/users/alice/gdpr \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{"password": "your-current-password"}'
{
  "status": "ok",
  "anonymized_as": "anonymized_a1b2c3d4",
  "message": "Données personnelles de alice anonymisées conformément au RGPD Art. 17."
}

Irréversible, et met fin à votre propre session

L'auto-effacement nécessite votre mot de passe actuel comme confirmation car elle est irréversible — votre nom d'utilisateur, votre nom complet, votre email et votre empreinte de mot de passe sont effacés, votre compte est désactivé, vos jetons API sont supprimés, et votre JWT existant cesse de fonctionner (le compte auquel il fait référence ne s'authentifie plus). Il n'y a pas de retour en arrière.

Ce que fait l'effacement, précisément

  • Ligne users : usernameanonymized_XXXXXXXX (aléatoire), full_name/email vidés, active = false, hashed_password effacé, secret TOTP/secret en attente/codes de récupération tous effacés (le MFA est également entièrement supprimé).
  • api_tokens créés par le compte : supprimés purement et simplement.
  • decision_records.decided_by : réécrit avec le même identifiant anonymisé (le fait qu'une décision CVE ait été prise est préservé à des fins d'audit ; l'identité derrière n'est pas conservée).
  • group_members.username : réécrit avec le même identifiant anonymisé.
  • Les entrées du journal d'audit ne sont jamais supprimées ni modifiées — exigence de traçabilité légale. Elles continuent de faire référence au nom d'utilisateur original tel qu'il a été enregistré au moment des faits ; c'est une caractéristique documentée et acceptée de l'anonymisation (l'historique d'audit passé est un registre historique, pas une donnée personnelle activement liée à un compte vivant à l'avenir).

Qui peut appeler cet endpoint

  • Le titulaire du compte (is_self), avec confirmation obligatoire par mot de passe dans le corps de la requête.
  • Un admin agissant sur un compte différent — aucune confirmation par mot de passe requise (même convention d'autorité que l'action admin classique delete_user()).

L'unique exception : les admins ne peuvent pas s'auto-effacer

{
  "detail": "Un administrateur ne peut pas supprimer son propre compte via cette voie (risque de verrouillage total du système) — demandez à un autre administrateur."
}

Si l'appelant est un admin effaçant son propre compte, la requête est rejetée avec 400, quel que soit le mot de passe. C'est un garde-fou délibéré : effacer le dernier (ou unique) compte admin verrouillerait de façon permanente toute l'installation hors de tout accès de niveau admin, sans voie de récupération. Un admin qui souhaite que ses propres données soient effacées doit demander à un second administrateur d'effectuer l'effacement en son nom.


4. Article 17 — Un admin effaçant le compte d'un autre utilisateur

curl -X DELETE https://repod.example.com/api/v1/auth/users/bob/gdpr \
  -H "Authorization: Bearer $ADMIN_JWT"

Aucun corps de requête n'est requis — un admin agissant sur le compte de quelqu'un d'autre saute entièrement l'étape de confirmation par mot de passe. La forme de la réponse est identique au cas self-service.


5. Vérifier que ça a fonctionné

  1. Export : confirmez que la réponse JSON inclut des données reconnaissables pour le compte (nom d'utilisateur, entrées d'audit, jetons) et renvoie 403 lorsqu'elle est appelée par un utilisateur non admin et non titulaire du compte.
  2. Auto-effacement : après avoir appelé DELETE .../gdpr avec votre mot de passe, confirmez que votre ancien JWT ne s'authentifie plus (GET /api/v1/auth/me avec le même jeton renvoie 401), et que GET /api/v1/auth/users (en tant qu'admin) affiche le compte sous son nouveau nom d'utilisateur anonymized_XXXXXXXX avec active: false.
  3. Blocage de l'auto-effacement admin : en tant qu'admin, appelez DELETE /api/v1/auth/users/<votre-propre-nom-utilisateur>/gdpr et confirmez que vous obtenez 400, pas 200.
  4. Trace d'audit préservée : confirmez que GET /api/v1/audit/logs?action=GDPR_DELETE affiche l'événement d'effacement lui-même, et que les entrées plus anciennes enregistrées sous le nom d'utilisateur désormais anonymisé sont toujours présentes et inchangées.