C2PA— the Coalition for Content Provenance and Authenticity — is the open standard for attaching verifiable provenance to digital media. If you have seen “Content Credentials” on an image from Photoshop, a Pixel camera, or an AI generator, that is C2PA in the wild. This guide is the developer’s view: the data model, how verification works, what the standard does and does not solve, and how to produce and validate manifests in your own stack.
The mental model: manifests, claims, and assertions
A C2PA manifest is a signed package of provenance attached to an asset. Three pieces matter most:
- Assertions are individual statements about the asset — what created it, what actions were taken, a hash of the pixels or bytes, the creator, the AI model used, and so on. Assertions can be standardized or custom.
- The claim binds a set of assertions together and is what actually gets signed. The signature covers the claim, which in turn references the assertions, so nothing inside can change without breaking the signature.
- The claim generator identifies the software that produced the manifest — the C2PA analogue of a user-agent string.
Manifests chain: when an asset is edited by another C2PA-aware tool, a new manifest is added that references the previous one, forming a tamper-evident history rather than overwriting it.
Hard bindings vs soft bindings
C2PA connects a manifest to content two ways. A hard binding is a cryptographic hash of the asset bytes — exact and tamper-evident, but only valid as long as those exact bytes survive. A soft binding is an invisible watermark or a content fingerprint that lets a verifier re-discover the manifest even after the file has been re-encoded or the embedded metadata removed. Soft bindings trade exactness for resilience; they are probabilistic recovery, not a cryptographic guarantee.
How verification works
To verify a C2PA asset, a consumer parses the manifest, checks that the claim’s signature is valid, and confirms the hard-binding hash still matches the content. The signature is only meaningful if the signing certificate chains to a trusted source — which is why C2PA defines conformance and trust lists. A valid signature from an unknown signer tells you the content has not changed since signing, but not that the signer is who you should trust. Resolving the signer to a known identity is a separate, deliberate step — never read trust from the asset’s own self-claimed fields.
What C2PA does not solve on its own
The most common production surprise: embedded manifests get stripped. Most C2PA data lives in a JUMBF block inside the file, and the moment a non-C2PA-aware platform re-encodes the upload — which is the norm on social and messaging apps — that block is silently dropped. The asset arrives with no signal a credential ever existed. Soft bindings exist precisely to mitigate this, but they add a watermarking dependency and are not perfect. We unpack the failure mode, and a sturdier delivery pattern, in why content credentials get stripped.
Producing and validating manifests
For experimentation, the reference tool is c2patool: it can read, add, and validate manifests against the spec, which makes it the natural gate in a test harness. In application code you will typically generate a manifest at publish time, embed a hard binding, sign the claim with your service key, and — where the file pipeline is lossy — register a soft binding so the manifest can be recovered later.
A useful design principle is to keep your source of truth as a signed record you control, and treat the C2PA manifest as an export format for interoperability. That way you are not betting authenticity on whether a JUMBF block survives a third-party re-encode. This is how Hessian approaches it: every published asset gets an Ed25519-signed provenance record (see cryptographic content signing with Ed25519), and an on-demand export embeds that signed record as a com.hessian.provenance.v1.2 custom assertion in a C2PA JSON-LD manifest definition — the structured payload you hand to a c2patool signing pipeline. The inner Hessian record is already signed; the outer C2PA manifest signing and validation step is a roadmap item, so describe it as a manifest you can feed into C2PA, not a finished Content Credential.
One subtlety worth getting right: only mark content as AI-generated when it actually is. Hessian’s editorial-origin (human-authored) records deliberately omit the AI-trained source-type marker, so human work is not mislabeled — which is also the correct behavior for EU AI Act labeling.
Where to start
If you are new to the broader topic, begin with what content provenance is, then come back here for the standard. If you are evaluating where provenance should live in your architecture, see headless CMS plus content provenance or the Hessian product overview.