Aller au contenu

PD-31 — Spécification Fonctionnelle

1. Résumé exécutif

La story PD-31 met en place un audit log probatoire couvrant 100% des événements d'authentification sur les canaux ios, pwa et api. Chaque événement est journalisé de manière append-only, horodaté en UTC millisecondes, chaîné cryptographiquement (SHA3-256) et intégré au cycle d'ancrage Merkle/TSA/blockchain existant. La solution inclut un moteur de détection temps réel (bruteforce, geo-hopping, token spray, etc.), un scoring de risque par événement et la journalisation probatoire des alertes elles-mêmes. Elle fournit également un export judiciaire vérifiable de bout en bout avec preuve d'inclusion Merkle, jeton TSA et transaction blockchain, tout en respectant les exigences Zero-Knowledge, RGPD et NF Z42-013/ISO 14641.

2. Glossaire

  • Append-only : modèle d'écriture où seules des insertions sont autorisées.
  • Chaînage de hash : event_hash_n calculé avec event_hash_n-1 pour garantir l'intégrité séquentielle.
  • Preuve Composite : ensemble probatoire composé des logs, Merkle path, root, TSA token et ancrage blockchain.
  • TSA : Time Stamping Authority fournissant un horodatage certifié tiers de confiance.
  • Risk score : score numérique [0.0..1.0] reflétant le niveau de risque d'un événement auth.
  • Geo-hopping : connexions rapprochées depuis des pays différents pour un même sujet.
  • Credential stuffing : tentatives massives depuis une même IP vers plusieurs identités.
  • Cold storage : archivage longue durée (S3 Glacier) non orienté accès temps réel.
  • Correlation ID : identifiant transversal inter-services pour la traçabilité.
  • Identity level : niveau d'identité (email, oidc, enterprise).

3. Fonctionnalités

F-31-01 : Capture exhaustive des événements d'authentification

  • Description : Capturer et normaliser tous les événements auth listés (AUTH_LOGIN_SUCCESS, AUTH_LOGIN_FAILURE, AUTH_LOGOUT, AUTH_MFA_ATTEMPT, AUTH_MFA_SUCCESS, AUTH_MFA_FAILURE, AUTH_DEVICE_REVOKED, AUTH_TOKEN_INVALID) pour les canaux ios, pwa, api.
  • Acteurs : Service Auth, Service Session, API Gateway, Bus interne.
  • Prérequis : PD-24/25, PD-28 disponibles ; mapping des événements source → codes PD-31 configuré.
  • Flux nominal :
  • Le service auth émet un événement brut avec correlation_id.
  • Le composant Audit Auth enrichit les métadonnées (IP, UA, géolocalisation, channel, risk_score initial).
  • Un event_id UUIDv7 est généré.
  • L'événement normalisé est envoyé en file asynchrone de journalisation.
  • Flux alternatifs :
  • A1 : user_id inconnu (tentative sur identifiant inexistant) → user_id = NULL, identity_level renseigné si déterminable.
  • A2 : device_id indisponible → device_id = NULL, pas de rejet.
  • A3 : géolocalisation temporairement indisponible → geo_country = 'ZZ', geo_region = NULL, événement conservé.
  • A4 : payload source incomplet → rejet de normalisation avec code interne AUTH_AUDIT_NORMALIZATION_ERROR, métrique d'échec incrémentée.
  • Postconditions : Événement normalisé prêt à journalisation probatoire ou rejet explicite monitoré.
  • Critères d'acceptation :
  • CA-31-001 : 100% des 8 types d'événements auth définis produisent un enregistrement normalisé.
  • CA-31-002 : 100% des événements normalisés possèdent event_id, event_type, timestamp, channel, ip_address, user_agent, geo_country, success, correlation_id, risk_score.
  • CA-31-003 : Les tentatives sur identifiant inconnu sont persistées avec user_id IS NULL sans perte.
  • CA-31-004 : Le composant accepte simultanément les 3 canaux sans divergence de schéma.

