# C2PA

> How OWG records C2PA content credentials on assets, maps manifests and ingredients onto lineage, and earns the attested assurance level only after verification.

**Status:** buildable on v0.92 with no schema change. The keys inside `asset.credentials` below are a convention set by this page.

## What C2PA is

The [Coalition for Content Provenance and Authenticity](https://c2pa.org/) publishes the Content Credentials specification, currently [version 2.4](https://spec.c2pa.org/specifications/specifications/2.4/specs/C2PA_Specification.html). A content credential is a **manifest** attached to or referenced by an asset:

- **Assertions** are statements about the asset: what was done to it (actions such as `c2pa.created`, `c2pa.opened` and `c2pa.edited`), which earlier assets went into it (**ingredients**), and whether it was produced by a generative model.
- A **claim** gathers the assertions and binds them to the content, by a cryptographic hash (a **hard binding**) or by a watermark or fingerprint (a **soft binding**).
- The **claim generator** is the software that wrote the claim; the **signer** holds the key that signed it.
- A **validator** checks the signature, the bindings and the signer's certificate, and reports whether the credential is valid and trusted.

C2PA also publishes guidance on [AI and machine-learning content](https://spec.c2pa.org/specifications/specifications/2.3/ai-ml/ai_ml.html).

## Where C2PA and OWG meet

They record provenance at different moments, and a production needs both:

| Layer | When | Answers |
|---|---|---|
| C2PA | At capture or generation, and at each signed edit | Is this file what its signer says it is? |
| OWG | Throughout production, as a side effect of running the work | Who made it, from what, under whose authority, after which approvals, at what cost? |
| Publication labelling (for example the EU AI Act icon set) | At publication | What does the audience need to be told? |

A C2PA manifest travels with one file. An OWG graph holds the whole production around it: the brief, the review that approved the image, the person who localized it, the check that verified the credential, the delivery. Each makes the other more useful: the manifest gives OWG's graph its strongest evidence, and the graph explains the manifest.

## The hook

C2PA lands on the **asset**, never on the task, in three existing fields:

```json
{
  "id": "key_art_fr",
  "predecessor": "key_art_base", "version_relation": "alternative",
  "identity": "sha256:…",
  "identifiers": [{ "scope": "c2pa", "id": "urn:c2pa:…" }],
  "credentials": {
    "scheme": "c2pa",
    "manifest": "urn:c2pa:…",
    "signer": "org_studio",
    "actions": ["c2pa.opened", "c2pa.edited"],
    "ingredients": [{ "asset": "key_art_base", "relationship": "parentOf" }],
    "status": "trusted"
  },
  "assurance": "attested"
}
```

| Key in `credentials` | Holds |
|---|---|
| `scheme` | `c2pa` |
| `manifest` | The active manifest's identifier. Also listed in `identifiers[]` under scope `c2pa`, so other systems can match on it |
| `signer` | The organization or participant id whose key signed the claim |
| `actions` | The C2PA action names in the manifest, as recorded |
| `ingredients` | `{ asset, relationship }` per ingredient, with C2PA's relationship (`parentOf`, `componentOf`, `inputTo`) and the OWG asset id it resolves to |
| `ai_generated` | `true` when the manifest declares generative-AI origin |
| `status` | The last verification result: `unverified`, `valid`, `trusted` or `invalid` |

## How it maps

| C2PA | OWG |
|---|---|
| Manifest | `credentials.manifest`, and an `identifiers[]` entry with scope `c2pa` |
| Hard binding (content hash) | `asset.identity` |
| `parentOf` ingredient | `predecessor` with a `version_relation` |
| `componentOf` ingredient | an `asset.composes[]` entry |
| `inputTo` ingredient | the producing task's `used[]` |
| Actions | The task that `produced` the asset; `credentials.actions` mirrors what the manifest says |
| Generative-AI origin | The producing task's [`ai_role: "generative"`](/compliance#declaring-ai-involvement), and `credentials.ai_generated` |
| Claim generator | The producing task's executor |
| Signer | `credentials.signer`, an organization or participant |
| Validation result | A `qc` task that `used` the asset, its report as an asset, and `credentials.status` |
| Trusted credential | `asset.assurance: "attested"` |

**`attested` is earned, not declared.** An asset gets `assurance: "attested"` only after a verification task has found its credential valid and its signer trusted. Until then a manifest is a claim, and the asset stays `asserted`. This is the rule that keeps OWG's strongest assurance level honest: see [Relationships → assurance](/relationships).

## Reference workflow

[`c2pa-localized-key-art.owg.json`](/corpus/c2pa-localized-key-art.owg.json): an agent generates base key art through a signing generation service; an art director approves it; a designer adds the French title treatment, producing a new signed asset whose manifest names the base image as its `parentOf` ingredient; a verifier checks the credential before delivery, and a failed check routes back to approval, at most twice.

```bash
curl -O https://openworkflowgraph.org/corpus/c2pa-localized-key-art.owg.json
owg-validate c2pa-localized-key-art.owg.json --json
```

**What to take from it:**

- The base image is `asserted` with status `unverified`; the verified French version is `attested`. Same scheme, different standing, and the document says why.
- The ingredient relationship and the OWG `predecessor` describe the same edge from two sides. A reconciler can check one against the other.
- The generation task declares `ai_role: "generative"` and its agent traces to the art director through `operated_by`: the AI disclosure falls out of the graph.

## What stays in C2PA

OWG does not sign, embed, strip or validate manifests, and it does not copy their assertions. The manifest store remains the system of record for the credential. OWG records that the credential exists, what it says at the level a production needs, and the result of checking it.

Signing needs a certificate from a certificate authority that C2PA recognizes. An implementation obtains one; it does not need to become one.

## Known gaps

- The keys inside `credentials` are a convention on this page. The schema leaves the object open.
- No validator rule yet checks that a task with `ai_role: "generative"` produced an asset whose credential says `ai_generated`, or the reverse. Both are recorded; their agreement is not checked.
- Soft bindings (watermarks, fingerprints) have no field. A soft-binding identifier can go in `identifiers[]` meanwhile.
- No reference signing or verification client ships with OWG.

See also: [Standards bindings](/standards-bindings), [Assets and versioning](/assets-and-versioning), [Compliance](/compliance), [Relationships](/relationships), [A2A](/a2a).
