diff --git a/README.md b/README.md
index bcb3f65..c4a9a77 100644
--- a/README.md
+++ b/README.md
@@ -69,9 +69,12 @@ Ce dépôt héberge le prototype **fonctionnel et vérifiable** du premier servi
- une **heure traçable jusqu'à UTC** : le service recoupe deux serveurs de
laboratoires de métrologie (Observatoire de Paris, PTB) et **cesse d'émettre**
dès que la dérive dépasse le seuil annoncé, comme l'exige ETSI EN 319 421 ;
-- un **journal d'audit chaîné par hachage, contresigné par des TSA tierces
- publiques** (FreeTSA.org, DigiCert) : chaque scellement se vérifie avec les
- outils RFC 3161 standards, sans dépendre de la confiance en Open eIDAS ;
+- un **journal d'audit chaîné par hachage**, écrit *avant* chaque signature :
+ si le journal ne peut pas être écrit, aucun jeton ne sort. Le scellement de
+ la tête de chaîne par des TSA tierces publiques et la réplication hors site
+ existent en bibliothèques (`oe-crosstsa`, `oe-replicate`) mais **ne sont pas
+ encore câblés dans les services** — écart déclaré dans
+ [docs/CONFORMITE-ETSI.md](docs/CONFORMITE-ETSI.md) ;
- le tout orchestré en `docker compose`, démarrable en une commande.
Ce n'est pas encore une TSA qualifiée : les écarts avec le référentiel eIDAS
@@ -120,9 +123,6 @@ awk '/BEGIN CERTIFICATE/{n++} {print > (n == 1 ? "tsu.pem" : "ca.pem")}' tsa-cha
openssl ts -verify -in facture.tsr -queryfile facture.tsq -CAfile ca.pem
```
-L'interface d'administration de la PKI est disponible sur
- (certificat auto-signé).
-
### Relire le journal d'audit
```bash
@@ -167,7 +167,7 @@ crates/oe-castore/ registre de la CA (PostgreSQL, et mémoire pour les tests
crates/oe-hsm/ accès PKCS#11 aux clés de signature (seule crate autorisant `unsafe`)
crates/oe-timesource/ surveillance de la traçabilité de l'heure
crates/oe-audit/ journal d'audit chaîné par hachage
-crates/oe-crosstsa/ contreseing du journal par des TSA tierces publiques
+crates/oe-crosstsa/ contreseing du journal par des TSA tierces publiques (pas encore câblé)
crates/oe-enroll/ client d'enrôlement auprès de la CA
crates/oe-httpapi/ endpoints HTTP (RFC 3161 + façade JSON)
deploy/ images des trois services, chart Helm
diff --git a/crates/oe-conformance/src/lib.rs b/crates/oe-conformance/src/lib.rs
index 5052b7b..c5de71f 100644
--- a/crates/oe-conformance/src/lib.rs
+++ b/crates/oe-conformance/src/lib.rs
@@ -630,10 +630,10 @@ pub fn system_matrix() -> Matrix {
},
Entry {
requirement: Requirement { standard: "ETSI EN 319 401", clause: "§7.10", title: "Journalisation des événements et durée de conservation" },
- status: Status::Covered,
- mechanism: "Journal JSON Lines chaîné par SHA-256 (oe-audit) ; durée de conservation contrôlée à la configuration par oe_conformance::check_audit_retention, branché sur bin/ca-server::Config::load.",
+ status: Status::Gap,
+ mechanism: "Journal JSON Lines chaîné par SHA-256 (oe-audit), écrit avant chaque émission dans les deux services ; durée de conservation contrôlée à la configuration par oe_conformance::check_audit_retention, mais côté CA seulement (bin/ca-server::Config::load).",
test: "crates/oe-audit/src/lib.rs (deux_ecrivains_partagent_la_meme_chaine), crates/oe-conformance/src/lib.rs (check_audit_retention_accepts_the_minimum, check_audit_retention_rejects_unconfigured_and_short_durations)",
- target: "",
+ target: "Contrôler aussi la durée de conservation au démarrage de tsa-server (docs/CPS.md B.3).",
},
Entry {
requirement: Requirement { standard: "ETSI EN 319 401", clause: "§7.9", title: "Intégrité démontrable des enregistrements d'audit" },
@@ -644,10 +644,10 @@ pub fn system_matrix() -> Matrix {
},
Entry {
requirement: Requirement { standard: "ETSI EN 319 401", clause: "§7.11", title: "Continuité d'activité et reprise après sinistre" },
- status: Status::Covered,
- mechanism: "Contreseing du journal par une TSA tierce (oe-crosstsa) et réplication WebDAV hors site (oe-replicate), validés contre un vrai serveur.",
+ status: Status::Gap,
+ mechanism: "Contreseing du journal par une TSA tierce (oe-crosstsa) et réplication WebDAV hors site (oe-replicate) écrits et testés contre un vrai serveur, mais appelés par aucun binaire : l'intégrité et la survie du journal reposent sur le contrôle d'accès et la sauvegarde de son volume.",
test: "crates/oe-crosstsa/tests/against_local_server.rs (seals_a_digest_against_a_real_rfc3161_server), crates/oe-replicate/tests/against_local_server.rs (replicates_content_via_webdav_put)",
- target: "",
+ target: "Constat J-1 : câbler dans tsa-server serve puis ca-server serve le scellement périodique (log.sealed), le contreseing tiers (log.cross_sealed) et la copie hors site (PR #49, #50 pour le stockage S3), testés de bout en bout sur le binaire ; dégrader /healthz sur échec prolongé.",
},
Entry {
requirement: Requirement { standard: "ETSI EN 319 401", clause: "§7.12", title: "Plan de cessation d'activité" },
diff --git a/crates/oe-tsa-core/src/lib.rs b/crates/oe-tsa-core/src/lib.rs
index af712cd..46e5166 100644
--- a/crates/oe-tsa-core/src/lib.rs
+++ b/crates/oe-tsa-core/src/lib.rs
@@ -5,13 +5,11 @@
//! (`Clock`, équivalent du moniteur `oe-timesource`, jalon J4) pour produire
//! et signer un jeton d'horodatage réel.
//!
-//! **Écart assumé face à `internal/conformance`** : la vérification du
-//! profil du certificat TSU (`conformance.CheckTSUCertificate`, EN 319 421
-//! §7.7.2) n'est pas encore portée (`oe-conformance` la déclare `Gap`,
-//! jalon J3) — `Authority::new` ne la reproduit donc pas encore. Ce qui est
-//! bien vérifié ici : la correspondance clé publique du token ↔ certificat,
-//! et la fenêtre de validité temporelle du certificat, comme dans `tsa.New`
-//! (Go).
+//! `Authority::new` vérifie la correspondance clé publique du token ↔
+//! certificat, la fenêtre de validité temporelle du certificat, comme dans
+//! `tsa.New` (Go), et le profil du certificat TSU
+//! (`oe_conformance::check_tsu_certificate`, portage de
+//! `conformance.CheckTSUCertificate`).
use std::sync::Arc;
diff --git a/deploy/helm/open-eidas/values.yaml b/deploy/helm/open-eidas/values.yaml
index 1f551b8..6b228df 100644
--- a/deploy/helm/open-eidas/values.yaml
+++ b/deploy/helm/open-eidas/values.yaml
@@ -53,6 +53,9 @@ tsa:
sources: "ntp.obspm.fr,ptbtime1.ptb.de"
minSources: 2
maxOffset: 500ms
+ # Scellement du journal et contreseing par des TSA tierces : valeurs
+ # transmises au service, qui ne les exploite PAS encore (écart J-1, voir
+ # docs/ARCHITECTURE.md §7).
crossTSA:
urls: "https://freetsa.org/tsr,http://timestamp.digicert.com"
audit:
diff --git a/docker-compose.yml b/docker-compose.yml
index a66cdc4..ad909db 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -131,6 +131,8 @@ services:
OPENEIDAS_TIME_MIN_SOURCES: "2"
OPENEIDAS_TIME_MAX_OFFSET: 500ms
OPENEIDAS_AUDIT_FILE: /var/lib/open-eidas/state/audit.log
+ # Scellement, contreseing tiers et réplication du journal : lus par la
+ # configuration mais PAS encore exploités (écart J-1, docs/ARCHITECTURE.md §7).
OPENEIDAS_AUDIT_SEAL_INTERVAL: 1h
OPENEIDAS_CROSS_TSA_URLS: ${OPENEIDAS_CROSS_TSA_URLS:-https://freetsa.org/tsr,http://timestamp.digicert.com}
OPENEIDAS_AUDIT_REPLICA_URL: http://audit-replica/
diff --git a/docs/API.md b/docs/API.md
index 0f67456..c0d60c1 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -198,10 +198,10 @@ Toutes les options sont pilotées par variables d'environnement.
| `OPENEIDAS_SIGNING_DIGEST` | `sha256` | Empreinte utilisée pour signer le jeton |
| `OPENEIDAS_MAX_REQUEST_BYTES` | `65536` | Taille maximale d'une requête |
| `OPENEIDAS_AUDIT_FILE` | `/var/lib/open-eidas/audit.log` | Journal d'audit chaîné par hachage |
-| `OPENEIDAS_AUDIT_SEAL_INTERVAL` | `1h` | Période de scellement de la tête de chaîne (`0` désactive) |
-| `OPENEIDAS_CROSS_TSA_URLS` | `https://freetsa.org/tsr,http://timestamp.digicert.com` | TSA tierces contresignant chaque scellement, séparées par des virgules |
+| `OPENEIDAS_AUDIT_SEAL_INTERVAL` | `1h` | Période de scellement de la tête de chaîne (`0` désactive). **Lue mais pas encore exploitée** : aucun scellement n'a lieu (écart J-1) |
+| `OPENEIDAS_CROSS_TSA_URLS` | `https://freetsa.org/tsr,http://timestamp.digicert.com` | TSA tierces contresignant chaque scellement, séparées par des virgules. **Lue mais pas encore exploitée** (écart J-1) |
| `OPENEIDAS_CROSS_TSA_TIMEOUT` | `15s` | Délai d'attente par TSA tierce |
-| `OPENEIDAS_AUDIT_REPLICA_URL` | — | Base WebDAV où répliquer le journal à chaque scellement (vide = désactivé) |
+| `OPENEIDAS_AUDIT_REPLICA_URL` | — | Base WebDAV où répliquer le journal à chaque scellement (vide = désactivé). **Lue mais pas encore exploitée** (écart J-1) |
| `OPENEIDAS_AUDIT_REPLICA_USER` | — | Utilisateur WebDAV |
| `OPENEIDAS_AUDIT_REPLICA_PASSWORD` | — | Mot de passe WebDAV |
| `OPENEIDAS_AUDIT_REPLICA_TIMEOUT` | `30s` | Délai d'attente de la réplication |
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
index 312aac3..60a222c 100644
--- a/docs/ARCHITECTURE.md
+++ b/docs/ARCHITECTURE.md
@@ -194,67 +194,49 @@ quiconque relit le fichier — y compris sans accès au service :
docker compose exec tsa tsa-server verify-audit
```
-Y sont consignés l'ouverture du journal, chaque jeton émis (numéro de série,
-`genTime`, politique, empreinte soumise, présence d'un nonce), chaque refus
-avec son `failureInfo`, chaque mesure de temps avec l'écart par source, et
-chaque enrôlement de certificat. Le jeton émis est **relu avant d'être
-consigné** : le journal enregistre ce que contient réellement le jeton, pas ce
-que le service croit y avoir mis.
+Y sont consignés l'ouverture du journal, chaque jeton émis
+(`timestamp.granted` : `genTime`, politique, présence d'un nonce, et le numéro
+de série du **certificat** TSU), chaque refus avec son `failureInfo`
+(`timestamp.rejected`) et chaque mesure de temps avec l'écart par source
+(`time.measurement`). La CA tient son propre journal chaîné, où figurent les
+demandes d'enrôlement, les décisions RA, les émissions et les révocations.
+
+**Écart en cours de correction** (constat J-3 de l'audit du 2026-09-25,
+PR #52) : le journal de la TSA ne consigne pas encore le numéro de série du
+**jeton**, ni l'empreinte soumise, et le jeton n'est pas relu avant d'être
+consigné.
Deux propriétés rendent le dispositif exploitable :
-- **Une écriture ratée annule l'émission.** Si le journal ne peut pas être
- écrit, la requête échoue. Un jeton non tracé ne sort jamais du service.
+- **Une écriture ratée annule l'émission.** L'événement est écrit *avant* la
+ signature : si le journal ne peut pas être écrit, la requête échoue et rien
+ n'est signé. Un jeton non tracé ne sort jamais du service. Il en va de même
+ côté CA pour l'émission, la révocation et la publication de la CRL.
- **Un journal altéré empêche le démarrage.** La chaîne est vérifiée
intégralement à l'ouverture.
-La tête de chaîne est **scellée périodiquement**
-(`OPENEIDAS_AUDIT_SEAL_INTERVAL`, une heure par défaut) : la TSU horodate sa
-propre empreinte de tête et le jeton obtenu est inscrit au journal, ce qui
-date son contenu.
-
-### Contreseing par des TSA tierces
-
-Le scellement ci-dessus reste auto-référentiel : il ne prouve l'antériorité à
-un tiers que si l'on fait déjà confiance à la TSU elle-même. Le service
-soumet donc la même tête de chaîne à une ou plusieurs **TSA publiques
-indépendantes** (`OPENEIDAS_CROSS_TSA_URLS`, par défaut FreeTSA.org et
-DigiCert), via le protocole RFC 3161 standard, et consigne chaque attestation
-obtenue (`log.cross_sealed`) : émetteur, date, numéro de série et jeton
-complet en base64.
-
-Un auditeur n'a besoin de rien d'Open eIDAS pour vérifier une attestation : le
-certificat de la TSA tierce est public, et les outils standards suffisent —
-```bash
-openssl ts -query -digest -sha256 -no_nonce -out head.tsq
-openssl ts -verify -in -queryfile head.tsq \
- -CAfile -untrusted
-```
-— une réponse `Verification: OK` établit que la tête de chaîne, donc tout le
-journal qu'elle couvre par construction, existait à la date attestée par une
-autorité qui n'a aucun lien avec Open eIDAS.
-
-L'indisponibilité d'une TSA tierce est journalisée mais non bloquante : le
-scellement propre au service continue, et les autres TSA configurées
-prennent le relais.
-
-### Réplication hors site
-
-Un journal chaîné et contresigné ne protège que contre l'altération — pas
-contre la perte de l'instance elle-même (panne disque, compromission,
-suppression accidentelle). À chaque scellement, le service dépose donc une
-copie complète et datée du journal (`audit--seq.log`) sur un
-serveur **WebDAV** distant (`OPENEIDAS_AUDIT_REPLICA_URL`) : Nextcloud, un
-stockage d'objets exposé en WebDAV, ou tout hébergeur souverain qui l'offre —
-aucun fournisseur particulier n'est imposé.
-
-Chaque copie est un journal complet et vérifiable indépendamment :
-```bash
-tsa-server verify-audit audit-20260906T145600Z-seq000030.log
-```
-retrouve exactement la même chaîne de hachage que sur l'instance d'origine,
-jusqu'au numéro de séquence capturé. L'échec de la réplication est
-journalisé mais non bloquant, comme pour le contreseing tiers.
+### Limite : l'intégrité repose sur l'hôte (écart déclaré)
+
+Le chaînage SHA-256 n'utilise pas de clé : quiconque peut écrire dans le
+fichier peut en tronquer la fin ou le réécrire en recalculant la chaîne, sans
+que `verify-audit` le voie. Ce qui ancre la tête de chaîne hors du système
+**n'est pas encore en service** (constat J-1) :
+
+- **Scellement périodique** par la TSU elle-même (`log.sealed`) : le format
+ est prévu (`oe_audit::EVENT_SEALED`, compté par `verify-audit`), mais aucun
+ service ne scelle.
+- **Contreseing par des TSA tierces** indépendantes (`oe-crosstsa`, protocole
+ RFC 3161 standard, vérifiable par `openssl ts -verify` sans rien d'Open
+ eIDAS) : bibliothèque écrite et testée contre un vrai serveur, non câblée.
+- **Réplication hors site** : `oe-replicate` (WebDAV) est écrit et testé, non
+ câblé ; une copie vers un stockage objet compatible S3 auto-hébergé est en
+ cours (PR #49 et #50).
+
+Les variables `OPENEIDAS_AUDIT_SEAL_INTERVAL`, `OPENEIDAS_CROSS_TSA_URLS` et
+`OPENEIDAS_AUDIT_REPLICA_*` du `docker-compose.yml` et du chart Helm sont
+lues sans être exploitées. D'ici là, l'intégrité du journal revient au
+contrôle d'accès de son volume (voir [CPS.md](CPS.md) B.3 et
+[CONFORMITE-ETSI.md](CONFORMITE-ETSI.md)).
## 8. Écarts assumés du prototype vis-à-vis d'une TSA qualifiée
@@ -269,10 +251,10 @@ ci-dessous en donne la lecture d'ensemble.
| Source de temps | Surveillance NTP de deux sources UTC(k) avec suspension automatique de l'émission | Réception redondante et indépendante, calibration documentée, journal des mesures conservé et audité |
| Cérémonie de clé | Scriptée, idempotente, procès-verbal consigné au journal d'audit (empreintes, opérateur, horodatage) — mais sans double contrôle ni témoin | Double contrôle, témoin indépendant, HSM certifié, racine hors ligne après cérémonie (voir [CA.md](CA.md)) |
| Approbation RA | Point d'approbation réellement actif : aucun chemin du code ne mène à l'émission sans décision d'un opérateur identifié, consignée en base et au journal. Automatisée sous un compte technique pour que la démonstration/CI s'amorce sans opérateur humain | Revue humaine réelle par un opérateur RA nominatif, à la place de l'approbation automatisée |
-| Journalisation | Journal chaîné par hachage, contresigné par des TSA tierces publiques et répliqué hors site à chaque scellement ; durée de conservation contrôlée au démarrage | Politique de conservation formalisée, réplication multi-région |
+| Journalisation | Journal chaîné par hachage, écrit avant chaque émission ; durée de conservation contrôlée au démarrage côté CA seulement. Scellement, contreseing tiers et réplication hors site **non câblés** (écart J-1) | Scellement et contreseing périodiques, copie hors site, conservation contrôlée côté TSA, politique de conservation formalisée |
| Politique d'horodatage | OID de test `1.3.6.1.4.1.99999.1.1.1` ; brouillon de Policy/Practice Statement dans [CPS.md](CPS.md) | OID sous l'arc PEN de l'association, [CPS.md](CPS.md) adopté formellement et publié |
| Profils de certificat | Structures Rust compilées et testées ; le certificat émis est relu depuis son DER et re-contrôlé avant délivrance ; CDP, AIA `ca_issuers` et répondeur OCSP réellement publiés et vérifiés | OID de politique de certification propre |
-| Continuité | Instance unique ; registre PostgreSQL sauvegardable, journal répliqué hors site | Redondance active/active, sauvegarde et restauration testées, plan de cessation d'activité engagé (voir [CA.md](CA.md)) |
+| Continuité | Instance unique ; registre PostgreSQL sauvegardable ; journal **non** répliqué hors site (écart J-1) | Redondance active/active, sauvegarde et restauration testées, plan de cessation d'activité engagé (voir [CA.md](CA.md)) |
| Audit | Aucun | Évaluation par un organisme accrédité (LSTI, Apave), inscription à la liste de confiance |
Le prototype refuse de démarrer sur les écarts qui rendraient les jetons ou
diff --git a/docs/CA.md b/docs/CA.md
index 457325e..817006a 100644
--- a/docs/CA.md
+++ b/docs/CA.md
@@ -381,12 +381,12 @@ l'URL, le serveur qui publie et le répondeur OCSP qui va chercher la CRL.
|---|---|---|
| Vol de la clé de la CA émettrice | La clé ne quitte jamais le token PKCS#11 ; seul le conteneur `ca` y accède | SoftHSM2 est logiciel : qui obtient le volume et le PIN obtient la clé. Un HSM certifié lève ce point |
| Vol du secret HMAC d'enrôlement | Il authentifie le demandeur, il ne décide pas : toute demande reste soumise à approbation | Une clé volée permet de déposer des demandes, pas d'en faire émettre |
-| Compromission d'un opérateur RA | Chaque décision est consignée avec son auteur ; le journal est chaîné, scellé et répliqué hors site | Un opérateur seul peut approuver : il n'y a pas de double validation |
+| Compromission d'un opérateur RA | Chaque décision est consignée avec son auteur dans le journal chaîné | Un opérateur seul peut approuver : il n'y a pas de double validation. Le journal n'est ni scellé ni répliqué hors site (écart J-1) : un accès en écriture à son volume permet de le réécrire |
| Numéro de série prédit ou rejoué | 128 bits sur `crypto/rand`, unicité portée par la clé primaire du registre | — |
| Certificat non conforme émis | Le DER produit est relu et re-contrôlé avant d'être enregistré ; l'émission est annulée sinon | — |
| CRL ancienne rejouée pour masquer une révocation | `CRLNumber` strictement croissant, servi par une séquence PostgreSQL ; le répondeur OCSP refuse de répondre plutôt que de servir un statut obsolète | — |
-| Altération du journal d'audit | Chaînage par hachage vérifié à l'ouverture ; un journal altéré empêche le démarrage | — |
-| Perte de l'instance | Registre PostgreSQL sauvegardable, journal répliqué hors site à chaque scellement | Sauvegarde et restauration non encore testées de bout en bout |
+| Altération du journal d'audit | Chaînage par hachage vérifié à l'ouverture ; un journal altéré empêche le démarrage | Chaînage sans clé : une réécriture complète avec recalcul de la chaîne n'est pas détectée tant que la tête n'est pas scellée hors du système (écart J-1) |
+| Perte de l'instance | Registre PostgreSQL sauvegardable | Journal non répliqué hors site (écart J-1) ; sauvegarde et restauration non encore testées de bout en bout |
## 8. Continuité et cessation d'activité
@@ -398,8 +398,8 @@ Ce qui doit être sauvegardé, et suffit à reconstituer l'autorité :
définitivement perdue ;
2. la **base PostgreSQL** — registre des certificats, demandes, historique des
CRL ;
-3. le **journal d'audit** (volume `castate`), déjà répliqué hors site à chaque
- scellement.
+3. le **journal d'audit** (volume `castate`) — pas encore répliqué hors site
+ (écart J-1) : à sauvegarder avec le reste.
État actuel : instance unique, sauvegarde non automatisée. C'est un écart
documenté ; la cible est une redondance active/active, une sauvegarde
diff --git a/docs/CONFORMITE-ETSI.md b/docs/CONFORMITE-ETSI.md
index 0a5dcf0..f28e5e9 100644
--- a/docs/CONFORMITE-ETSI.md
+++ b/docs/CONFORMITE-ETSI.md
@@ -5,7 +5,7 @@
correction se fait dans le code, pour que la matrice publiée reste
celle que le système applique réellement. -->
-**28 exigences** — 24 couvertes, 2 écarts documentés, 2 hors périmètre logiciel.
+**28 exigences** — 22 couvertes, 4 écarts documentés, 2 hors périmètre logiciel.
Trois statuts seulement, pour qu'aucune zone grise ne puisse s'y loger :
@@ -18,9 +18,9 @@ Trois statuts seulement, pour qu'aucune zone grise ne puisse s'y loger :
| Clause | Exigence | Statut | Mécanisme | Vérification / cible |
|---|---|---|---|---|
| §7.4 | Gestion des clés du prestataire dans un module cryptographique | couvert | Toutes les clés vivent dans un token PKCS#11 et n'en sortent jamais : oe-hsm::Pkcs11Token, validé contre un vrai token SoftHSM2 (crates/oe-hsm/tests/pkcs11_integration.rs). | crates/oe-hsm/tests/pkcs11_integration.rs |
-| §7.10 | Journalisation des événements et durée de conservation | couvert | Journal JSON Lines chaîné par SHA-256 (oe-audit) ; durée de conservation contrôlée à la configuration par oe_conformance::check_audit_retention, branché sur bin/ca-server::Config::load. | crates/oe-audit/src/lib.rs (deux_ecrivains_partagent_la_meme_chaine), crates/oe-conformance/src/lib.rs (check_audit_retention_accepts_the_minimum, check_audit_retention_rejects_unconfigured_and_short_durations) |
+| §7.10 | Journalisation des événements et durée de conservation | écart documenté | Journal JSON Lines chaîné par SHA-256 (oe-audit), écrit avant chaque émission dans les deux services ; durée de conservation contrôlée à la configuration par oe_conformance::check_audit_retention, mais côté CA seulement (bin/ca-server::Config::load). | **Cible :** Contrôler aussi la durée de conservation au démarrage de tsa-server (docs/CPS.md B.3). |
| §7.9 | Intégrité démontrable des enregistrements d'audit | couvert | Chaînage par hachage vérifié intégralement à l'ouverture ; verrou de fichier partagé entre plusieurs écrivains d'un même processus : oe-audit::Log. | crates/oe-audit/src/lib.rs (deux_ecrivains_partagent_la_meme_chaine, verify_detects_modified_record, verify_detects_truncated_and_rewritten_tail) |
-| §7.11 | Continuité d'activité et reprise après sinistre | couvert | Contreseing du journal par une TSA tierce (oe-crosstsa) et réplication WebDAV hors site (oe-replicate), validés contre un vrai serveur. | crates/oe-crosstsa/tests/against_local_server.rs (seals_a_digest_against_a_real_rfc3161_server), crates/oe-replicate/tests/against_local_server.rs (replicates_content_via_webdav_put) |
+| §7.11 | Continuité d'activité et reprise après sinistre | écart documenté | Contreseing du journal par une TSA tierce (oe-crosstsa) et réplication WebDAV hors site (oe-replicate) écrits et testés contre un vrai serveur, mais appelés par aucun binaire : l'intégrité et la survie du journal reposent sur le contrôle d'accès et la sauvegarde de son volume. | **Cible :** Constat J-1 : câbler dans tsa-server serve puis ca-server serve le scellement périodique (log.sealed), le contreseing tiers (log.cross_sealed) et la copie hors site (PR #49, #50 pour le stockage S3), testés de bout en bout sur le binaire ; dégrader /healthz sur échec prolongé. |
| §7.12 | Plan de cessation d'activité | hors périmètre logiciel | Procédure organisationnelle décrite dans docs/CA.md, indépendante du langage d'implémentation. | **Cible :** Engagement juridique de l'association, dépôt auprès de l'organe de contrôle, séquestre des journaux. |
| §6.1 | Politique de service et déclaration des pratiques publiées | écart documenté | docs/CPS.md porte un brouillon structuré, déjà indépendant du langage d'implémentation du service. | **Cible :** Adoption formelle de docs/CPS.md par l'association (organisationnel, non affecté par le portage Rust). |