Audit Gateway et Evidence Service : modèle de sécurité
Cette page décrit les garanties vérifiées par les tests de la section 11 du kit (services/control-plane/tests/test_evidence_gateway.py, services/control-plane/tests/test_evidence_config_redaction.py). Le mode opératoire est dans ../operations/siem-audit.md.
Garanties
| Garantie | Mécanisme | Preuve de test |
|---|---|---|
| Aucun événement perdu | événement et ligne eai.audit_outbox écrits dans la transaction du changement ; annulation = ni changement ni événement | test_rolled_back_change_leaves_no_event_and_committed_one_always_has_it |
| Livraison sans échantillonnage, reprise après panne | job audit_gateway, recul exponentiel, ordre par séquence, clé d'idempotence, déduplication côté récepteur | test_gateway_redelivers_after_target_outage_without_loss_or_duplicate, test_gateway_publishes_to_real_jetstream_with_dedup (nats-server 2.15.2 réel) |
| Trous de séquence détectés | contrôle de contiguïté de la boîte d'envoi, alerte sequence_gap | test_gateway_detects_outbox_sequence_gap |
| Scellement vérifiable | JSON canonique RFC 8785, racine de Merkle sha256, hachage du sceau précédent, signature Ed25519, identifiant de clé | test_seal_signature_verifies_online_and_offline, test_forged_seal_signature_is_rejected |
| Altération détectée | moniteur audit_integrity sur chaîne, sceaux et horodatages | test_monitor_detects_sql_tampering_of_a_sealed_event |
| Horodatages distincts | event_time < ingested_at < sealed_at, tolérance de dérive bornée | test_event_time_ingested_at_sealed_at_are_distinct_and_ordered |
| Séparation d'accès aux charges utiles | enveloppe Tink, clé hors base, déchiffrement réservé à auditor et security_officer, refusé à platform_admin | test_payload_encrypted_and_only_auditor_decrypts_with_audited_reason |
| Accès audités | chaque lecture, recherche, vérification, export écrit son événement | test_reads_searches_and_exports_are_audited |
| Conservation légale | blocage de la purge et de l'effacement, levée par deux approbateurs distincts, preuve de purge sans contenu | test_legal_hold_blocks_purge_and_release_needs_two_distinct_approvers |
| Pas de secret ni de donnée personnelle dans les journaux | masquage dans eai.logs (message, champs, exceptions) ; masquage des identifiants dans les métadonnées d'audit | test_secrets_and_pii_never_reach_logs, test_audit_metadata_has_no_credentials_and_pii_goes_to_the_encrypted_payload |
| Sauvegarde et restauration | chaîne, sceaux, conservation légale et preuves de purge vérifiés après pg_backup.sh et pg_restore.sh | test_restored_backup_keeps_verifiable_chain_seals_and_hold_state |
Rôles et accès
| Opération | Route | Rôles |
|---|---|---|
| Lister les sceaux, vérifier un sceau ou toute la chaîne | GET /v1/evidence/seals, GET /v1/evidence/seals/{seal_id}/verify, GET /v1/evidence/verify | auditor, security_officer, tenant_admin |
| Sceller maintenant | POST /v1/evidence/seals | security_officer, auditor |
| Exporter le lot vérifiable hors ligne | GET /v1/evidence/bundle | auditor, security_officer |
| Déchiffrer la charge d'un événement, avec une raison | POST /v1/evidence/events/{event_id}/payload | auditor, security_officer seulement (contrôle explicite, platform_admin refusé) |
| Journal des accès | GET /v1/evidence/access-log | auditor, security_officer |
| Alertes d'intégrité, état de la passerelle | GET /v1/evidence/alerts, GET /v1/evidence/gateway | auditor, security_officer, tenant_admin |
| Poser, lister, lever une conservation légale | POST /v1/evidence/holds, GET /v1/evidence/holds, POST /v1/evidence/holds/{hold_id}/release | auditor, security_officer, tenant_admin |
| Lancer la purge des charges | POST /v1/evidence/retention/run | security_officer, tenant_admin |
| Lire les preuves de purge | GET /v1/evidence/retention/evidence | auditor, security_officer, tenant_admin |
La levée d'une conservation légale demande deux appels de deux approbateurs distincts : la conservation est levée à la seconde approbation ; le même approbateur deux fois reçoit 409 audit_hold_same_approver.
Réglages exigés en production
La garde de démarrage (eai.security.startup) refuse en production :
EAI_AUDIT_SEAL_SIGNING_KEY_REFabsent (la clé Ed25519 des sceaux doit venir d'OpenBao,EAI_AUDIT_SEAL_SIGNING_KEYen PEM ne sert qu'en développement et en test) ;EAI_AUDIT_PAYLOAD_KEKdifférent deopenbao-transit;EAI_AUDIT_SIGNINGàhmac, ouEAI_OPENBAO_URLetEAI_OPENBAO_TOKENabsents (signature des exports WORM) ;EAI_AUDIT_CLOCK_SKEW_SECONDShors de 0 à 3600.
La liste complète des réglages de l'Audit Gateway (intervalles, lots, tentatives, sujet NATS, collecteur HTTP) est dans ../operations/siem-audit.md.
Vérifier une preuve hors ligne
Le lot de GET /v1/evidence/bundle porte un manifeste signé par la clé des sceaux. Il se vérifie sans accès à la plateforme avec le module eai.domains.evidence.verify :
cd services/control-plane
.venv/bin/python -m eai.domains.evidence.verify <bundle.json>
<bundle.json> : le fichier renvoyé par GET /v1/evidence/bundle. Résultat : un rapport JSON (valid, chain, seals, clock), code de sortie 0 si le lot est valide, 1 sinon.
Une signature fausse ou un événement modifié après scellement est signalé (test_seal_signature_verifies_online_and_offline, test_forged_seal_signature_is_rejected).
Voir aussi : risk-compliance.md (preuves et catalogue de contrôles), retention-privacy.md (conservations légales et effacement).
Limites
- Le rôle propriétaire de la base peut modifier les lignes : l'altération est détectée (chaîne, sceaux signés), pas empêchée. L'immuabilité du stockage relève de l'export WORM, qualifié seulement avec un profil de stockage à verrouillage d'objet vérifié.
- La révision du bundle OPA n'est enregistrée que lorsque la décision la fournit.