F-31-02 : Journalisation append-only probatoire

  • Description : Persister chaque événement auth dans le journal append-only avec hash SHA3-256 et chaînage.
  • Acteurs : Audit Writer, PostgreSQL, Trigger d'intégrité.
  • Prérequis : Schéma SQL audit déployé ; trigger anti-update/delete actif.
  • Flux nominal :
  • Le worker lit la file asynchrone.
  • Il calcule event_hash en incluant la charge canonique + previous_hash.
  • Il insère la ligne en transaction ACID.
  • Il publie l'ack de persistance.
  • Flux alternatifs :
  • B1 : indisponibilité DB < 30s → retry exponentiel, pas de perte.
  • B2 : indisponibilité DB > 30s → mise en file durable, alerte WARNING.
  • B3 : violation contrainte DB → événement en dead-letter queue avec motif.
  • Postconditions : Événement immuable stocké, hashable et chaîné.
  • Critères d'acceptation :
  • CA-31-005 : Toute tentative SQL UPDATE ou DELETE sur auth_audit_log est bloquée par la base.
  • CA-31-006 : 100% des lignes insérées ont event_hash non nul sur 64 hex chars.
  • CA-31-007 : Pour N événements consécutifs, previous_hash de N = event_hash de N-1.
  • CA-31-008 : Le taux de perte d'événements est égal à 0 sur test de charge 1M événements.

F-31-03 : Intégration au cycle Merkle/TSA/blockchain

  • Description : Intégrer les événements auth au batch probatoire (10 min ou 1000 événements), avec ancrage TSA et blockchain.
  • Acteurs : Batcher Merkle (PD-39), Service TSA, Anchoring blockchain (PD-40).
  • Prérequis : Services PD-39/PD-40 opérationnels ; contrat d'interface batch disponible.
  • Flux nominal :
  • Les événements auth_audit_log marqués pending_anchor sont batchés.
  • Calcul du Merkle root et émission de preuve d'inclusion.
  • Root envoyé au TSA puis ancré blockchain.
  • Les références (merkle_root, tsa_token_ref, blockchain_tx_ref) sont liées aux événements.
  • Flux alternatifs :
  • C1 : échec TSA → statut anchor_partial, retry planifié.
  • C2 : échec blockchain → statut anchor_partial, retry planifié.
  • C3 : batch incomplet au timeout 10 min → clôture batch avec volume courant.
  • Postconditions : Événement rattaché à un batch d'ancrage ou en état de rattrapage tracé.
  • Critères d'acceptation :
  • CA-31-009 : Chaque événement persistant est rattaché à un batch_id en moins de 10 minutes ou 1000 événements.
  • CA-31-010 : 100% des événements en statut anchored possèdent merkle_root, tsa_token_ref, blockchain_tx_ref.
  • CA-31-011 : La vérification de Merkle path retourne true pour 100% des échantillons ancrés testés.
  • CA-31-012 : Les états d'échec TSA/blockchain sont visibles et retentés automatiquement.

F-31-04 : Scoring de risque par événement

  • Description : Calculer un risk_score [0..1] pour chaque événement auth en temps réel.
  • Acteurs : Risk Engine, Config Service.
  • Prérequis : règles de scoring versionnées ; cache contextuel accessible.
  • Flux nominal :
  • Le moteur charge les règles actives.
  • Il évalue le contexte (historique IP/user/device, patterns).
  • Il produit risk_score et facteurs contributifs.
  • Le score est persisté avec l'événement.
  • Flux alternatifs :
  • D1 : règles indisponibles → fallback version validée précédente.
  • D2 : contexte incomplet → score calculé sur facteurs disponibles, drapeau partial_context=true.
  • Postconditions : Chaque événement possède un score numérique exploitable.
  • Critères d'acceptation :
  • CA-31-013 : 100% des événements ont un risk_score numérique dans [0.0,1.0].
  • CA-31-014 : Les règles de scoring sont modifiables sans redéploiement applicatif.
  • CA-31-015 : Le calcul du score ajoute au plus 0.5 ms P99 au traitement asynchrone d'audit.
  • CA-31-016 : En mode fallback, le service trace explicitement la version de règles utilisée.

F-31-05 : Détection d'anomalies et alerting probatoire

  • Description : Détecter les patterns anormaux et déclencher des alertes (INFO, WARNING, CRITICAL) intégrées au cycle probatoire.
  • Acteurs : Alert Engine, Admin Notification Service, Auth Guard.
  • Prérequis : store de fenêtre temporelle (Redis ou PostgreSQL optimisé), seuils configurés.
  • Flux nominal :
  • Chaque événement auth est évalué contre les 5 patterns.
  • Si seuil atteint, une alerte est générée avec niveau et justification.
  • L'alerte est notifiée selon niveau.
  • L'alerte est journalisée comme événement probatoire.
  • Flux alternatifs :
  • E1 : faux positif identifié manuellement → ajustement de seuil, historisé.
  • E2 : incident critique en cascade → limitation des notifications (rate limit) sans perte de journalisation.
  • Postconditions : Alertes traçables, opposables et exploitables sécurité.
  • Critères d'acceptation :
  • CA-31-017 : Bruteforce déclenché si >5 échecs sur même user_id en 5 min.
  • CA-31-018 : Credential stuffing déclenché si >10 échecs même IP sur users distincts en 1 min.
  • CA-31-019 : Token spray déclenché si >20 AUTH_TOKEN_INVALID en 1 min.
  • CA-31-020 : Geo-hopping déclenché pour 2 pays différents à moins de 2h.
  • CA-31-021 : Délai détection + émission alerte < 1s P95.
  • CA-31-022 : 100% des alertes sont enregistrées en tant qu'événements probatoires.

