Claude attache désormais des métadonnées de provenance C2PA signées aux fichiers qu'il génère. Il en va de même pour les modèles d'images d'OpenAI et, comme l'explique cet article sur Gemini. Pour la première fois, un véritable signal de provenance peut donc arriver jusqu'à votre point de terminaison de téléchargement. Pourtant, votre pipeline risque fortement de le supprimer avant qu'un utilisateur ne le voie.
Essayez Apidog dès aujourd’hui
Ce phénomène n'est généralement pas malveillant : il s'agit du comportement par défaut. sharp().resize() produit un fichier sans métadonnées, sauf si vous demandez explicitement leur conservation. ImageMagick et Pillow se comportent de manière similaire, tout comme la plupart des CDN d'images. Le manifeste entre, un JPEG plus petit ressort, et rien dans vos logs ne signale sa disparition.
Il s'agit d'une défaillance que vous pouvez tester rapidement. Voici comment les métadonnées disparaissent dans un pipeline courant, comment identifier l'étape responsable et comment ajouter une vérification de bout en bout dans la CI afin d'empêcher les régressions. Apidog orchestre le scénario HTTP ; c2patool vérifie le fichier au niveau des octets.
Ce qui est réellement détruit
Un manifeste C2PA est un bloc signé cryptographiquement, intégré dans le conteneur du fichier. Il indique qui a signé l'actif et ce qui est revendiqué à son sujet. Comme il est signé, toute modification des octets sans nouvelle signature peut être détectée par un lecteur compatible.
Le point important est le conteneur : dès que vous le réécrivez, le manifeste peut disparaître.
| Opération | Le manifeste survit-il par défaut ? |
|---|---|
| Copie ou déplacement bit-à-bit | Oui |
sharp().resize().toBuffer() |
Non |
ImageMagick convert / magick
|
Non |
Pillow Image.save()
|
Non |
| PNG vers WebP, JPEG vers AVIF | Non |
| Optimisation automatique par CDN d'images | Généralement non |
| Capture d'écran | Non |
| Réenregistrement depuis un éditeur d'images | Non |
| Téléchargement S3 sans transformation | Oui |
La plupart des opérations de la colonne « non » sont courantes dans une application web : création de miniatures, génération de variantes responsives, négociation de format ou suppression des métadonnées EXIF. Chacune est raisonnable isolément, mais chacune peut interrompre silencieusement la chaîne de provenance.
La suppression des métadonnées pour des raisons de confidentialité est souvent volontaire. Les données EXIF peuvent contenir des coordonnées GPS ou des numéros de série d'appareil photo. Cependant, une suppression globale avec -strip élimine également le manifeste de provenance. Il faut donc supprimer sélectivement les blocs EXIF concernés au lieu de supprimer toutes les métadonnées.
Prouvez-le en deux minutes
Avant de modifier votre pipeline, confirmez le problème avec un fichier signé. Une image générée par Claude convient, ou vous pouvez utiliser un échantillon signé fourni par l'Initiative pour l'Authenticité du Contenu.
Installez l'outil de ligne de commande de référence :
cargo install c2patool
Vérifiez ensuite le fichier original :
c2patool fixtures/signed-sample.png
Le résultat devrait contenir un rapport JSON indiquant le générateur de la revendication et le statut de la signature.
Faites maintenant passer le fichier par votre véritable parcours d'upload et de livraison :
# Téléchargement via votre véritable point de terminaison
curl -sS -X POST https://api.example.com/v1/assets \
-H "Authorization: Bearer $API_TOKEN" \
-F "file=@fixtures/signed-sample.png" \
-o /tmp/upload.json
# Récupération via l'URL utilisée par votre frontend
ASSET_URL=$(jq -r '.url' /tmp/upload.json)
curl -sS "$ASSET_URL" -o /tmp/roundtrip.png
# Le manifeste a-t-il survécu ?
c2patool /tmp/roundtrip.png
Interprétez le résultat selon trois cas :
- Rapport valide : le manifeste a survécu et sa signature est valide.
- Aucun manifeste trouvé : une étape du pipeline l'a supprimé. C'est le cas le plus courant.
- Erreur de validation : un manifeste est présent, mais sa signature ne correspond plus aux octets du fichier. Une transformation a probablement modifié le fichier en conservant l'ancien manifeste. Ce cas est plus grave qu'une simple suppression, car il signale une altération aux vérificateurs en aval.
Le troisième résultat apparaît généralement lorsqu'une bibliothèque conserve le bloc de métadonnées tout en réécrivant les pixels.
Identifiez l'étape responsable
Si le test de bout en bout échoue, vérifiez le fichier après chaque étape du pipeline. Ne vous limitez pas au fichier présent dans le stockage d'origine : testez aussi l'URL de livraison réellement utilisée par vos utilisateurs.
1. Redimensionnement et génération de miniatures
C'est le premier suspect. Dans sharp, les métadonnées sont supprimées par défaut :
// Supprime le manifeste C2PA
await sharp(input).resize(1200).toFile(output);
// Préserve le bloc de métadonnées
await sharp(input)
.resize(1200)
.keepMetadata()
.toFile(output);
Conserver le bloc ne suffit toutefois pas à conserver une signature valide. Les pixels ont changé ; la signature originale ne correspond donc plus aux nouveaux octets.
Pour maintenir une chaîne de provenance valide, vous devez :
- conserver le bloc de métadonnées ;
- re-signer la sortie ;
- enregistrer la transformation comme une assertion d'action, par exemple
c2pa.resized.
Les bibliothèques c2pa pour Rust, Python, JavaScript et C prennent en charge ce type d'intégration.
2. Conversion de format
Convertir une image vers AVIF ou WebP crée un nouveau conteneur. Vous devez alors préserver et re-signer la sortie, ou accepter que la chaîne de provenance s'arrête à cette étape et le signaler explicitement.
3. CDN d'images
De nombreux CDN réécrivent les fichiers au moment de la livraison. Certains conservent et re-signent désormais les Content Credentials nativement, mais ce n'était historiquement pas le cas de la plupart d'entre eux.
Testez toujours l'URL de livraison finale :
curl -sS "$DELIVERY_URL" -o /tmp/delivered-image
c2patool /tmp/delivered-image
Tester uniquement l'origine peut produire un résultat positif qui ne reflète pas le fichier réellement téléchargé par l'utilisateur.
4. Normalisation à l'ingestion
Les services qui réencodent les fichiers dès leur réception sont faciles à oublier. Cherchez ces transformations dans les dépôts d'infrastructure, les workers asynchrones et les fonctions déclenchées par l'upload.
Ajoutez un test permanent à la CI
Un curl ponctuel confirme uniquement l'état actuel du pipeline. Une modification future — par exemple l'ajout d'une étape de redimensionnement — peut réintroduire le problème.
Séparez la vérification en deux couches :
- un test de bout en bout pour valider le parcours HTTP ;
- une vérification au niveau des octets pour valider le manifeste C2PA.
Couche 1 : test de bout en bout dans Apidog
L'orchestration suit un scénario API classique :
- téléverser un fichier signé ;
- capturer l'URL renvoyée ;
- récupérer l'actif via le chemin de livraison réel ;
- vérifier la réponse HTTP et le fichier retourné.
Étape 1 : POST /v1/assets
Configurez une requête multipart/form-data contenant le fichier signé. La mécanique est la même que dans le test des API de téléchargement de fichiers.
Ajoutez les assertions suivantes :
- le statut HTTP vaut
201; - la réponse respecte votre schéma ;
- la réponse contient une URL de livraison.
Le script post-réponse peut transmettre l'URL à l'étape suivante :
const body = pm.response.json();
pm.environment.set("ASSET_URL", body.url);
pm.test("upload returns a delivery URL", function () {
pm.expect(body.url)
.to.be.a("string")
.and.to.include("https://");
});
Étape 2 : GET {{ASSET_URL}}
Vérifiez :
- le statut HTTP
200; - le
Content-Typeattendu ; - une taille de réponse cohérente avec le fichier envoyé.
Une diminution importante de la taille est un indice qu'un réencodage a eu lieu :
const uploadedBytes = Number(pm.environment.get("FIXTURE_BYTES"));
const returnedBytes = pm.response.responseSize;
pm.test("asset was not silently re-encoded", function () {
pm.expect(returnedBytes).to.be.above(uploadedBytes * 0.9);
});
La taille est une heuristique, pas une preuve cryptographique. Elle permet néanmoins de détecter rapidement les échecs flagrants dans la même suite que vos autres tests. Les modèles d'assertion standard sont présentés dans le guide des assertions API.
Couche 2 : vérification au niveau des octets dans la CI
La validation d'une signature nécessite l'analyse du conteneur. C'est le rôle de c2patool, pas celui du client HTTP.
Exécutez l'outil sur le fichier récupéré par le scénario de bout en bout :
# .github/workflows/provenance.yml
name: provenance
on: [pull_request]
jobs:
c2pa-round-trip:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install c2patool
run: cargo install c2patool
- name: Install Apidog CLI
run: npm install -g apidog-cli
- name: Run the round-trip scenario
run: |
apidog run --access-token "$APIDOG_ACCESS_TOKEN" \
-t "$SCENARIO_ID" \
-e "$ENV_ID" \
-r cli,html \
--out-dir ./apidog-reports
env:
APIDOG_ACCESS_TOKEN: ${{ secrets.APIDOG_ACCESS_TOKEN }}
SCENARIO_ID: ${{ vars.PROVENANCE_SCENARIO_ID }}
ENV_ID: ${{ vars.APIDOG_ENV_ID }}
- name: Verify the manifest survived
run: |
set -euo pipefail
curl -sS "$ASSET_URL" -o /tmp/roundtrip.png
c2patool /tmp/roundtrip.png > /tmp/report.json
jq -e '.validation_status == null or (.validation_status | length) == 0' /tmp/report.json
set -euo pipefail est indispensable. Sans cette option, un échec de c2patool sur un fichier dépouillé pourrait être traité comme un avertissement, laissant la CI au vert.
Si vous débutez avec l'exécution de scénarios Apidog dans un pipeline, consultez le guide sur l'automatisation des tests API dans GitHub Actions.
Couche 3, optionnelle : un point de terminaison de vérification
Si la provenance est une fonctionnalité exposée par votre produit, créez un petit point de terminaison dans votre service. Il peut exécuter la bibliothèque c2pa et renvoyer un résultat structuré.
Vos tests HTTP pourront alors vérifier un JSON normal :
{
"asset_id": "img_9f2c41",
"provenance": {
"status": "verified",
"standard": "c2pa",
"signer": "Anthropic",
"signature_valid": true,
"checked_at": "2026-08-11T09:14:22Z",
"tool": "c2patool/0.9"
}
}
Conservez au moins trois états distincts :
-
verified: manifeste présent et signature valide ; -
absent: aucun manifeste trouvé ; -
invalid: manifeste présent, mais signature invalide.
Ajoutez unchecked si le vérificateur peut être temporairement indisponible. Une panne de vérification ne doit pas être interprétée comme un résultat propre.
Documentez cette structure dans votre définition OpenAPI et validez-la afin d'éviter la disparition de champs lors d'une refactorisation. Le guide Comment valider les spécifications OpenAPI couvre cette étape.
Conservez quatre fichiers de test
Une suite de tests de provenance doit couvrir les cas négatifs, pas uniquement le parcours nominal.
-
Fichier signé valide : attendez
verified. Ce test détecte les suppressions involontaires. -
Fichier dépouillé : utilisez la même image, mais supprimez le manifeste avec
exiftool -all=. Attendezabsent, et non une erreur ouverified. -
Fichier altéré : modifiez un octet après la signature. Attendez
invalid. Ce test confirme que vous validez réellement la signature. -
Format non pris en charge : utilisez un fichier sans support de manifeste. Attendez un état
absentpropre plutôt qu'une erreur 500.
Commitez ces quatre fichiers dans le dépôt, à côté du scénario de test. Ils sont stables et permettent de détecter les régressions du pipeline.
Pourquoi cette vérification est importante
La promesse de votre produit
Si votre interface affiche un badge de provenance alors que votre pipeline supprime les manifestes après un redimensionnement, le badge est incorrect. Vous risquez de découvrir le problème uniquement lorsqu'un utilisateur le signale.
La conformité
Si vous utilisez C2PA pour répondre à des exigences liées à l'Article 50, un manifeste supprimé signifie qu'un contrôle ne fonctionne pas. La distinction entre fournisseur et déployeur dans l'Article 50 de l'EU AI Act pour les développeurs d'API aide à déterminer les obligations applicables.
La fiabilité du signal
La provenance n'est utile que si la chaîne est conservée de bout en bout. Chaque pipeline qui supprime silencieusement les manifestes réduit la valeur du signal pour l'ensemble de l'écosystème.
Téléchargez Apidog pour construire le scénario de test de bout en bout contre vos propres points de terminaison, puis ajoutez la vérification c2patool dans votre CI.
FAQ
Le redimensionnement d'une image supprime-t-il les métadonnées C2PA ?
Oui, par défaut dans les bibliothèques courantes. La conservation du bloc de métadonnées nécessite une option explicite. Pour conserver une signature valide après transformation, vous devez également re-signer la sortie.
Comment vérifier si un fichier contient des métadonnées C2PA ?
Exécutez la commande suivante :
c2patool <file>
Vous pouvez aussi déposer le fichier sur la page de vérification des Content Credentials.
Puis-je conserver les métadonnées C2PA lors d'un redimensionnement ?
Oui, mais la conservation seule ne suffit pas. Préservez le bloc, puis re-signez la sortie avec une assertion d'action telle que c2pa.resized, en utilisant l'une des bibliothèques c2pa. Sinon, l'ancienne signature ne correspondra plus aux nouveaux octets.
Les CDN suppriment-ils les Content Credentials ?
Beaucoup les suppriment lors de l'optimisation automatique. Certains les conservent et les re-signent désormais nativement. Testez l'URL de livraison réellement utilisée par vos utilisateurs, et non uniquement l'origine.
Quelle est la différence entre un manifeste supprimé et un manifeste invalide ?
Un manifeste supprimé signifie qu'aucun manifeste n'a été trouvé. Cela ne fournit aucune information sur l'origine du fichier.
Un manifeste invalide existe, mais sa signature ne correspond plus aux octets. Le fichier a donc été modifié après la signature. Conservez ces deux états séparément.
Apidog peut-il vérifier directement une signature C2PA ?
Apidog orchestre le test de bout en bout et vérifie les réponses HTTP, notamment le JSON d'un point de terminaison de vérification. L'analyse de la signature elle-même relève de c2patool, exécuté dans la CI ou dans votre propre service. Utilisez les deux outils ensemble.
Dois-je supprimer les données EXIF pour protéger la confidentialité tout en conservant C2PA ?
C'est l'objectif recommandé, mais il nécessite une approche sélective. Un -strip général supprime les données EXIF et le manifeste C2PA. Supprimez uniquement les blocs EXIF nécessaires et laissez le manifeste C2PA intact.
À retenir
Les métadonnées de provenance peuvent arriver intactes à votre API, puis disparaître pendant le redimensionnement, la conversion de format, l'optimisation CDN ou la livraison. Votre supervision ne le détectera pas forcément.
La solution est simple à automatiser :
- conservez un fichier signé comme fixture ;
- testez le parcours complet via l'URL de livraison réelle ;
- vérifiez le fichier retourné avec
c2patool; - faites échouer la CI lorsque le manifeste est absent ou invalide ;
- distinguez toujours les états
verified,absent,invalidet, si nécessaire,unchecked.
Une vingtaine de minutes de configuration suffit pour transformer une promesse affichée dans votre interface en une garantie effectivement appliquée par votre pipeline.
Top comments (0)