Immuabilité du stockage adressable par contenu
Problème
Dans les systèmes de stockage adressable par contenu (CAS), les fichiers sont identifiés par leur hash de contenu. Si vous modifiez un fichier sur place (même des optimisations « inoffensives »), le contenu ne correspond plus à son identifiant, ce qui compromet les garanties d'intégrité de tout le système.
Contexte / Conditions de déclenchement
- Travail avec le protocole Blossom (fichiers à
/{sha256}) - Travail avec IPFS (fichiers à
/ipfs/{CID}) - Tout système où le nom de fichier = hash du contenu
- Considération d'optimisations de fichiers comme :
- MP4 faststart (déplacement de l'atome moov)
- Optimisation/compression d'images
- Suppression de métadonnées
- Conversion de format
- Systèmes utilisant ProofMode ou vérification cryptographique
La règle fondamentale
NE MODIFIEZ JAMAIS un fichier stocké à son hash de contenu.
Le hash EST l'identité. Changer le contenu → changer le hash → le fichier se trouve maintenant à la mauvaise adresse.
Ce qui tourne mal
Fichier original : abc123... (hash) → contient les octets X
Après « optimisation » : abc123... (hash) → contient les octets Y
Résultat :
- Le hash abc123 ne se vérifie plus
- Les signatures ProofMode invalides
- Les recherches adressables par contenu retournent des données erronées
- Les preuves cryptographiques cassées
- L'intégrité des données compromise
Solution : Stocker les dérivés séparément
Si vous avez besoin de versions optimisées/traitées, stockez-les à des chemins séparés :
/{hash} ← Fichier original (NE JAMAIS MODIFIER)
/{hash}/hls/master.m3u8 ← Version transcodée HLS
/{hash}/faststart.mp4 ← Version optimisée faststart
/{hash}/thumb.jpg ← Miniature
/{hash}/720p.mp4 ← Variante de résolution
L'original reste identique octet par octet. Les dérivés se trouvent dans des sous-répertoires.
Modèle d'implémentation
// WRONG - modifie l'original
async fn process_video(hash: &str) {
let path = format!("/{}", hash);
let video = download(&path);
let optimized = apply_faststart(video);
upload(&path, optimized); // ❌ CASSE LE HASH !
}
// RIGHT - crée un dérivé
async fn process_video(hash: &str) {
let original_path = format!("/{}", hash);
let derivative_path = format!("/{}/faststart.mp4", hash);
let video = download(&original_path);
let optimized = apply_faststart(video);
upload(&derivative_path, optimized); // ✓ Original intact
}
Vérification
- Le hash du fichier original se vérifie toujours :
sha256sum file == filename - Les signatures ProofMode restent valides
- Les recherches de contenu retournent les données attendues
Erreurs courantes
- « C'est juste déplacer des métadonnées » - Change quand même les octets, casse quand même le hash
- « On mettra à jour la référence de hash » - Maintenant vous avez des références orphelines partout
- « Personne ne le remarquera » - Les systèmes de vérification LE remarqueront
- « C'est une optimisation » - Optimisez les dérivés, pas les originaux
Notes
- Ceci s'applique à TOUT système adressable par contenu, pas seulement Blossom
- IPFS, les objets Git, les couches Docker suivent tous ce principe
- Si vous avez besoin de la version optimisée comme principale, le client devrait la télécharger ainsi
- Le transcodage vers de nouveaux formats (HLS, DASH) est acceptable car ce sont clairement des fichiers distincts