F-31-06 : Contrôle d'accès audit et traçabilité de consultation

  • Description : Restreindre l'accès aux logs aux rôles ADMIN et AUDITOR, et journaliser toute consultation.
  • Acteurs : API Audit, IAM/RBAC, Journal de consultation.
  • Prérequis : rôles IAM existants ; middleware d'autorisation activé.
  • Flux nominal :
  • Un acteur authentifié appelle l'API audit.
  • RBAC valide le rôle.
  • Les données demandées sont retournées.
  • Une trace de consultation est enregistrée.
  • Flux alternatifs :
  • F1 : rôle insuffisant → 403 FORBIDDEN.
  • F2 : token invalide/expiré → 401 UNAUTHORIZED.
  • Postconditions : Accès conforme au moindre privilège et entièrement auditable.
  • Critères d'acceptation :
  • CA-31-023 : Les rôles hors ADMIN/AUDITOR reçoivent systématiquement 403.
  • CA-31-024 : 100% des consultations réussies créent une trace de consultation.
  • CA-31-025 : Les traces de consultation incluent actor_id, timestamp, query_scope, correlation_id.

F-31-07 : Export judiciaire probatoire

  • Description : Produire un export vérifiable incluant logs filtrés, Merkle path, root, TSA token, transaction blockchain et métadonnées batch.
  • Acteurs : API Export, Expert judiciaire, Auditor.
  • Prérequis : événements ancrés ; droits AUDITOR ou ADMIN.
  • Flux nominal :
  • L'acteur soumet un filtre (date/user/event_type/channel).
  • Le service extrait le sous-ensemble.
  • Il joint les preuves cryptographiques associées.
  • Il génère un package signé et téléchargeable.
  • Flux alternatifs :
  • G1 : événements non ancrés dans le périmètre → package marqué PARTIAL_PROOF avec justification.
  • G2 : filtre vide résultat → 204 NO_CONTENT.
  • Postconditions : Export exploitable en audit/expertise.
  • Critères d'acceptation :
  • CA-31-026 : Un export complet contient toujours les 6 artefacts obligatoires définis en besoin §7.1.
  • CA-31-027 : La vérification end-to-end (inclusion + TSA + blockchain) réussit sur 100% des exports complets testés.
  • CA-31-028 : Temps de génération d'un export de 100k événements < 60s P95.
  • CA-31-029 : Les exports sont accessibles uniquement aux rôles autorisés.

F-31-08 : Rétention légale et migration hot/cold

  • Description : Appliquer la politique de conservation 3 ans hot PostgreSQL + 10 ans cold S3 Glacier.
  • Acteurs : Retention Scheduler, Storage Service, Compliance.
  • Prérequis : bucket Glacier et politiques lifecycle configurés.
  • Flux nominal :
  • Job quotidien identifie les événements > 3 ans.
  • Export vers stockage cold avec checksum.
  • Marquage de l'état d'archivage en base.
  • Vérification d'intégrité post-migration.
  • Flux alternatifs :
  • H1 : échec transfert cold → retry, alerte WARNING.
  • H2 : checksum non conforme → rollback opérationnel et alerte CRITICAL.
  • Postconditions : Conservation conforme sans rupture de chaîne probatoire.
  • Critères d'acceptation :
  • CA-31-030 : 100% des événements dépassant 3 ans sont migrés vers cold sous 24h.
  • CA-31-031 : Vérification checksum réussie pour 100% des objets archivés.
  • CA-31-032 : Conservation minimale de 10 ans garantie par policy versionnée.

3bis. Diagrammes Mermaid

Diagramme d'états — Cycle d'ancrage (anchor_status)

Trois états pour le cycle probatoire d'un événement auth (INV-31-01, INV-31-02).

