Generated with the help of an LLM, reviewed and approved by me before posting.
Problem/Motivation
When a later tool re-signs a file, CredentialInspector::inspect() returns the types of the active manifest only. The AI origin recorded earlier, in the ingredient manifest, is lost and no suggestion is made.
Steps to reproduce
- Upload an image derivative signed by c2pa_sign. Its active manifest has a
c2pa.created action with digitalSourceType trainedAlgorithmicMedia. inspect() returns it and a Pending suggestion is queued.
- Upload the same file with c2pa_sign "Assert that files were uploaded" on. c2pa_sign re-signs it. The new active manifest has only
c2pa.opened and c2pa.creativeWork. The trainedAlgorithmicMedia action is in the parentOf ingredient.
inspect() returns {"isTrusted":true,"digitalSourceTypes":[],"signer":"C2PA Signer"}. No suggestion, nothing logged.
Proposed resolution
Could the digitalSourceType of a parentOf ingredient count when the active manifest has none? Or log a notice when a trusted manifest has no type, so the case is visible.
Found while testing the round trip with ai_disclosure. Drupal 11.4, 1.0.x-dev at 05e9424, c2pa_sign 1.4.11, c2patool 0.9.12.
Comments
Comment #12
maurice1969 commentedThanks for the clear report!
I could reproduce it with C2PA Sign 1.4.11 and c2patool 0.9.12, using a test PNG signed like your derivative. C2PA Sign puts
c2pa.opened+c2pa.creativeWorkon top, and the AI type ends up in theparentOfingredient. After publishing, it's signed once more, so the type sits two levels down.Both your options are in 1.0.x now and will be in alpha1:
– (b) A trusted manifest without a type logs a notice.
– (a) If the file's own manifest is trusted but has no type, the module takes it from the nearest
parentOfingredient, as long as that ingredient is trusted. With your setup you now get the suggestion, with a note that it was found "2 level(s) down".(a) took more work than expected. A file's "trusted" verdict says nothing about who signed the ingredient, so a file with an untrusted AI claim can still look trusted after re-signing.
provemark/content-credentials0.19.0 now gives each ingredient its own verdict, and only counts it when everything above it is trusted and nothing in the file reports a fault. I tried a few ways to trick it, like an AI manifest pasted over different pixels and then re-signed by C2PA Sign. Those stay refused.One thing to check on your side: C2PA Sign's own certificate needs to be in this module's trust anchors, or every upload it signs reads as untrusted.
Two more things I ran into:
– C2PA Sign 1.4.11 only works with c2patool 0.9.x; with 0.28.1 every upload failed, even a plain image. And 0.9.x can't read the newer C2PA 2.x format, so a 2.x file loses its credentials completely when C2PA Sign re-signs it. Your round trip is fine since both ends use the old format. I think that's worth an issue for C2PA Sign. Happy to write it up, and if you know the maintainer, a heads-up would help.
– On the verifier route, a C2PA Sign upload with a site logo read as untrusted, because the verifier didn't read the logo where c2patool 0.9.12 stores it. That's fixed in provemark/c2pa-verifier 0.6.1, which the module now asks for. So your setup gets the suggestion on all three routes.
Just curious: what added
trainedAlgorithmicMediato your derivative in step 1? As far as I can tell, C2PA Sign doesn't set a source type for image styles.Comment #16
maurice1969 commentedAs mentioned, I filed the C2PA Sign part as an issue there: c2pa_sign#3596032. On a test site C2PA Sign worked with a current c2patool after a few small changes, and then C2PA 2.x files kept their credentials too.