Lab: C2PA / Content Credentials#
Current status: Partial · Detect: Partial · Remove: Partial · Last tested: 2026-08-13
← Back to the Lab · ← Back to the MarkMyAss cleaner
What this signal is#
C2PA (Coalition for Content Provenance and
Authenticity) defines a standard for embedding a cryptographically
signed manifest in a file -- a record of how content was created or
edited, optionally including "generated by AI" assertions. The manifest
is packaged in a JUMBF container (ISO/IEC 19566-5): a JPEG APP11
marker segment, or a PNG caBX chunk.
MarkMyAss's C2PA support is explicitly labeled Partial, and stays that way regardless of individual test outcomes. This is a capability-level statement, not something a single clean/verify run can upgrade.
What MarkMyAss can test#
MarkMyAss's own detector scans for the JUMBF container structure itself
(the APP11 segment / caBX chunk), NOT the manifest's contents. Presence
of the container is a strong signal that a C2PA manifest exists; absence
is a strong signal that it doesn't -- but this is a structural,
byte-level scan, not a spec-conformant C2PA parse. Implementation:
src/ghostmark/detectors/c2pa.py.
What MarkMyAss can remove#
The JUMBF container segment/chunk is deleted from the file (JPEG, PNG).
This reliably removes a C2PA manifest embedded via the standard
container MarkMyAss scans for -- it is not an audited guarantee against
every possible embedding technique a future or unusual C2PA
implementation might use. Implementation:
src/ghostmark/cleaners/c2pa.py.
PDF: detection uses a raw byte-signature scan (looking for c2pa/jumb
markers); cleaning is not implemented for PDF.
What MarkMyAss cannot test#
- Cryptographic signature or trust-chain validation. Neither
MarkMyAss's own detector nor its use of
c2patoolperforms signature verification against a trust list. "No manifest found" is not the same claim as "this content's provenance chain, if any, is valid" -- those are different questions entirely. - Manifests embedded via non-standard containers MarkMyAss doesn't scan for.
- Whether removing the container also removed every trace referenced elsewhere in the file (e.g. a cross-reference in a custom XMP field) -- MarkMyAss's cleaner targets the JUMBF container specifically.
Verification methodology#
Independent verification uses
c2patool, the
official Content Authenticity Initiative CLI, in its default read-only
mode (c2patool FILE, no -m flag -- it never signs or modifies
anything). MarkMyAss uses c2patool only to confirm presence/absence of a
manifest, matching the scope of its own heuristic detector -- this is
explicitly not a claim that c2patool cryptographically validated
anything. Implementation:
src/ghostmark/independent_verify.py
(C2paToolVerifier).
c2patool is optional and licensed Apache-2.0/MIT; MarkMyAss never vendors
it, only shells out to a separately-installed binary (see
THIRD_PARTY_LICENSES.md). If it isn't installed, MarkMyAss says so
rather than guessing.
Reproducible test commands#
ghostmark inspect photo.jpg --json # look for the "c2pa" detector entry
ghostmark clean photo.jpg
ghostmark verify photo.ghostmark.jpg --receipt receipt.json
# Independently, with c2patool directly (read-only):
c2patool photo.jpg
c2patool photo.ghostmark.jpg
Covered by
tests/test_images.py
(synthetic JUMBF-marker fixtures) and
tests/test_independent_verify.py
(mocked c2patool behavior, including the "no manifest" and genuine-error
paths).
Related pages#
- C2PA Remover -- the practical, action-oriented version of this page.
- Content Credentials Remover -- same mechanism, written for people who know the "cr" icon rather than the C2PA spec name.
Sources#
- C2PA Technical Specification
- ISO/IEC 19566-5 -- JPEG systems, JUMBF
- c2patool / c2pa-rs, Content Authenticity Initiative
Something outdated or inaccurate?#
Open an issue or submit a
pull request against
src/ghostmark/web/content/lab/c2pa.md.
Last reviewed: 2026-08-13