stateDiagram-v2
    [*] --> pending : Événement persisté (append-only, INV-31-01)
    pending --> anchored : Batch Merkle + TSA + blockchain OK
    pending --> anchor_partial : Échec TSA ou blockchain (retry planifié)
    anchor_partial --> anchored : Retry réussi (TSA + blockchain)
    anchor_partial --> anchor_partial : Retry échoué (nouvel essai planifié)

    note right of pending
        event_hash = SHA3-256(payload + previous_hash)
        Chaînage cryptographique vérifié (INV-31-02)
    end note
    note right of anchored
        merkle_root + tsa_token_ref + blockchain_tx_ref
        présents et vérifiables
    end note

Diagramme d'états — Sévérité des alertes

Trois niveaux de sévérité pour les alertes détectées (INV-31-07).

stateDiagram-v2
    [*] --> INFO : Pattern détecté sous seuil critique
    [*] --> WARNING : Seuil intermédiaire atteint
    [*] --> CRITICAL : Seuil critique franchi

    INFO --> LOG_ONLY : Action décidée
    WARNING --> NOTIFY_ADMIN : Action décidée
    CRITICAL --> TEMP_ACCOUNT_BLOCK : Action décidée

    LOG_ONLY --> journalisé : Alerte enregistrée append-only (INV-31-07)
    NOTIFY_ADMIN --> journalisé : Alerte enregistrée append-only (INV-31-07)
    TEMP_ACCOUNT_BLOCK --> journalisé : Alerte enregistrée append-only (INV-31-07)

    note right of journalisé
        count(alertes_émises) == count(alertes_journalisées)
        Intégration probatoire obligatoire (INV-31-07)
    end note

Diagramme d'états — Rétention légale (hot/cold)

Migration des événements selon la politique de conservation.

stateDiagram-v2
    [*] --> hot_postgresql : Événement persisté
    hot_postgresql --> migration_en_cours : Événement > 3 ans (job quotidien)
    migration_en_cours --> cold_s3_glacier : Checksum OK (INV-31-02 préservé)
    migration_en_cours --> hot_postgresql : Checksum KO → rollback + alerte CRITICAL
    cold_s3_glacier --> [*] : Rétention 10 ans expirée

    note right of hot_postgresql
        Immutabilité garantie (INV-31-01)
        Horodatage UTC ms (INV-31-03)
    end note
    note right of cold_s3_glacier
        Chaîne probatoire intacte
        AES-256 at-rest
    end note

Diagramme de séquence — Flux nominal de journalisation probatoire

Flux multi-services depuis l'émission d'un événement auth jusqu'à l'ancrage blockchain (INV-31-01, INV-31-02, INV-31-03, INV-31-06, INV-31-08).

sequenceDiagram
    participant Auth as Service Auth
    participant Audit as Audit Auth (enrichissement)
    participant Queue as File asynchrone
    participant Writer as Audit Writer
    participant DB as PostgreSQL (append-only)
    participant Risk as Risk Engine
    participant Batcher as Batcher Merkle (PD-39)
    participant TSA as TSA (RFC 3161)
    participant BC as Blockchain (PD-40)

    Auth->>Audit: Événement brut + correlation_id (INV-31-06)
    Note over Auth,Audit: Non-bloquant (INV-31-08)
    Audit->>Audit: Enrichissement (IP, UA, geo, channel)
    Audit->>Risk: Contexte événement
    Risk-->>Audit: risk_score [0.0..1.0]
    Audit->>Queue: Événement normalisé (UUIDv7, UTC ms — INV-31-03)

    Queue->>Writer: Consommation asynchrone
    Writer->>Writer: SHA3-256(payload_canonique + previous_hash) (INV-31-02)
    Writer->>DB: INSERT append-only (INV-31-01)
    Note over DB: Trigger bloque UPDATE/DELETE
    DB-->>Writer: ACK persistance
    Writer-->>Queue: ACK consommation

    Note over DB,Batcher: Batch : 10 min ou 1000 événements
    DB->>Batcher: Événements pending_anchor
    Batcher->>Batcher: Calcul Merkle root + preuves d'inclusion
    Batcher->>TSA: Demande horodatage certifié
    TSA-->>Batcher: tsa_token_ref
    Batcher->>BC: Ancrage Merkle root
    BC-->>Batcher: blockchain_tx_ref
    Batcher->>DB: UPDATE anchor_status = 'anchored' + refs

Diagramme de séquence — Export judiciaire vérifiable

Flux de génération d'un export probatoire avec vérification end-to-end (INV-31-02, INV-31-05, INV-31-06).

