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_ncalculé avecevent_hash_n-1pour 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 canauxios,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_idUUIDv7 est généré. - L'événement normalisé est envoyé en file asynchrone de journalisation.
- Flux alternatifs :
- A1 :
user_idinconnu (tentative sur identifiant inexistant) →user_id = NULL,identity_levelrenseigné si déterminable. - A2 :
device_idindisponible →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 NULLsans 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_hashen 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
UPDATEouDELETEsurauth_audit_logest bloquée par la base. - CA-31-006 : 100% des lignes insérées ont
event_hashnon nul sur 64 hex chars. - CA-31-007 : Pour N événements consécutifs,
previous_hashde N =event_hashde 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_logmarquéspending_anchorsont 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_iden moins de 10 minutes ou 1000 événements. - CA-31-010 : 100% des événements en statut
anchoredpossèdentmerkle_root,tsa_token_ref,blockchain_tx_ref. - CA-31-011 : La vérification de Merkle path retourne
truepour 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_scoreet 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_scorenumé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êmeuser_iden 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
>20AUTH_TOKEN_INVALIDen 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
ADMINetAUDITOR, 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/AUDITORreçoivent systématiquement403. - 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
AUDITORouADMIN. - 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_PROOFavec 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_logne 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
ADMINetAUDITORpeuvent 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
<1msP99 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_id→auth_audit_log.event_id(N:1)auth_audit_log.batch_id→ batch Merkle externe (N:1 logique)judicial_export.filter_criteriaréférence un sous-ensemble deauth_audit_logauth_audit_access_logtrace les appels de lecture/export surauth_audit_logetjudicial_export- Une alerte génère un événement probatoire corrélé via
correlation_idpartagé
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 :
- Codes erreur :
400 BAD_REQUEST: AUTH_AUDIT_SCHEMA_INVALID401 UNAUTHORIZED: token service invalide403 FORBIDDEN: service non autorisé409 CONFLICT: AUTH_AUDIT_DUPLICATE_EVENT422 UNPROCESSABLE_ENTITY: failure_reason incohérent429 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 :
- Response 200 :
- Codes erreur :
400,401,403,404,409,422
4) Export judiciaire¶
- Endpoint :
POST /v1/audit/auth-events/judicial-export - Auth :
AUDITOR|ADMIN - Request :
- Response 202 :
- Response 200 (download metadata) :
- 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.successauth.login.failureauth.logoutauth.mfa.attemptauth.mfa.successauth.mfa.failureauth.device.revokedauth.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éeaudit.auth.anchor.status: mise à jour état d'ancrageaudit.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|AUDITORuniquement - 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.