Aller au contenu

PD-31 — Plan d'implémentation

1. Architecture cible

┌─────────────────────────────────────────────────────────────────────────────┐
│                           AUTH SERVICES                                      │
│  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐                        │
│  │  Login   │ │  Logout  │ │   MFA    │ │  Token   │                        │
│  │ Service  │ │ Service  │ │ Service  │ │  Guard   │                        │
│  └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘                        │
│       │            │            │            │                               │
│       └────────────┴────────────┴────────────┘                               │
│                           │                                                  │
│                    EventEmitter                                              │
│                    (auth.*.*)                                                │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│                      AUTH AUDIT MODULE (nouveau)                             │
│                                                                              │
│  ┌────────────────────┐    ┌────────────────────┐    ┌──────────────────┐  │
│  │  AuthAuditListener │───▶│ AuthAuditNormalizer│───▶│ AuthAuditQueue   │  │
│  │  (EventSubscriber) │    │  (enrichissement)  │    │   (BullMQ)       │  │
│  └────────────────────┘    └────────────────────┘    └────────┬─────────┘  │
│                                                                 │           │
│  ┌────────────────────┐    ┌────────────────────┐              │           │
│  │   RiskScoreEngine  │◀───│ AuthAuditProcessor │◀─────────────┘           │
│  │   (scoring)        │    │   (worker)         │                          │
│  └────────────────────┘    └─────────┬──────────┘                          │
│                                      │                                      │
│  ┌────────────────────┐    ┌─────────▼──────────┐    ┌──────────────────┐  │
│  │  AlertDetector     │◀───│ AuthAuditWriter    │───▶│ auth_audit_log   │  │
│  │  (patterns)        │    │ (hash + persist)   │    │   (PostgreSQL)   │  │
│  └─────────┬──────────┘    └────────────────────┘    └──────────────────┘  │
│            │                                                                │
│            ▼                                                                │
│  ┌────────────────────┐    ┌────────────────────┐                          │
│  │ AlertNotifier      │    │ auth_alert_log     │                          │
│  │ (notifications)    │    │   (PostgreSQL)     │                          │
│  └────────────────────┘    └────────────────────┘                          │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│                      MERKLE ANCHORING (existant PD-39/40)                    │
│  ┌────────────────────┐    ┌────────────────────┐    ┌──────────────────┐  │
│  │   MerkleBatcher    │───▶│     TSAService     │───▶│ BlockchainAnchor │  │
│  └────────────────────┘    └────────────────────┘    └──────────────────┘  │
└─────────────────────────────────────────────────────────────────────────────┘

2. Décisions d'architecture

QO-31-01 : Source de vérité seuils alerting

Décision : PostgreSQL comme source de vérité, Redis comme cache de lecture.

Justification : - PostgreSQL garantit la persistance et l'auditabilité des changements de configuration - Redis offre des performances de lecture < 1ms pour la détection en temps réel - Invalidation du cache via événement alert.config.updated

Implémentation :

// AlertConfigService
async getConfig(patternCode: string): Promise<AlertConfig> {
  const cached = await this.redis.get(`alert:config:${patternCode}`);
  if (cached) return JSON.parse(cached);

  const config = await this.repo.findOne({ where: { patternCode } });
  await this.redis.set(`alert:config:${patternCode}`, JSON.stringify(config), 'EX', 300);
  return config;
}

QO-31-02 : Export avec événements non ancrés

Décision : Permettre PARTIAL_PROOF avec flag explicite et avertissement.

Justification : - Refuser l'export (422) bloquerait des cas légitimes (export urgent, événements récents) - L'utilisateur doit être informé explicitement de la portée réduite - Le manifest de l'export doit lister les événements non ancrés

Implémentation :

// JudicialExportService
if (unanchoredCount > 0) {
  result.proofMode = 'PARTIAL_PROOF';
  result.warnings.push(`${unanchoredCount} événements non encore ancrés`);
  result.unanchoredEventIds = unanchoredIds;
}

QO-31-03 : Clé de signature forensic

Décision : Utiliser la clé HSM existante (via PD-37/40).

Justification : - Éviter la fragmentation des clés - La clé HSM est déjà auditée et conforme FIPS 140-2 - Les exports utilisent le même mécanisme que l'ancrage Merkle

3. Modules à créer/modifier

Module A : AuthAuditModule (nouveau)

Fichiers : - src/modules/auth-audit/auth-audit.module.ts - src/modules/auth-audit/services/auth-audit.service.ts - src/modules/auth-audit/services/auth-audit-normalizer.service.ts - src/modules/auth-audit/services/auth-audit-writer.service.ts - src/modules/auth-audit/services/risk-score.service.ts - src/modules/auth-audit/processors/auth-audit.processor.ts - src/modules/auth-audit/listeners/auth-event.listener.ts - src/modules/auth-audit/entities/auth-audit-log.entity.ts - src/modules/auth-audit/dto/auth-audit-event.dto.ts - src/modules/auth-audit/interfaces/auth-audit.interfaces.ts