sequenceDiagram
    participant Actor as Auditor / Admin
    participant API as API Export
    participant RBAC as Middleware RBAC
    participant DB as PostgreSQL
    participant Proof as Service Preuves
    participant S3 as S3 (stockage export)
    participant AccessLog as auth_audit_access_log

    Actor->>API: POST /v1/audit/auth-events/judicial-export (INV-31-05 : rôle vérifié)
    API->>RBAC: Vérification JWT + rôle ADMIN|AUDITOR
    RBAC-->>API: Autorisé

    API->>DB: Extraction événements filtrés
    DB-->>API: Sous-ensemble auth_audit_log

    API->>Proof: Récupération preuves par batch_id
    Proof-->>API: Merkle paths + roots + TSA tokens + blockchain_tx_refs (INV-31-02)

    alt Tous événements ancrés
        API->>API: proof_mode = FULL_PROOF
    else Événements non ancrés présents
        API->>API: proof_mode = PARTIAL_PROOF (justification incluse)
    end

    API->>API: Assemblage package + SHA3-256 checksum
    API->>S3: Upload package signé
    S3-->>API: package_uri

    API->>AccessLog: Trace consultation (actor_id, query_scope, correlation_id — INV-31-06)
    API-->>Actor: 202 {export_id, status: PROCESSING} puis 200 {package_uri, checksum}

Diagramme de séquence — Détection d'anomalie et alerting probatoire

Flux temps réel de détection, scoring et journalisation probatoire des alertes (INV-31-04, INV-31-07, INV-31-08).

sequenceDiagram
    participant Writer as Audit Writer
    participant Alert as Alert Engine
    participant Redis as Redis (fenêtre temporelle)
    participant Config as auth_alert_config
    participant DB as PostgreSQL (append-only)
    participant Notif as Admin Notification

    Writer->>Alert: Événement auth persisté
    Alert->>Config: Chargement règles actives (5 patterns)
    Alert->>Redis: Évaluation fenêtre temporelle (IP/user/device)
    Redis-->>Alert: Compteurs fenêtre glissante

    alt Seuil atteint (ex: >5 échecs / 5 min — bruteforce)
        Alert->>Alert: Génération alerte (severity, risk_delta, pattern_code)
        Alert->>DB: INSERT auth_alert_log (append-only — INV-31-07)
        Note over DB: Alerte = événement probatoire ancrable
        Alert->>DB: INSERT auth_audit_log (événement alerte — INV-31-07)
        Note over DB: Zero données secrètes (INV-31-04)

        alt severity = CRITICAL
            Alert->>Notif: Notification admin immédiate
        else severity = WARNING
            Alert->>Notif: Notification admin standard
        else severity = INFO
            Alert->>Alert: LOG_ONLY (pas de notification)
        end
    end

    Note over Writer,Alert: Traitement < 1s P95, non-bloquant (INV-31-08)

4. Invariants de sécurité

INV-31-01 : Immutabilité stricte du journal

  • Règle : Aucune ligne de auth_audit_log ne peut être modifiée ou supprimée après insertion.
  • Vérification : Trigger DB bloquant UPDATE/DELETE + tests d'intégration quotidiens.
  • Violation : Perte d'opposabilité juridique ; incident sécurité CRITICAL ; blocage des exports judiciaires jusqu'à remédiation.

INV-31-02 : Intégrité cryptographique chaînée

  • Règle : Chaque événement doit avoir event_hash = SHA3-256(payload_canonique + previous_hash).
  • Vérification : Job de recalcul aléatoire continu (échantillon min 1%) + vérification exhaustive mensuelle.
  • Violation : Lot marqué corrompu, escalade conformité immédiate, invalidation du batch concerné.

INV-31-03 : Horodatage UTC millisecondes

  • Règle : Tous les timestamps sont en UTC ISO-8601 avec précision millisecondes.
  • Vérification : Contrainte de format en ingestion + test de conformité sur 100% des événements.
  • Violation : Rejet de l'événement en normalisation et alerte qualité.

INV-31-04 : Minimisation Zero-Knowledge

  • Règle : Interdiction absolue d'enregistrer mot de passe, secret MFA, clés cryptographiques, PII non nécessaire.
  • Vérification : Allowlist de champs + scanner DLP sur payload brut avant persistance.
  • Violation : Incident RGPD majeur, purge légale contrôlée, notification sécurité/compliance.

INV-31-05 : Contrôle d'accès audit

  • Règle : Seuls ADMIN et AUDITOR peuvent lire/exporter les logs.
  • Vérification : Middleware RBAC + tests automatiques 401/403 à chaque build.
  • Violation : Exposition de données d'audit, incident sécurité CRITICAL.

