Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6e753dc
Add legacy manifests page
crandmck May 29, 2025
9150115
reorg and add notes
crandmck Jun 2, 2025
1b86f20
Reorg and add comments
crandmck Jun 2, 2025
937704f
Restructuring content into sections for reading and writing manifest …
crandmck Jun 12, 2025
4feff2c
edits
crandmck Jun 18, 2025
0273169
wip reorg
crandmck Jun 19, 2025
d170f89
wip save
crandmck Jul 14, 2025
c3dd874
Reorg files and add some new files to cover all reading/writing cases…
crandmck Jul 17, 2025
a6db053
Merge branch 'main' into old-new-manifests
crandmck Jul 17, 2025
c383f79
typo
crandmck Jul 23, 2025
33b35d3
cawg updates
crandmck Jul 24, 2025
3af1829
more cleanup
crandmck Jul 24, 2025
b898d64
Change org.cai.ingredientIds to IngredientIds
crandmck Aug 28, 2025
a8c24fa
Fix merge conflicts
crandmck Aug 28, 2025
a928e2e
Merge branch 'main' into old-new-manifests
crandmck Sep 3, 2025
20d3a57
Merge branch 'main' of https://github.com/contentauth/opensource.cont…
crandmck Sep 3, 2025
0170bdc
Clean up for review
crandmck Sep 5, 2025
34e6196
add review comment
crandmck Sep 5, 2025
5072faa
update validation
crandmck Sep 5, 2025
f9e7a17
Updates to validation
crandmck Sep 5, 2025
8980dee
labels for legacy ingredients
crandmck Sep 5, 2025
3b7267b
Move section on v2 actions
crandmck Sep 5, 2025
cbc3029
Removed missed instance of CreativeWork
crandmck Sep 5, 2025
8e59a3f
Gavin review comments
crandmck Sep 11, 2025
8e50d88
missed commits
crandmck Sep 11, 2025
283c7b9
fix merge conflict
crandmck Sep 12, 2025
b038dc3
Removed bad examples per GP
crandmck Sep 15, 2025
8f45550
Remove page on writing CAWG id assertions for now
crandmck Sep 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions docs/manifest/json-ref/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,4 @@ pagination_next: null
pagination_prev: null
---