Dépendances : - CryptoModule (SHA3, canonicalisation) - AuditModule (journal append-only) - BullModule (queues) - GeoipModule (géolocalisation IP)

Responsabilités : - Écoute des événements auth - Normalisation et enrichissement - Calcul du risk_score - Persistance append-only avec hash chaîné

Module B : AuthAlertModule (nouveau)

Fichiers : - src/modules/auth-alert/auth-alert.module.ts - src/modules/auth-alert/services/alert-detector.service.ts - src/modules/auth-alert/services/alert-config.service.ts - src/modules/auth-alert/services/alert-notifier.service.ts - src/modules/auth-alert/entities/auth-alert-log.entity.ts - src/modules/auth-alert/entities/auth-alert-config.entity.ts - src/modules/auth-alert/dto/alert-config.dto.ts - src/modules/auth-alert/patterns/*.pattern.ts (5 patterns)

Dépendances : - AuthAuditModule - RedisModule (fenêtre glissante) - NotificationModule (alertes admin)

Responsabilités : - Détection des 5 patterns (bruteforce, stuffing, geo-hopping, device, token) - Gestion de la configuration des seuils - Émission des alertes - Journalisation probatoire des alertes

Module C : AuthAuditApiModule (nouveau)

Fichiers : - src/modules/auth-audit-api/auth-audit-api.module.ts - src/modules/auth-audit-api/controllers/auth-audit.controller.ts - src/modules/auth-audit-api/controllers/auth-alert.controller.ts - src/modules/auth-audit-api/controllers/judicial-export.controller.ts - src/modules/auth-audit-api/services/judicial-export.service.ts - src/modules/auth-audit-api/entities/judicial-export.entity.ts - src/modules/auth-audit-api/entities/auth-audit-access-log.entity.ts - src/modules/auth-audit-api/guards/audit-access.guard.ts - src/modules/auth-audit-api/interceptors/audit-access-log.interceptor.ts

Dépendances : - AuthAuditModule - AuthAlertModule - MerkleModule (preuves d'inclusion) - StorageModule (exports S3)

Responsabilités : - Endpoints REST (5 API) - Contrôle d'accès RBAC (ADMIN/AUDITOR) - Journalisation des consultations - Génération des exports judiciaires

Module D : Modifications auth existant

Fichiers à modifier : - src/modules/auth/services/login.service.ts → émettre auth.login.success/failure - src/modules/auth/services/logout.service.ts → émettre auth.logout - src/modules/auth/services/mfa.service.ts → émettre auth.mfa.* - src/modules/auth/guards/jwt.guard.ts → émettre auth.token.invalid - src/modules/auth/guards/device.guard.ts → émettre auth.device.revoked

Nature des modifications : - Ajout d'émission d'événements via EventEmitter2 - Pas de changement de logique métier

4. Séquence d'implémentation

Phase 1 : Infrastructure (3 jours)
├── T1.1 : Entités TypeORM (auth_audit_log, triggers) [1j]
├── T1.2 : Entités alertes + config [0.5j]
├── T1.3 : Entités access_log + export [0.5j]
└── T1.4 : Migrations PostgreSQL [1j]

Phase 2 : Core Audit (4 jours)
├── T2.1 : AuthAuditNormalizer (validation, enrichissement) [1j]
├── T2.2 : AuthAuditWriter (hash chaîné, insert) [1j]
├── T2.3 : RiskScoreEngine (règles, calcul) [1j]
└── T2.4 : AuthAuditProcessor (BullMQ worker) [1j]

Phase 3 : Alerting (3 jours)
├── T3.1 : AlertDetector + 5 patterns [1.5j]
├── T3.2 : AlertConfigService (Redis cache) [0.5j]
└── T3.3 : AlertNotifier + journalisation [1j]

Phase 4 : API (3 jours)
├── T4.1 : POST /internal/v1/audit/auth-events [0.5j]
├── T4.2 : GET /v1/audit/auth-events + pagination [0.5j]
├── T4.3 : PUT /v1/audit/auth-alerts/config [0.5j]
├── T4.4 : GET /v1/audit/auth-alerts [0.5j]
└── T4.5 : POST judicial-export + JudicialExportService [1j]

Phase 5 : Intégration (2 jours)
├── T5.1 : Listener auth events [0.5j]
├── T5.2 : Intégration MerkleBatcher (PD-39) [0.5j]
├── T5.3 : Guards + Interceptors [0.5j]
└── T5.4 : Modifications services auth existants [0.5j]

Phase 6 : Tests (3 jours)
├── T6.1 : Tests unitaires (TC-31-001..016) [1j]
├── T6.2 : Tests intégration (TC-31-017..036) [1j]
└── T6.3 : Tests E2E + perf (TC-31-037..052) [1j]

Total : 18 jours

5. Diagrammes Mermaid

5.1 Graphe de dépendances entre modules

graph TD
    subgraph "Auth Services (existant)"
        LoginService["LoginService"]
        LogoutService["LogoutService"]
        MfaService["MfaService"]
        JwtGuard["TokenGuard (JWT)"]
        DeviceGuard["DeviceGuard"]
    end

    subgraph "Module A : AuthAuditModule"
        AuthEventListener["AuthAuditListener"]
        AuthAuditNormalizer["AuthAuditNormalizer"]
        AuthAuditProcessor["AuthAuditProcessor"]
        AuthAuditWriter["AuthAuditWriter"]
        RiskScoreEngine["RiskScoreEngine"]
    end

    subgraph "Module B : AuthAlertModule"
        AlertDetector["AlertDetector"]
        AlertConfigService["AlertConfigService"]
        AlertNotifier["AlertNotifier"]
    end

    subgraph "Module C : AuthAuditApiModule"
        AuthAuditController["AuthAuditController"]
        AuthAlertController["AuthAlertController"]
        JudicialExportController["JudicialExportController"]
        JudicialExportService["JudicialExportService"]
        AuditAccessGuard["AuditAccessGuard"]
    end

    subgraph "Modules externes"
        CryptoModule["CryptoModule (SHA3)"]
        BullMQ["BullModule (BullMQ)"]
        GeoipModule["GeoipModule"]
        RedisModule["RedisModule"]
        NotificationModule["NotificationModule"]
        MerkleModule["MerkleModule (PD-39)"]
        StorageModule["StorageModule (S3)"]
    end

    subgraph "Persistance"
        AuthAuditLog[("auth_audit_log")]
        AuthAlertLog[("auth_alert_log")]
        AuthAlertConfig[("auth_alert_config")]
    end

    LoginService -->|EventEmitter auth.*.*| AuthEventListener
    LogoutService -->|EventEmitter auth.*.*| AuthEventListener
    MfaService -->|EventEmitter auth.*.*| AuthEventListener
    JwtGuard -->|EventEmitter auth.*.*| AuthEventListener
    DeviceGuard -->|EventEmitter auth.*.*| AuthEventListener

    AuthEventListener --> AuthAuditNormalizer
    AuthAuditNormalizer --> BullMQ
    BullMQ --> AuthAuditProcessor
    AuthAuditProcessor --> RiskScoreEngine
    AuthAuditProcessor --> AuthAuditWriter
    AuthAuditWriter --> CryptoModule
    AuthAuditWriter --> AuthAuditLog
    AuthAuditNormalizer --> GeoipModule

    AuthAuditWriter --> AlertDetector
    AlertDetector --> RedisModule
    AlertDetector --> AlertConfigService
    AlertDetector --> AlertNotifier
    AlertNotifier --> NotificationModule
    AlertNotifier --> AuthAlertLog
    AlertConfigService --> AuthAlertConfig

    AuthAuditController --> AuthAuditLog
    AuthAlertController --> AuthAlertLog
    AuthAlertController --> AlertConfigService
    JudicialExportController --> JudicialExportService
    JudicialExportService --> MerkleModule
    JudicialExportService --> StorageModule
    JudicialExportService --> AuthAuditLog
    AuthAuditController --> AuditAccessGuard
    AuthAlertController --> AuditAccessGuard
    JudicialExportController --> AuditAccessGuard

5.2 Diagramme de séquence — Flux audit complet (login -> alerte -> ancrage)

sequenceDiagram
    participant Client
    participant LoginService
    participant EventEmitter
    participant AuthAuditListener
    participant AuthAuditNormalizer
    participant GeoipModule
    participant AuthAuditQueue as AuthAuditQueue (BullMQ)
    participant AuthAuditProcessor
    participant RiskScoreEngine
    participant AuthAuditWriter
    participant CryptoModule
    participant DB as PostgreSQL (auth_audit_log)
    participant AlertDetector
    participant RedisModule
    participant AlertNotifier
    participant MerkleBatcher

    Client->>LoginService: POST /auth/login
    LoginService->>EventEmitter: emit(auth.login.success, payload)

    EventEmitter->>AuthAuditListener: onAuthEvent(payload)
    AuthAuditListener->>AuthAuditNormalizer: normalize(payload)
    AuthAuditNormalizer->>GeoipModule: geolocate(ip)
    GeoipModule-->>AuthAuditNormalizer: { country, city, lat, lon }
    AuthAuditNormalizer-->>AuthAuditListener: normalizedEvent
    AuthAuditListener->>AuthAuditQueue: add(normalizedEvent)

    AuthAuditQueue->>AuthAuditProcessor: process(job)
    AuthAuditProcessor->>RiskScoreEngine: computeScore(event)
    RiskScoreEngine-->>AuthAuditProcessor: risk_score

    AuthAuditProcessor->>AuthAuditWriter: write(event, risk_score)
    AuthAuditWriter->>CryptoModule: sha3_256(canonical(event) + previous_hash)
    CryptoModule-->>AuthAuditWriter: event_hash
    AuthAuditWriter->>DB: INSERT (append-only, hash chaîné)
    DB-->>AuthAuditWriter: OK

    AuthAuditWriter->>AlertDetector: evaluate(event)
    AlertDetector->>RedisModule: INCR sliding_window(user, pattern)
    RedisModule-->>AlertDetector: count
    alt Seuil dépassé
        AlertDetector->>AlertNotifier: notify(alert)
        AlertNotifier->>DB: INSERT auth_alert_log
    end

    AuthAuditWriter->>MerkleBatcher: addLeaf(event_hash)
    Note over MerkleBatcher: Ancrage Merkle asynchrone (PD-39/40)

5.3 Diagramme de séquence — Export judiciaire

sequenceDiagram
    participant Admin
    participant JudicialExportController
    participant AuditAccessGuard
    participant JudicialExportService
    participant DB as PostgreSQL
    participant MerkleModule
    participant CryptoModule
    participant StorageModule as StorageModule (S3)

    Admin->>JudicialExportController: POST /v1/audit/judicial-exports
    JudicialExportController->>AuditAccessGuard: checkRole(ADMIN | AUDITOR)
    AuditAccessGuard-->>JudicialExportController: authorized

    JudicialExportController->>JudicialExportService: generateExport(filters)

    JudicialExportService->>DB: SELECT auth_audit_log WHERE filters
    DB-->>JudicialExportService: events[]

    loop Pour chaque événement
        JudicialExportService->>MerkleModule: getInclusionProof(event_hash)
        MerkleModule-->>JudicialExportService: merkle_path
    end

    alt Événements non ancrés
        JudicialExportService->>JudicialExportService: proofMode = PARTIAL_PROOF
    end

    JudicialExportService->>CryptoModule: sha3_256(export_content)
    CryptoModule-->>JudicialExportService: export_checksum

    JudicialExportService->>StorageModule: upload(export.zip)
    StorageModule-->>JudicialExportService: s3_url

    JudicialExportService->>DB: INSERT judicial_export (manifest)
    JudicialExportService-->>JudicialExportController: { exportId, url, proofMode }
    JudicialExportController-->>Admin: 201 Created

6. Risques techniques

R1 : Performance insertion sous charge

Risque : Latence > 5ms sous charge 1000+ evt/s

Mitigation : - Insertion batch via BullMQ (grouper les INSERT) - Index partiels sur colonnes fréquemment filtrées - Monitoring Prometheus avec alertes

R2 : Calcul hash chaîné et concurrence

Risque : Collision previous_hash si insertions concurrentes

Mitigation : - Advisory lock PostgreSQL sur la séquence d'insertion - Transaction SERIALIZABLE pour le calcul du hash - File unique (pas de parallélisme sur l'écriture)

R3 : Détection alertes fenêtre glissante

Risque : Faux négatifs si Redis indisponible

Mitigation : - Fallback PostgreSQL (requête window function) - Retry automatique avec backoff - Logging des échecs pour audit

R4 : Volume de données après 3 ans

Risque : Table > 1B lignes, performances dégradées

Mitigation : - Partitionnement par date (PARTITION BY RANGE) - Job de migration automatique vers cold storage - Archivage avec vérification checksum

R5 : Intégrité export judiciaire

Risque : Export incomplet ou non vérifiable

Mitigation : - Vérification Merkle path avant packaging - Checksum SHA3-256 de chaque artefact - Tests E2E de vérification complète

7. Estimation

Module Tâches Jours Complexité
Infrastructure T1.1-T1.4 3 Moyenne
Core Audit T2.1-T2.4 4 Élevée
Alerting T3.1-T3.3 3 Moyenne
API T4.1-T4.5 3 Moyenne
Intégration T5.1-T5.4 2 Faible
Tests T6.1-T6.3 3 Moyenne
Total 18 tâches 18 jours

Buffer risques : +20% = 3.5 jours Total avec buffer : 21.5 jours (~4 semaines)


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