INV-31-06 : Traçabilité de bout en bout

  • Règle : Tout événement et toute consultation portent un correlation_id.
  • Vérification : Contrainte NOT NULL + dashboard de complétude (objectif 100%).
  • Violation : Rupture d'investigation inter-services ; non-conformité audit.

INV-31-07 : Intégration probatoire des alertes

  • Règle : Toute alerte générée est journalisée comme événement append-only et ancrée.
  • Vérification : Contrôle de parité count(alertes_emises) == count(alertes_journalisees).
  • Violation : Faible valeur probatoire des actions sécurité ; non-conformité process.

INV-31-08 : Non-blocage du flux d'authentification

  • Règle : La journalisation d'audit est asynchrone et ne bloque jamais la réponse auth.
  • Vérification : SLO auth overhead <1ms P99 sur charge nominale et pic.
  • Violation : Dégradation production ; bascule en mode dégradé avec file durable obligatoire.

5. Modèle de données

Entités

Table auth_audit_log

Colonne Type Contraintes
id BIGSERIAL PRIMARY KEY
event_id UUID NOT NULL UNIQUE
event_type VARCHAR(32) NOT NULL CHECK (IN 8 codes)
event_timestamp TIMESTAMPTZ(3) NOT NULL
user_id UUID NULL
identity_level VARCHAR(16) NULL CHECK (IN 'email','oidc','enterprise')
device_id UUID NULL
channel VARCHAR(8) NOT NULL CHECK (IN 'ios','pwa','api')
ip_address INET NOT NULL
user_agent TEXT NOT NULL CHECK (length 1-2048)
geo_country CHAR(2) NOT NULL CHECK (regex ^[A-Z]{2}$)
geo_region VARCHAR(128) NULL
success BOOLEAN NOT NULL
failure_reason VARCHAR(64) NULL
session_id UUID NULL
correlation_id UUID NOT NULL
risk_score NUMERIC(4,3) NOT NULL CHECK (0.000-1.000)
event_payload_canonical JSONB NOT NULL
previous_hash CHAR(64) NULL
event_hash CHAR(64) NOT NULL
batch_id UUID NULL
anchor_status VARCHAR(16) NOT NULL DEFAULT 'pending' CHECK (IN 'pending','anchor_partial','anchored')
created_at TIMESTAMPTZ(3) NOT NULL DEFAULT now()

Contraintes additionnelles : - CHECK (success = false AND failure_reason IS NOT NULL OR success = true AND failure_reason IS NULL)

Index : - idx_auth_audit_event_ts (event_timestamp DESC) - idx_auth_audit_user_ts (user_id, event_timestamp DESC) - idx_auth_audit_ip_ts (ip_address, event_timestamp DESC) - idx_auth_audit_correlation (correlation_id) - idx_auth_audit_batch (batch_id) - idx_auth_audit_anchor_status (anchor_status)

Table auth_alert_log

Colonne Type Contraintes
id BIGSERIAL PRIMARY KEY
alert_id UUID NOT NULL UNIQUE
source_event_id UUID NOT NULL FK → auth_audit_log.event_id
pattern_code VARCHAR(32) NOT NULL CHECK (IN 5 patterns)
severity VARCHAR(16) NOT NULL CHECK (IN 'INFO','WARNING','CRITICAL')
threshold_snapshot JSONB NOT NULL
risk_delta NUMERIC(4,3) NOT NULL CHECK (0.000-1.000)
decision_action VARCHAR(32) NOT NULL CHECK (IN 'LOG_ONLY','NOTIFY_ADMIN','TEMP_ACCOUNT_BLOCK')
correlation_id UUID NOT NULL
created_at TIMESTAMPTZ(3) NOT NULL DEFAULT now()

Table auth_alert_config

Colonne Type Contraintes
id BIGSERIAL PRIMARY KEY
pattern_code VARCHAR(32) NOT NULL UNIQUE
threshold_value INTEGER NOT NULL CHECK (> 0)
window_seconds INTEGER NOT NULL CHECK (> 0)
severity_default VARCHAR(16) NOT NULL CHECK (IN 3 levels)
enabled BOOLEAN NOT NULL DEFAULT true
version INTEGER NOT NULL
updated_by UUID NOT NULL
updated_at TIMESTAMPTZ(3) NOT NULL DEFAULT now()

Table auth_audit_access_log

Colonne Type Contraintes
id BIGSERIAL PRIMARY KEY
access_id UUID NOT NULL UNIQUE
actor_id UUID NOT NULL
actor_role VARCHAR(16) NOT NULL CHECK (IN 'ADMIN','AUDITOR')
action VARCHAR(16) NOT NULL CHECK (IN 'READ','EXPORT')
query_scope JSONB NOT NULL
result_count INTEGER NOT NULL CHECK (>= 0)
correlation_id UUID NOT NULL
created_at TIMESTAMPTZ(3) NOT NULL DEFAULT now()

