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.