open-standards/wai/live-conformance/c2pa-identity
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science 1a63a8d66e
Some checks failed
wai-audit collector and player integration / does this change touch it (push) Successful in 15s
joule-moq-web browser client / joule-moq-web · does this change touch it (push) Successful in 20s
joule-moq-remote host agent / joule-moq-remote · does this change touch it (push) Successful in 22s
wai-fleet service / does this change touch it (push) Successful in 20s
wai-sink-android native sink library / does this change touch it (push) Successful in 9s
WAI Studio / does this change touch it (push) Successful in 13s
wai-sink-swift native sink package / does this change touch it (push) Successful in 14s
wai-app and Create / wai-app · does this change touch it (push) Successful in 2m16s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 10s
WAI examples / WAI examples · does this change touch them (push) Successful in 8s
wai-quantum for JavaScript / does this change touch it (push) Successful in 3m41s
joule-moq-room room service / joule-moq-room · does this change touch it (push) Successful in 3m44s
wai-ledger service / does this change touch it (push) Successful in 3m44s
WAI operation catalogue / does this change touch it (push) Successful in 3m45s
wai-quantum studio and desktop / does this change touch it (push) Successful in 3m48s
joule-moq-http live HTTP egress / joule-moq-http · does this change touch it (push) Successful in 3m58s
wai-pack / wai-pack · does this change touch it (push) Successful in 3m53s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Successful in 1m39s
wai-audit collector and player integration / collector · linux (push) Successful in 3m21s
wai-fleet service / service · linux (push) Successful in 3m14s
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (push) Successful in 1m3s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Successful in 2m30s
wai-ledger service / service · linux (push) Successful in 2m37s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Successful in 7m31s
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (push) Successful in 2m28s
wai-pack / wai-pack · linux (push) Successful in 5m27s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Successful in 4m26s
wai-quantum for JavaScript / javascript · linux (push) Successful in 10m50s
wai-quantum studio and desktop / studio · browser (push) Successful in 9m7s
WAI operation catalogue / the catalogue and every door · linux (push) Successful in 10m45s
wai-quantum studio and desktop / desktop app · linux (push) Successful in 9m41s
WAI Studio / Studio in WebKit · linux (push) Successful in 26m7s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Failing after 13m17s
WAI examples / WAI examples · portable · linux (push) Successful in 22m54s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Successful in 2m0s
joule-moq-remote host agent / joule-moq-remote, every target (macos) (push) Successful in 52s
wai-fleet service / service · macos (push) Successful in 44s
joule-moq-http live HTTP egress / joule-moq-http, every target (push) Successful in 3m28s
wai-pack / wai-pack · linux-arm64 (push) Successful in 4m36s
wai-pack / wai-pack · the floor through a media prober (push) Successful in 1m49s
wai-pack / wai-pack · dependency licences (push) Successful in 2m5s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Successful in 9m44s
WAI Studio / Studio in Chromium and Firefox · macos (push) Successful in 10m57s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (push) Successful in 14m29s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Successful in 13m11s
joule-moq-room room service / joule-moq-room, every target (push) Successful in 10m22s
WAI examples / WAI examples · android-app · linux-arm64 (push) Successful in 11m25s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (push) Successful in 8m51s
wai-ledger service / service · macos (push) Successful in 1m8s
wai-pack / wai-pack · independent verifier (Python) (push) Successful in 21m13s
wai-pack / wai-pack · macos (push) Successful in 3m53s
wai-quantum studio and desktop / desktop app · macos (push) Successful in 5m53s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (push) Successful in 22m0s
wai-quantum studio and desktop / desktop app · windows (push) Successful in 13m39s
Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization
Every identity assertion WAI wrote was reported cawg.x509.signature.mismatch by the C2PA SDK's
validator. Read at their sources: Identity Assertion 1.0 to 1.3 §8.2.1 (the payload is serialized
in RFC 8949 §4.2.1's core deterministic encoding and those bytes are signed; no later version or
erratum), and the c2pa crate at 0.91.7 and 0.91.11, its newest release, which signs and verifies
its own serialization of the payload's members in the schema's order (referenced_assertions,
sig_type, role; url, alg, hash) with the writer that keeps declaration order. The bytes signed
were the whole difference: the COSE structure, protected header, sig_type, hashed URIs and chain
of a WAI assertion and of one the SDK's builder writes are the same.