Table judicial_export

Colonne Type Contraintes
id BIGSERIAL PRIMARY KEY
export_id UUID NOT NULL UNIQUE
requested_by UUID NOT NULL
filter_criteria JSONB NOT NULL
proof_mode VARCHAR(16) NOT NULL CHECK (IN 'FULL_PROOF','PARTIAL_PROOF')
event_count INTEGER NOT NULL CHECK (>= 0)
artifact_manifest JSONB NOT NULL
package_uri TEXT NOT NULL
sha3_256_checksum CHAR(64) NOT NULL
created_at TIMESTAMPTZ(3) NOT NULL DEFAULT now()

Relations

  • auth_alert_log.source_event_idauth_audit_log.event_id (N:1)
  • auth_audit_log.batch_id → batch Merkle externe (N:1 logique)
  • judicial_export.filter_criteria référence un sous-ensemble de auth_audit_log
  • auth_audit_access_log trace les appels de lecture/export sur auth_audit_log et judicial_export
  • Une alerte génère un événement probatoire corrélé via correlation_id partagé

6. Interfaces

API REST

1) Ingestion interne d'événement auth

  • Endpoint : POST /internal/v1/audit/auth-events
  • Auth : mTLS service-to-service + JWT de service
  • Request :
    {
      "event_type": "AUTH_LOGIN_FAILURE",
      "timestamp": "2026-02-15T14:23:11.482Z",
      "user_id": "d4a6e912-2b2c-4c2f-a4e2-3f5f63b3d612",
      "identity_level": "email",
      "device_id": null,
      "channel": "pwa",
      "ip_address": "203.0.113.10",
      "user_agent": "Mozilla/5.0 ...",
      "geo_country": "FR",
      "geo_region": "IDF",
      "success": false,
      "failure_reason": "INVALID_CREDENTIALS",
      "session_id": null,
      "correlation_id": "9b2c295c-76ff-49c8-b152-f3d95d719a26"
    }
    
  • Response 202 :
    {
      "event_id": "01953f75-6f4b-7c65-aee9-9f6ce34f9d12",
      "status": "QUEUED",
      "risk_score": 0.640
    }
    
  • Codes erreur :
  • 400 BAD_REQUEST : AUTH_AUDIT_SCHEMA_INVALID
  • 401 UNAUTHORIZED : token service invalide
  • 403 FORBIDDEN : service non autorisé
  • 409 CONFLICT : AUTH_AUDIT_DUPLICATE_EVENT
  • 422 UNPROCESSABLE_ENTITY : failure_reason incohérent
  • 429 TOO_MANY_REQUESTS : quota dépassé
  • 503 SERVICE_UNAVAILABLE : file indisponible

2) Consultation des logs d'authentification

  • Endpoint : GET /v1/audit/auth-events
  • Auth : JWT utilisateur, rôles ADMIN|AUDITOR
  • Query params : from, to, user_id, event_type, channel, ip, correlation_id, page, size
  • Response 200 :
    {
      "items": [{
        "event_id": "01953f75-6f4b-7c65-aee9-9f6ce34f9d12",
        "event_type": "AUTH_LOGIN_FAILURE",
        "timestamp": "2026-02-15T14:23:11.482Z",
        "user_id": "d4a6e912-2b2c-4c2f-a4e2-3f5f63b3d612",
        "channel": "pwa",
        "ip_address": "203.0.113.10",
        "geo_country": "FR",
        "success": false,
        "failure_reason": "INVALID_CREDENTIALS",
        "risk_score": 0.640,
        "correlation_id": "9b2c295c-76ff-49c8-b152-f3d95d719a26"
      }],
      "page": 1,
      "size": 50,
      "total": 1240
    }
    
  • Codes erreur : 400, 401, 403, 416, 500

3) Configuration des seuils d'alerte

  • Endpoint : PUT /v1/audit/auth-alerts/config/{pattern_code}
  • Auth : ADMIN
  • Request :
    {
      "threshold_value": 5,
      "window_seconds": 300,
      "severity_default": "WARNING",
      "enabled": true
    }
    
  • Response 200 :
    {
      "pattern_code": "BRUTEFORCE",
      "threshold_value": 5,
      "window_seconds": 300,
      "severity_default": "WARNING",
      "enabled": true,
      "version": 12
    }
    
  • Codes erreur : 400, 401, 403, 404, 409, 422