The [C2PA specification](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_manifests) describes a manifest with a binary structure in JPEG universal metadata box format ([JUMBF](https://www.iso.org/standard/84635.html)) that includes JSON as well as binary data for things like encryption keys and thumbnail images. Because the binary structure is hard to understand and program to, the SDK defines a JSON manifest structure that's a declarative language for representing and creating a binary manifest.

The JSON manifest is an abstract translation layer that's easier to understand than the binary format. It can describe everything in the underlying binary format except for binary data such as thumbnails that are included by a structure called a _resource reference_. To generate a binary manifest, the SDK assembles all the JSON objects, resource references, and ingredients defined, and then converts them into different assertions and other objects as required.

These JSON references are generated from the JSON schemas for [ManifestDefinition](https://docs.rs/c2pa/latest/c2pa/struct.ManifestDefinition.html) and [Reader](https://docs.rs/c2pa/latest/c2pa/struct.Reader.html) objects (_structs_ in Rust terminology):

- [ManifestDefinition](manifest-def.mdx): Defines a manifest and builds a manifest store.
- [Reader](reader.mdx): Reads and validates a manifest.
No longer used.
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
---
id: ingredients
title: Ingredients
id: reading-ingredients
title: Reading ingredients
---

## Overview

Digital assets are often not created entirely from scratch, but instead created from one or more existing assets, for example placing an image into a layer in Photoshop. Such constituent assets are called _ingredients_.

This documentation covers C2PA v1 ingredients. The [C2PA Technical Specification](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_ingredient) also describes improved v2 ingredients.
Existing manifests may contain any of these three kinds of ingredients:
- V1, with labels starting with `c2pa.ingredient` (deprecated). See [Reading legacy manifest data](legacy.md#legacy-ingredients).
- V2, with labels starting with `c2pa.ingredient.v2` (deprecated). See [Reading legacy manifest data](legacy.md#legacy-ingredients).
- V3, with labels starting with `c2pa.ingredient.v3`, which addresses the issue of validating ingredients after redaction.

:::note
The C2PA Technical Specification describes _ingredient assertions_ but the CAI SDK treats ingredients separately as their own objects in the JSON manifest rather than as a type of assertion.
:::

## Ingredient objects

Each ingredient used to create an asset is listed in the [JSON manifest](manifest/json-ref/manifest-def.mdx) `ingredients` array. When an ingredient itself has Content Credentials, those manifests are included in the composed asset's manifest store to keep the provenance data intact.
The `ingredients` array contains an element for each ingredient used to create an asset. When an ingredient itself has Content Credentials, those manifests are included in the composed asset's manifest store to keep the provenance data intact.

The `ingredients` array contains an [ingredient object](manifest/json-ref/manifest-def.mdx#ingredient) for each ingredient. The only required property of the `ingredient` object is the `title` property, which usually is the source file name.

The `label` property for the first ingredient in a manifest is `c2pa.ingredient.v3` When there is more than one ingredient, subsequent labels have a monotonically increasing index: `c2pa.ingredient.v3__1`, `c2pa.ingredient.v3__2`, and so on.

Other important properties of the ingredient object include:
- `format`: MIME type of the source file.
- `document_id` and `instance_id` which are derived from the ingredient asset's XMP metadata.
- `format`: MIME type of the source file (optional).
- `document_id` (optional) and `instance_id` (required) which are derived from the ingredient asset's XMP metadata.
- `thumbnail`: Object with properties that identify the thumbnail image.
- `active_manifest`: For an ingredient with a manifest store, the label of the active manifest.
- `relationship`: One of `parentOf`, `componentOf`, or `inputTo`. See [Relationship](#relationship) below.
Expand Down Expand Up @@ -55,7 +58,9 @@ The ingredient object's `relationship` property describes its relationship to th
| `componentOf` | This ingredient is one of the assets that composes the current asset. |
| `inputTo` | This ingredient was used as input to a computational process, such as an AI/ML model, that led to the creation or modification of this asset. |

## Validation status
## Validation results

The [ValidationResults](/docs/manifest/json-ref/reader#validationresults) object contains the the validation results for the active manifest and any changes to ingredients.

When ingredients are added, the SDK validates their Content Credentials (if any). However, the validation status of an ingredient does not imply anything about the validation status of the composed asset containing the ingredient. In other words:
- A composed asset's Content Credentials may be valid, but one or more of its ingredients may have invalid Content Credentials. For example, test file [adobe-20220124-XCA.jpg](https://contentcredentials.org/verify?source=https://spec.c2pa.org/public-testfiles/image/jpeg/adobe-20220124-XCA.jpg)
Expand Down
156 changes: 156 additions & 0 deletions docs/manifest/reading/legacy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
---
id: legacy-manifests
title: Reading legacy manifest data
---

As much as possible, an application should **write** manifest data that conforms to the recent [version 2.2](https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html) C2PA technical specification, but should be able to **read and validate** manifest data that conforms to earlier versions of the specification. This ensures that your application is "backward-compatible" and can still validate older assets with claims that were written in the past.

## Legacy ingredients

Old manifests may contain these kinds of deprecated ingredient data:
- V1 ingredients, with labels that begin with `c2pa.ingredient`.
- V2 ingredients, with labels that begin with `c2pa.ingredient.v2`.

<a name="question1"></a>

<div class="review-comment">
Should we say anything more about reading v1 and v2 ingredients?
</div>

## Legacy actions

Existing manifests may contain two versions of actions: original v1 actions, with label `c2pa.actions`, and revised v2 actions, with label `c2pa.actions.v2`. While a v1 action is fully specified in its actions array, a v2 action may either be fully specified in an element of the actions array or it may be derived from an element in the templates array with the same action name.

<a name="question2"></a>

<div class="review-comment">
What should we say about reading v1 actions?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As with Ingredients, we have a single Actions struct that handles both types of actions. So the label will be different, and you may want to to check for both labels or use starts_with. The rules for parsing actions templates needs to be added somewhere along with how to handle localizations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to provide an action resolver for this.

</div>

## Legacy metadata assertions

Existing manifests may contain individual assertions for each metadata standard:
- [Exif assertion](#exif-assertion)
- [IPTC metadata assertion](#iptc-metadata-assertion)
- [Creative Work assertion](#creative-work-assertion)

In the latest version of the SDK, Exif and IPTC assertions are now CAWG assertions, and the CreativeWork assertion is not supported at all.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CreativeWork should not be used but there are some new alternatives via CAWG such as the AssetRef assertion and Cawg Identity claims aggregator for social media.


### Exif assertion

Exchangeable image file (Exif) format is a standard for storing technical metadata in image files of JPEG, TIFF, PNG, and other formats. Most digital cameras (including smartphones), scanners and other digital capture devices use Exif to store information such as device make and model, shutter speed, ISO number, date and time of capture, location, and so on. For more information on Exif, see the [Exif specification](https://www.cipa.jp/std/documents/download_e.html?DC-008-Translation-2019-E).

Use an Exif assertion to add Exif information to the asset in a way that can be validated cryptographically. An Exif assertion has the label `stds.exif`.

Here is a simple example:

```json
"assertions": [
...
{
"label": "stds.exif",
"data": {
"@context" : {
"exif": "http://ns.adobe.com/exif/1.0/"
},
"exif:GPSVersionID": "2.2.0.0",
"exif:GPSLatitude": "39,21.102N",
"exif:GPSLongitude": "74,26.5737W",
"exif:GPSAltitudeRef": 0,
"exif:GPSAltitude": "100963/29890",
"exif:GPSTimeStamp": "2019-09-22T18:22:57Z"
}
}
...
]
```

### IPTC metadata assertion

An International Press Telecommunications Council (IPTC) metadata assertion represents properties from the [IPTC Photo Metadata Standard](https://www.iptc.org/std/photometadata/specification/IPTC-PhotoMetadata) and [Video Metadata Standard](https://www.iptc.org/standards/video-metadata-hub/recommendation/) that describe ownership, rights, and descriptive metadata about an asset.

An IPTC assertion has the label `stds.iptc` and is stored in JSON-LD format using the XMP field names and structures specified in the IPTC standards.

Earlier versions of the C2PA specification defined the `stds.iptc.photo-metadata` label for IPTC photo metadata; starting with version 1.3, the C2PA specification defines the `stds.iptc` assertion that includes video metadata as well.

See also [IPTC Photo Metadata User Guide](https://www.iptc.org/std/photometadata/documentation/userguide/).

For example:

```json
...
"assertions": [
...
{
"label": "stds.iptc",
"data": {
"@context" : {
"Iptc4xmpCore": "http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/",
"Iptc4xmpExt": "http://iptc.org/std/Iptc4xmpExt/2008-02-29/",
"dc" : "http://purl.org/dc/elements/1.1/",
"photoshop" : "http://ns.adobe.com/photoshop/1.0/",
"plus" : "http://ns.useplus.org/ldf/xmp/1.0/",
"xmp" : "http://ns.adobe.com/xap/1.0/",
"xmpDM" : "http://ns.adobe.com/xmp/1.0/DynamicMedia/",
"xmpRights" : "http://ns.adobe.com/xap/1.0/rights/"
},
"photoshop:DateCreated": "Aug 31, 2022",
"dc:creator": [ "Julie Smith" ],
"Iptc4xmpExt:DigitalSourceType": "https://cv.iptc.org/newscodes/digitalsourcetype/digitalCapture",
"dc:rights": "Copyright (C) 2022 Example Photo Agency. All Rights Reserved.",
"photoshop:Credit": "Julie Smith/Example Photo Agency via Example Distributor",
"plus:licensor": [
{
"plus:LicensorName": "Example Photo Agency",
"plus:LicensorURL": "http://examplephotoagency.com/images/"
}
],
"xmpRights:WebStatement": "http://examplephotoagency.com/terms.html",
"xmpRights:UsageTerms": [
"Not for online publication. Germany OUT"
],
"Iptc4xmpExt:LocationCreated": {
"Iptc4xmpExt:City": "San Francisco"
},
"Iptc4xmpExt:PersonInImage": [
"Erika Fictional"
],
"Iptc4xmpCore:AltTextAccessibility": "Photo of Erika Fictional standing in front of the Golden Gate Bridge at sunset."
}
},
...
]
```

### Creative work assertion

The deprecated creative work metadata assertion has the label `stds.schema-org.CreativeWork`.

For example:

```json
...
"assertions": [
...
{
"label": "stds.schema-org.CreativeWork",
"data": {
"@context": "https://schema.org",
"@type": "CreativeWork",
"url": "https://stock.adobe.com/615559889"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This url can now be supplied via the AssetRef assertion.

},
"kind": "Json"
},
...
]
```

## Legacy training and data mining assertion

Old manifests may have training and data mining assertions with the following entry keys:
- `c2pa.data_mining`
- `c2pa.ai_training`
- `c2pa.ai_generative_training`
- `c2pa.ai_inference`

These assertions have been replaced by [CAWG training and data mining assertions](../writing/assertions-actions.md#cawg-training-and-data-mining-assertion) with `cawg.*` entry keys.
Original file line number Diff line number Diff line change
@@ -1,40 +1,29 @@
---
id: cawg-id
title: CAWG identity assertions
id: reading-cawg-id
title: Reading CAWG identity assertions
---

The [Creator Assertions Working Group (CAWG)](https://cawg.io/) identity assertion enables a credential holder to prove control over a digital identity and to use that identity to document a content creator’s role(s) in a C2PA asset’s lifecycle.

There are two different ways to provide identity assertions:
The SDK can read and validate CAWG identity assertions provided:

- Using an [X.509 certificate](https://cawg.io/identity/1.1/#_x_509_certificates_and_cose_signatures) to sign the identity claims. Enterprises or large organizations can use this approach to assert their identity in a particular trust ecosystem; for example, a news organization or publisher. The SDK can validate and sign these claims.
- Using an [identity claim aggregator](https://cawg.io/identity/1.1/#_identity_claims_aggregation). Individuals can use this approach to document their role in creating an asset by using identity signals collected and verified by a third-party aggregator. The SDK can validate these claims only. Signing is not supported.

:::note
The SDK can validate claims for both kinds of identity assertions, but can only sign claims for identity assertions using an X.509 certificate.
:::

## Using an X.509 certificate

When providing an identity assertion by using an X.509 certificate, the value of `signer_payload.sig_type` must be `cawg.x509.cose`. The signature value must be a COSE signature as described in the [CAWG Identity Assertion technical specification](https://cawg.io/identity/1.1/#_x_509_certificates_and_cose_signatures).
## Assertions signed using a certificate

## Using an identity claim aggregator
In an identity assertion provided by using an X.509 certificate, the value of `signer_payload.sig_type` is `cawg.x509.cose`. The signature value must be a COSE signature as described in the [CAWG Identity Assertion technical specification](https://cawg.io/identity/1.1/#_x_509_certificates_and_cose_signatures).

As defined in the [CAWG Identity Assertion technical specification](https://cawg.io/identity/1.1/#_identity_claims_aggregation), content creators may wish to document their role in creating an asset using identity signals such as:
- Verified web sites
- Social media accounts
- Official ID documentation
- Professional accreditations
- Organizational affiliations
## Assertions signed using a claim aggregator

To facilitate the use of such identity signals, the content creator may use the services of a trusted third-party intermediary known as a _identity claims aggregator_ to gather these signals and to restate them on their behalf.

The identity claims aggregator:
An identity assertion can also be signed using a trusted third-party intermediary known as an [_identity claims aggregator_](https://cawg.io/identity/1.1/#_identity_claims_aggregation). The identity claims aggregator:

- Collects and verifies identity attestation claims from various identity providers such as social media sites and ID verification vendors.
- Creates a unique asset-specific credential that binds the identity attestation claims to a specific asset.

## Identity assertion
In an identity assertion provided by using an identity clarims aggregator, the value of `signer_payload.sig_type` is `cawg.identity_claims_aggregation`.

### Example

An identity assertion using an identity claims aggregator has this general form in JSON:

Expand Down Expand Up @@ -72,14 +61,14 @@ An identity assertion using an identity claims aggregator has this general form
]
```

### Verified identity types
## Verified identity types

The following table describes the allowed values of the `type` property of `verifiedIdentities` array elements.

| Value | Meaning |
|--------------|----------|
| `cawg.document_verification` | The identity provider verified one or more government-issued identity documents presented by the content creator.
| `cawg.web_site` | The content creator has proven control over a specific domain to the identity claims aggregator._
| `cawg.web_site` | The content creator has proven control over a specific domain to the identity claims aggregator.
| `cawg.affiliation` | The identity provider is attesting to the content creator’s membership in an organization. This could be a professional organization or an employment relationship.
| `cawg.social_media` | The content creator has demonstrated control over an account (typically a social media account) hosted by the identity provider.
| `cawg.crypto_wallet` | The content creator has demonstrated control over an account (typically a crypto-wallet) hosted by the identity provider.
Expand Down
12 changes: 12 additions & 0 deletions docs/manifest/reading/reading.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
id: reading-index
title: Reading and validating manifest data
---

Use a [Reader](manifest/json-ref/reader.mdx) structure to read and validate manifest data. The Rust library and other language libraries provide methods and objects for working with this structure.

- [Reading ingredients](ingredients-reading.md)
- [Reading CAWG identity assertions](reading-cawg-id.md)
- [Reading legacy manifest data](legacy.md)
- [Validating manifests](validation.md)
- [Reader JSON reference](manifest/json-ref/reader.mdx) generated from the JSON schema for [Reader](https://docs.rs/c2pa/latest/c2pa/struct.Reader.html) object (_struct_ in Rust terminology).
Loading