c2pa-binding §4.10, §4.11, §6.2 step 12, §6.3, §9.2, §9.3 and decisions D6 (revised): a writer
signs the schema's order by default and may be asked for the core deterministic encoding
(identity::Signed); the stored assertion stays deterministic either way. The verifier accepts a
signature over either serialization of the payload's members, states which, and refuses one over
a third order, over other members, or by another key. On the SDK's path an identity assertion is
read in any well-formed encoding (one the SDK's builder wrote is accepted) and a map with a key
twice is refused.

Tests run the SDK's validator, configured with the corpora's anchors, on manifests signed
through the SDK and on the store writer's stores beside their envelopes: trusted, no failure
code, cawg.x509.credential.trusted, cawg.x509.signature.validated and cawg.identity.well-formed
for each identity assertion. The strict form gets exactly cawg.x509.signature.mismatch, pinned.
c2pa-sdk-identity/vectors.json pins the validator's report of every file at the SDK's version.

Both corpora regenerated with their tools (c2pa-identity byte for byte on x86_64 and aarch64);
new vectors for the strict form, the SDK builder's assertion, a signature over a third order and
over other members. Both Python verifiers compute the two serializations themselves and are
caught without either and when they take the members in any order. The wire break and the
three API changes are acknowledged in the change note.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
2026-11-11 09:58:01 -05:00
..
bound-identity-deterministic Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
bound-iscc-binding Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
bound-iscc-binding-only ISCC: the io.iscc.v0 soft binding in a C2PA store, matching on every code, the Meta-Code held to IEP-0002, and the Unicode tables pinned 2026-11-10 22:36:11 -05:00
detection-in-manifest Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
identity-algorithm Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
identity-credential-swapped Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
identity-duplicate-reference Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
identity-expired Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
identity-hard-binding-missing Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
identity-over-other-claim Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
identity-pad-nonzero Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
identity-pad1-missing Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
identity-sig-type-unknown Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
identity-signed-other-members Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
identity-signed-third-order Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
identity-untrusted Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
identity-wrong-purpose Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
iscc-altered-content Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
iscc-binding-as-text ISCC: the io.iscc.v0 soft binding in a C2PA store, matching on every code, the Meta-Code held to IEP-0002, and the Unicode tables pinned 2026-11-10 22:36:11 -05:00
iscc-binding-before-watermark ISCC: the io.iscc.v0 soft binding in a C2PA store, matching on every code, the Meta-Code held to IEP-0002, and the Unicode tables pinned 2026-11-10 22:36:11 -05:00
iscc-binding-claims-robustness-record ISCC: the io.iscc.v0 soft binding in a C2PA store, matching on every code, the Meta-Code held to IEP-0002, and the Unicode tables pinned 2026-11-10 22:36:11 -05:00
iscc-binding-featureless-image-code ISCC: the io.iscc.v0 soft binding in a C2PA store, matching on every code, the Meta-Code held to IEP-0002, and the Unicode tables pinned 2026-11-10 22:36:11 -05:00
iscc-binding-instance-of-altered-bytes ISCC: the io.iscc.v0 soft binding in a C2PA store, matching on every code, the Meta-Code held to IEP-0002, and the Unicode tables pinned 2026-11-10 22:36:11 -05:00
iscc-binding-no-generator ISCC: the io.iscc.v0 soft binding in a C2PA store, matching on every code, the Meta-Code held to IEP-0002, and the Unicode tables pinned 2026-11-10 22:36:11 -05:00
iscc-binding-other-asset ISCC: the io.iscc.v0 soft binding in a C2PA store, matching on every code, the Meta-Code held to IEP-0002, and the Unicode tables pinned 2026-11-10 22:36:11 -05:00
iscc-binding-short-units ISCC: the io.iscc.v0 soft binding in a C2PA store, matching on every code, the Meta-Code held to IEP-0002, and the Unicode tables pinned 2026-11-10 22:36:11 -05:00
iscc-binding-truncated ISCC: the io.iscc.v0 soft binding in a C2PA store, matching on every code, the Meta-Code held to IEP-0002, and the Unicode tables pinned 2026-11-10 22:36:11 -05:00
iscc-binding-twice ISCC: the io.iscc.v0 soft binding in a C2PA store, matching on every code, the Meta-Code held to IEP-0002, and the Unicode tables pinned 2026-11-10 22:36:11 -05:00
iscc-binding-unit-missing ISCC: the io.iscc.v0 soft binding in a C2PA store, matching on every code, the Meta-Code held to IEP-0002, and the Unicode tables pinned 2026-11-10 22:36:11 -05:00
iscc-other-picture Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
objects Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
robustness C2PA stores carry identity assertions, soft bindings and the ISCC identifier, trust lists are pinned by digest, and a detection verdict is a claim of its own 2026-11-10 15:25:49 -05:00
signer-outside-trust-list Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
soft-binding-claim-lacks-attack Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
soft-binding-unmarked-asset C2PA stores carry identity assertions, soft bindings and the ISCC identifier, trust lists are pinned by digest, and a detection verdict is a claim of its own 2026-11-10 15:25:49 -05:00
soft-binding-wrong-asset Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
trust C2PA stores carry identity assertions, soft bindings and the ISCC identifier, trust lists are pinned by digest, and a detection verdict is a claim of its own 2026-11-10 15:25:49 -05:00
README.md Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00
vectors.json Identity assertions validate in the C2PA SDK's validator: the holder signs the schema's order by default, a verifier accepts either serialization 2026-11-11 09:58:01 -05:00

live-conformance/c2pa-identity — trust lists, soft bindings, the ISCC soft binding and identifier, and identities

The corpus of extensions/c2pa-binding.md §9.2: C2PA Manifest Stores beside stored WAI envelopes that carry, after the three assertions of §4.1, soft bindings of wai-mark:tent64 (§4.8), the ISCC soft binding io.iscc.v0 and the ISCC identifier (§4.9) and the Creator Assertions Working Group's identity assertions (§4.10), verified against trust lists pinned by digest (§6.4); and what a verifier states of each.

Files. vectors.json lists the vectors, each its name, envelope, store, receipts (as in c2pa-envelope/), claimLists and identityLists (the trust lists its verifier is configured with, each its file, the uri and type the verifier names it by, and the digest it pinned), robustness (the robustness record and claims its verifier was given, in order) and expect. trust/ holds the lists in the form the C2PA Trust List is published in; robustness/ the record of wai-mark:tent64 over the corpus's first two pictures, the claim of every attack it shows survived, and a claim of one attack more; objects/ the four envelopes, the receipts, and for each envelope its first good store, as an origin serves them (a second good store over one envelope is in its vector's own directory). A file another vector already wrote is named by that vector's path. anchors is empty: every anchor comes from a list. time is the instant T.