4) Export judiciaire

  • Endpoint : POST /v1/audit/auth-events/judicial-export
  • Auth : AUDITOR|ADMIN
  • Request :
    {
      "filters": {
        "from": "2026-01-01T00:00:00.000Z",
        "to": "2026-01-31T23:59:59.999Z",
        "user_id": "d4a6e912-2b2c-4c2f-a4e2-3f5f63b3d612"
      },
      "proof_mode": "FULL_PROOF"
    }
    
  • Response 202 :
    {
      "export_id": "f6b8f11f-6f2d-4f58-95f8-f3f95d6d2e66",
      "status": "PROCESSING"
    }
    
  • Response 200 (download metadata) :
    {
      "export_id": "f6b8f11f-6f2d-4f58-95f8-f3f95d6d2e66",
      "proof_mode": "FULL_PROOF",
      "event_count": 1834,
      "package_uri": "s3://probatiovault-exports/pd31/f6b8....zip",
      "sha3_256_checksum": "8d6d9c7e2a...."
    }
    
  • Codes erreur : 400, 401, 403, 404, 409, 422, 503

5) Consultation des alertes auth

  • Endpoint : GET /v1/audit/auth-alerts
  • Auth : ADMIN|AUDITOR
  • Query params : from, to, severity, pattern_code, user_id, ip
  • Codes : 200, 400, 401, 403, 500

Événements

Événements consommés

  • auth.login.success
  • auth.login.failure
  • auth.logout
  • auth.mfa.attempt
  • auth.mfa.success
  • auth.mfa.failure
  • auth.device.revoked
  • auth.token.invalid

Contrat minimal : correlation_id (UUID), timestamp (UTC ms), channel, ip_address, user_agent, success

Événements publiés

  • audit.auth.logged : événement auth persisté
  • audit.auth.alert.raised : alerte sécurité levée
  • audit.auth.anchor.status : mise à jour état d'ancrage
  • audit.auth.export.generated : export judiciaire disponible

Garanties : At-least-once ; idempotence via event_id/alert_id

7. Contraintes techniques

Performance

Métrique SLA
Insertion journal < 5 ms P99
Throughput global > 1000 evt/s
Overhead auth sync < 1 ms P99
Détection alerte < 1 s P95
Export 100k events < 60 s P95
Disponibilité API 99.9% mensuel

Sécurité

  • Chiffrement at-rest : AES-256 (DB + objets export)
  • Chiffrement in-transit : TLS 1.3 minimum
  • RBAC strict : ADMIN|AUDITOR uniquement
  • Signature/checksum SHA3-256 des exports
  • Journalisation consultations obligatoire
  • Zero données secrètes (Zero-Knowledge)

Conformité

  • RGPD : minimisation, finalité, contrôle d'accès, traçabilité
  • NF Z42-013 / ISO 14641 : intégrité, horodatage, traçabilité, conservation
  • Conservation : 3 ans hot + 10 ans cold
  • Auditabilité : preuves vérifiables (Merkle/TSA/blockchain)

8. Dépendances

Internes

Module Story Usage
Journal append-only PD-37 Persistance probatoire
Batch Merkle + TSA PD-39 Ancrage périodique
Ancrage blockchain PD-40 Preuve publique
Auth SRP-6a PD-24/25 Événements source
Session/JWT PD-28 Événements source
IAM RBAC Contrôle d'accès
Correlation middleware Traçabilité

Externes

  • PostgreSQL (journal + métadonnées)
  • Redis (fenêtre temporelle alerting)
  • Service GeoIP (cache local)
  • S3 Glacier (archivage légal)
  • TSA + blockchain (via PD-39/40)

9. Hors périmètre

  • Dashboard de visualisation des logs
  • Analytics temps réel (Grafana/Prometheus dashboards métier)
  • Intégration SIEM externe (Splunk, ELK)
  • Notifications push utilisateur final
  • Génération automatique rapport PDF certifié
  • Refonte auth SRP-6a ou MFA existants

10. Questions ouvertes

ID Question Impact
QO-31-01 Source de vérité seuils alerting : Redis (dynamique) ou PostgreSQL (transactionnelle) ? Architecture alerting
QO-31-02 Export FULL_PROOF avec événements non ancrés : échec 422 ou dégrader en PARTIAL_PROOF ? UX export
QO-31-03 Exports judiciaires signés avec clé dédiée "forensic signing" distincte ? Sécurité exports

Document généré dans le cadre du workflow de gouvernance ProbatioVault.