Ancrage temporel public
Prouver à un tiers (ou à toi-même dans 5 ans) que la chaîne d'audit existait à une date T précise, sans dépendre de l'horloge système ni d'une autorité de confiance unique.
Deux mécanismes en parallèle
Gratuit, irrévocable. Le hash d'un batch d'entrées est inclus dans une transaction Bitcoin via le protocole OTS. Une fois confirmé (~1-2h), prouvable indépendamment via n'importe quel nœud Bitcoin.
Pro : irrévocable, pas d'autorité centrale, vérifiable à perpétuité.
Con : pas qualifié eIDAS au sens strict (à compléter avec une TSA qualifiée pour le formalisme).
Universign, Lex Persona, ChamberSign, Certigna, GlobalSign, D-Trust. Token signé par une autorité qualifiée européenne, format RFC 3161 standard.
Pro : qualifié eIDAS, recevable directement en justice avec preuve QTSA.
Con : payant à l'usage, dépend de la TSA partenaire.
Stratégie : best-of-N
Tous les TSP enabled sont sollicités en parallèle pour chaque batch. Le bundle ASiC-E embarque tous les receipts qui ont répondu, dans anchors/{anchor_id}/{provider}.{ots|tsr}. Un seul provider suffit à prouver la date, mais avoir plusieurs souches d'ancrage rend la preuve robuste à la disparition d'un opérateur.
anchors/
├── 01900000-aaaa/
│ ├── opentimestamps.ots ← Bitcoin OTS
│ ├── universign.tsr ← RFC 3161 Universign
│ └── lex_persona.tsr ← RFC 3161 Lex Persona
└── 01900000-bbbb/
├── opentimestamps.ots
└── universign.tsr
Cycle d'ancrage
1. Cronapp:anchor:batch(toutes les 5 min ou ad hoc) : → trouve les audit_entry non-ancrées → calcule batch_hash = hash agrégé des entries du batch → dispatch un BatchAndAnchorMessage Symfony Messenger 2.messenger:consume asyncconsomme : → pour chaque TimestampingProvider tagged service "app.timestamp_provider" enabled (OTS + TSP eIDAS configurés) : → soumet batch_hash, reçoit un timestamp token → stocke dans anchor_token (status SUBMITTED) → si au moins UN provider a répondu : status anchor = SUBMITTED 3. Cronapp:anchor:upgrade(toutes les 15 min, Bitcoin pour OTS) : → re-tente la confirmation des OTS submittted depuis > 30 min → status passe à CONFIRMED quand le bloc Bitcoin est inclus dans la chaîne
Canary : un troisième mécanisme
Indépendant des ancrages, le canary tourne en boucle (5min en prod) et signe avec la master key un snapshot de l'état de la chaîne. Embarqué dans chaque bundle comme CANARY.json. Sert de point d'ancrage temporel continu à grain fin.
Combiné avec les ancrages OTS/TSP du batch, on a une triangulation forte :
- • OTS Bitcoin → preuve à ~1h près (granularité bloc)
- • TSP qualifié → preuve à la seconde, signée par autorité QTSA
- • Canary → preuve à 5 min près, signée master, en continu
Ancrage par session & couverture exigible
- La clôture (ou le refus) d'une session déclenche un ancrage immédiat — le scheduler 5 min n'est que le filet. Avec une TSA active (confirmée à l'émission), le bundle final arrive en secondes via
bundle.generated. - Le manifest signé de chaque bundle déclare sa couverture d'ancrage (
anchor_coverage: complete|partial|none) — les vérificateurs (CLI, viewer) refusent un bundle incomplet. POST /v1/proofsaccepterequire_anchored: true→422 ANCHORS_PENDINGtant que chaque entrée n'a pas une ancre CONFIRMED. C'est le mode à utiliser pour toute remise de preuve.