Equivalence. A conforming verifier given a vector's files and T reaches the outcome expect states (§6): for refuse, the reason of §7 and the code §7 gives it (c2pa, the C2PA 2.4 code for §7.1's reasons and the Identity Assertion's for an identity's, null where §7 gives none); for accept, what §6.3 states, among it the trustLists that held the claim signer's anchor, the softBindings, the isccBinding (its alg, its sequence in its canonical form as iscc, and its generator), the iscc identifier in its canonical form and the identities with the identity list that held each anchor.

The vectors.

  • Good: bound-full (a soft binding, the ISCC identifier and the creator's identity over the hard binding, the actions, the WAI assertion and the soft binding), bound-two-identities (the publisher's identity referencing the creator's), bound-identity-only (the unmarked picture's store with one identity), bound-identity-deterministic (the same store with the identity signed over the payload's core deterministic encoding, the form a writer may ask for; every other identity of the corpus is signed over the payload's members in the schema's order, §4.10's default, and each accepted identity's signed says which), bound-iscc-binding (the first picture's store with its watermark's soft binding, the ISCC soft binding, the identifier and the creator's identity over the three assertions and both soft bindings), bound-iscc-binding-only (the unmarked picture's store with the ISCC soft binding alone: an Image-Code, a Data-Code and an Instance-Code) and bound-featureless-picture (a picture of one grey: the ISCC soft binding holds a Data-Code and an Instance-Code and no Image-Code, and the identifier holds the featureless Image-Code).
  • An identity's signature is refused (identity_signature_mismatch) when it is the creator's under the publisher's certificates (identity-credential-swapped), over the payload's members in a third order, which is neither serialization of §4.10 (identity-signed-third-order), or over a payload with another role than the one the assertion holds (identity-signed-other-members).
  • One negative for each reason of §7.2, and three of §7.1's credential_untrusted: a signer under an anchor no list holds, an anchor its list withdrew, and an anchor whose trust starts after T; each name says its defect.
  • The ISCC soft binding's negatives, iscc-binding-*: computed from another envelope; its Data-Code the envelope's and its Instance-Code that of the envelope with one bit changed, which iscc §5 would match and §6.2 step 11 refuses; a unit missing; units of 64 bits; a featureless Image-Code included (iscc_mismatch, each); its sequence cut by a byte; its value the sequence's text; no generator; a second ISCC binding; the ISCC binding before the watermark's (manifest_malformed, each); and the watermark's robustness claim named as its own (soft_binding_unevidenced).

Provenance. wai_c2pa_identity_vectors gen writes every file but this one from fixed seeds: every key is SHA-256 of a label and no key is one anyone holds; the certificates are issued under the corpus's own four test anchors; the lists are the corpus's own; the pictures are rings and ramps the generator draws, two of them marked with wai-mark:tent64, and one picture of a single grey, each written as PNG by the packaging corpus's still writer, so each store states the source type algorithmicMedia. The robustness record's table is the harness's (robustness-evidence §6), run over the two unmarked pictures, and is reproduced by anyone who holds them.

Checked by. wai_c2pa_identity_vectors verify and tests/c2pa_identity.rs in wai-rs (every file regenerates byte for byte and no other is here; every vector gets its outcome; every reason of §7.2 refuses one), and ../c2pa_live_verify.py, the second implementation, written from the extension's text, which reads the lists and the identity assertions itself, detects the mark with _wai_mark.py, verifies the robustness evidence with robustness_verify.py and recomputes the ISCC units with iscc_verify.py, requires every mutated copy of a good vector to be refused, and requires every one of its own checks, dropped, to be caught.

Read by a C2PA SDK's validator. Every good store here that carries an identity assertion is given to a C2PA SDK's validator beside its envelope, with the certificates of the vector's trust lists as its anchors for claim signers and for identity credentials, by the test the_sdks_validator_accepts_the_stores_the_store_writer_writes of c2pa_emit::identity_corpus (wai-rs, features c2pa_emit,c2pa_envelope; it runs in the conformance workflow's c2pa-emitter job). Of each store whose identities are signed over the schema's order the validator's state is trusted, it reports the claim signature validated, the data hash matched and no failure code, and for each identity assertion cawg.x509.credential.trusted, cawg.x509.signature.validated and cawg.identity.well-formed. Of bound-identity-deterministic it reports cawg.x509.signature.mismatch and nothing else: that validator does not verify the core deterministic encoding (c2pa-binding §4.10). It reads the claim, the hard binding, the hashed URIs and the identity assertions; the soft bindings, the ISCC assertions and WAI's own assertion it carries as assertions whose hashes it checks and whose content it does not judge.