diff --git a/docs/manifest/json-ref/index.md b/docs/manifest/json-ref/index.md
index 17f3fe9..d94e92d 100644
--- a/docs/manifest/json-ref/index.md
+++ b/docs/manifest/json-ref/index.md
@@ -6,11 +6,6 @@ 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 newline at end of file
+Please see:
+- [ManifestDefinition JSON reference](manifest-def.mdx)
+- [Reader JSON reference](reader.mdx)
\ No newline at end of file
diff --git a/docs/manifest/json-ref/manifest-def.mdx b/docs/manifest/json-ref/manifest-def.mdx
index 77c5dda..95a88b9 100644
--- a/docs/manifest/json-ref/manifest-def.mdx
+++ b/docs/manifest/json-ref/manifest-def.mdx
@@ -7,9 +7,11 @@ hide_table_of_contents: true
import ManifestReference from './manifest-ref.js';
:::danger Warning
-This is a beta release of this reference. It is a work in progress and may not be accurate or complete.
+This is a beta release of this reference. It is a work in progress and may not be accurate or complete. It was generated from the unmodified JSON schema generated from c2pa-rs on 05/09/2025.
:::
-This page is generated from the unmodified JSON schema generated from c2pa-rs on 05/09/2025.
+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.
diff --git a/docs/manifest/json-ref/reader.mdx b/docs/manifest/json-ref/reader.mdx
index b4a1141..c1085af 100644
--- a/docs/manifest/json-ref/reader.mdx
+++ b/docs/manifest/json-ref/reader.mdx
@@ -7,9 +7,11 @@ hide_table_of_contents: true
import ManifestReference from './manifest-ref.js';
:::danger Warning
-This is a beta release of this reference. It is a work in progress and may not be accurate or complete.
+This is a beta release of this reference. It is a work in progress and may not be accurate or complete. It was generated from the unmodified JSON schema generated from c2pa-rs on 05/09/2025.
:::
-This page is generated from the unmodified JSON schema generated from c2pa-rs on 05/09/2025.
+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.
diff --git a/docs/manifest/ingredients.md b/docs/manifest/reading/ingredients-reading.md
similarity index 66%
rename from docs/manifest/ingredients.md
rename to docs/manifest/reading/ingredients-reading.md
index c030c41..b15f903 100644
--- a/docs/manifest/ingredients.md
+++ b/docs/manifest/reading/ingredients-reading.md
@@ -1,13 +1,16 @@
---
-id: ingredients
-title: Ingredients
+id: reading-ingredients
+title: Reading ingredients
---
-## Overview
+## 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_.
+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.
@@ -15,17 +18,31 @@ The C2PA Technical Specification describes _ingredient assertions_ but the CAI S
## 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 `ingredients` array contains an [ingredient object](manifest/json-ref/reader.mdx#ingredient) for each ingredient. The `ingredient` object's `title` property (usually is the source file name) is required for v1 and v2 ingredients, but optional for v3 ingredients.
+
+### The label property
+
+The `label` property is used in two ways:
+
+- When creating an ingredient, you can assign any value you like to `label` and we will match that with the the action `ingredientIds` to find an associated action. The value you specify here does not end up in the manifest. it is optional and only used for doing action/ingredient pairing.
+- When reading a manifest, the `label` will always exist and correspond to actual label assigned to the ingredient. It will be in the format you described below. Note that older v1 claims may have older forms of ingredient labels.
+
+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 properties
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.
+An ingredient assertion must always have a `relationship` and an `instance_id`, but the API will default `relationship` to `componentOf` if not specified and will generate an `instance_id` if you don't give it one. It will also always return a label.
+
For example:
```json
@@ -52,10 +69,12 @@ The ingredient object's `relationship` property describes its relationship to th
| Value of `relationship` | Description |
|--------------------------|-------------|
| `parentOf` | The current asset is a derived asset or asset rendition of this ingredient. This relationship value is also used with update manifests. There can be at most one parent ingredient in a manifest. |
-| `componentOf` | This ingredient is one of the assets that composes the current asset. |
+| `componentOf` | This ingredient is one of the assets that composes the current asset. This is the default value. |
| `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)
@@ -109,6 +128,3 @@ As noted above, the test file [adobe-20220124-CIE-sig-CA.jpg](https://contentcre
The [C2PA public-testfiles](https://spec.c2pa.org/public-testfiles/image/) repository has several examples of images with multiple ingredients:
- [Image with two ingredients](https://contentcredentials.org/verify?source=https://spec.c2pa.org/public-testfiles/image/jpeg/adobe-20220124-CAICA.jpg); [View JSON manifest store](https://spec.c2pa.org/public-testfiles/image/jpeg/manifests/adobe-20220124-CAICA/manifest_store.json)
- [Image with seven ingredients](https://contentcredentials.org/verify?source=https://spec.c2pa.org/public-testfiles/image/jpeg/adobe-20220124-CAIAIIICAICIICAIICICA.jpg); [View JSON manifest store](https://spec.c2pa.org/public-testfiles/image/jpeg/manifests/adobe-20220124-CAIAIIICAICIICAIICICA/manifest_store.json)
-
-
-
diff --git a/docs/manifest/reading/legacy.md b/docs/manifest/reading/legacy.md
new file mode 100644
index 0000000..e32a349
--- /dev/null
+++ b/docs/manifest/reading/legacy.md
@@ -0,0 +1,159 @@
+---
+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`.
+
+While these labels will show up so you can detect them, the API will return the same ingredient object for all of them, but the field contents may vary depending on the version.
+
+
+## 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.
+
+As with Ingredients, a single `Actions` object handles both versions of actions. The label will be different for each version, and you may want to to check for both labels or use `starts_with`.
+
+
+
+## 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.
+
+### 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"
+ },
+ "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.
\ No newline at end of file
diff --git a/docs/manifest/cawg-id.md b/docs/manifest/reading/reading-cawg-id.md
similarity index 77%
rename from docs/manifest/cawg-id.md
rename to docs/manifest/reading/reading-cawg-id.md
index 8f192d2..9b1b2ba 100644
--- a/docs/manifest/cawg-id.md
+++ b/docs/manifest/reading/reading-cawg-id.md
@@ -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:
@@ -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.
diff --git a/docs/manifest/reading/reading.md b/docs/manifest/reading/reading.md
new file mode 100644
index 0000000..a3bcabb
--- /dev/null
+++ b/docs/manifest/reading/reading.md
@@ -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).
diff --git a/docs/manifest/validation.md b/docs/manifest/reading/validation.md
similarity index 65%
rename from docs/manifest/validation.md
rename to docs/manifest/reading/validation.md
index 579531a..a2f1210 100644
--- a/docs/manifest/validation.md
+++ b/docs/manifest/reading/validation.md
@@ -3,35 +3,48 @@ id: manifest-validation
title: Validating manifests
---
-Processing an asset includes [validating the manifests](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_validation) in the associated manifest store. During validation, errors can occur in the active manifest and in ingredients.
+Processing an asset includes [validating the manifests](https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_validation) in the associated manifest store. During validation, errors can occur in the active manifest and in ingredients.
-## Validation errors in manifests
+In the latest version of the SDK:
+
+- Builder performs validation by default, so you can't create an invalid manifest. Previously, the SDK was permissive in this regard.
+- Validation is much stricter.
+
+::: note
+There is a setting to disable full validation when signing.
+:::
+
+
-When you load an asset, all the manifests in the manifest store are validated and any [failure codes](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_failure_codes) are assigned to the `validation_status` array. Inspect the array to find the validation errors.
+`Reader` has these validation methods:
+- `validation_state()` returns `ValidationState` object (`validation_state` in JSON), which can be `Invalid`, `Valid` or `Trusted`.
+- `validation_results()` returns `ValidationResults` (`validation_results` in JSON), which can be `success`, `informational`, and `failure` codes for the active manifest and ingredients.
-:::tip
-Validation returns ONLY error codes; success is not explicitly indicated. If there are no validation errors, then the manifest won't have the `validation_status` element.
+:::note
+The old `ValidationStatus` and `validation_status` array in previous SDK releases are deprecated in favor of `ValidationResults` / `validation_results` and `ValidationState` / `validation_state`.
:::
+## Validation errors in manifests
+
+When you load an asset, all the manifests in the manifest store are validated and [result codes](https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_failure_codes) are assigned to properties in the `validation_results` object.
+
Manifest validation errors can occur, for example, when:
- The bits of an asset are edited after it was signed.
- A claim or assertion is missing or tampered with.
- The manifest is signed with an invalid credential.
-:::caution
-Don't assume that just because you didn't get an error from the function return value that there are not validation errors. You MUST check the `validation_status` array to see if there are errors or not.
-:::
-
## Validation errors in ingredients
-Ingredients are validated when they are imported into an asset and the result is stored in the ingredient's `validation_status` array.
+Ingredients are validated when they are imported into an asset and the result is stored in the ingredient's `validation_results` object.
Only errors that are not already recorded in the `validation_status` of an ingredient are reported. See [ValidationStatus](./json-ref/manifest-def.mdx#validationstatus) object in Manifest store reference.
## Error status codes
-The following table describes some common validation error status codes. Refer to the [C2PA Technical Specification](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_failure_codes) for the full list.
+The following table describes some common validation error status codes. Refer to the [C2PA Technical Specification](https://spec.c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_failure_codes) for the full list.
| Validation Status Code| Description | Type of URI |
| --------------------- | ------------ | ----------- |
@@ -51,29 +64,4 @@ Validation error status codes can contain JUMBF URIs that reference assertions o
- **Assertion URI**: A URI like `self#jumbf=c2pa.assertions/` where `` is either `stds.schema-org.*` or `c2pa.*`.
- **Signature Box URI**: A URI like `self#jumbf=c2pa.signature`.
-For more information, see the [C2PA Technical Specification](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_uri_references).
-
-
+For more information, see the [C2PA Technical Specification](https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_uri_references).
diff --git a/docs/manifest/understanding.md b/docs/manifest/understanding.md
index 8d74263..8831d33 100644
--- a/docs/manifest/understanding.md
+++ b/docs/manifest/understanding.md
@@ -1,31 +1,37 @@
---
id: understanding-manifest
-title: Understanding manifests
+title: Working with manifests
---
-## Overview
+## Understanding manifests
The concept of a _manifest_ is central to how Content Credentials work.
A collection of manifests (known as a _manifest store_) is attached to an asset. Each manifest contains information about the provenance of the asset. Creating or editing an asset using a C2PA-compliant device or tool (for example Adobe Photoshop) adds a new manifest to the manifest store.
-A manifest store can be linked to an asset in three ways:
+The manifests in the manifest store are not ordered, but the most-recently added manifest is the _active manifest_. The active manifest has content bindings that can be validated with the asset—that is, it's hashed with the asset to ensure its validity.
+
+### Location of manifest store
+
+A manifest store can be either:
+
+- Directly embedded in the asset's metadata.
+- In a _sidecar file_, which is a file with the same file name as the asset but with a `.c2pa` extension.
-1. Directly embedded in the asset's metadata.
-1. In a sidecar file, a file with the same file name as the asset but with a `.c2pa` extension.
-1. In a remote URL, linked from the asset's metadata, as detailed in the [C2PA specification](https://spec.c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_external_manifests). NOTE: A given asset can have a remote manifest store plus a local manifest store linked in one of the first two ways.
+In addition, an asset can have a [external manifest store](https://spec.c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_external_manifests), linked from the asset's metadata, as detailed in the [C2PA specification](https://spec.c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_embedding_a_reference_to_an_external_manifest). This is sometimes referred to as a _remote manifest_.
-To determine if an asset has Content Credentials, the SDK checks for the presence of a manifest store (in the order shown above). So, for example to see if `foo.jpg` has Content Credentials, the SDK first checks if there's a manifest store in the file itself, then looks for a sidecar file (`foo.c2pa` in the same directory), and finally looks in the asset's metadata for a reference to a remote manifest store.
+To determine if an asset has Content Credentials, the SDK checks for the presence of a manifest store in this order:
+1. In the asset metadata
+1. In a sidebar file.
+1. In a remote manifest.
-A remote manifest store can be provided for a given asset as well as an embedded or sidecar manifest store. In other words, an asset can have an embedded _and_ a remote manifest store or a sidecar _and_ a remote manifest store.
+So, for example to see if `foo.jpg` has Content Credentials, the SDK first checks if there's a manifest store in the file itself, then looks for a sidecar file (`foo.c2pa` in the same directory), and finally looks in the asset's metadata for a reference to a remote manifest store.
:::info
Currently, only Adobe has implemented a Content Credentials cloud service to provide access to remote manifest stores, but in theory anyone could do so to provide a publicly-accessible network location for manifests.
:::
-The manifests in the manifest store are not ordered, but the most-recently added manifest is the _active manifest_. The active manifest has content bindings that can be validated with the asset—that is, it's hashed with the asset to ensure its validity.
-
-## Binary versus JSON manifest
+## Binary versus JSON manifest formats
The manifest as described in the C2PA specification is a binary structure in JPEG universal metadata box format ([JUMBF](https://www.iso.org/standard/84635.html)) that can include JSON and binary data for things like encryption keys and thumbnail images.
@@ -48,4 +54,5 @@ The time-stamp is typically defined as part of the signing information. You can
## References
- [JUMBF](https://www.iso.org/standard/84635.html): A framework for JPEG standards to add universal metadata, supplementary images, or other elements in addition to the base image.
-- [C2PA Specifications](https://spec.c2pa.org/specifications/)
\ No newline at end of file
+- [C2PA Technical Specification v2.2](https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html)
+
diff --git a/docs/manifest/assertions-actions.md b/docs/manifest/writing/assertions-actions.md
similarity index 68%
rename from docs/manifest/assertions-actions.md
rename to docs/manifest/writing/assertions-actions.md
index f745a9c..18e9113 100644
--- a/docs/manifest/assertions-actions.md
+++ b/docs/manifest/writing/assertions-actions.md
@@ -1,13 +1,13 @@
---
id: assertions-actions
-title: Assertions and actions
+title: Writing assertions and actions
---
-## Assertions
+## Overview
-Assertions provide information about when, where, and how an asset was created or transformed.
+Assertions provide information about when, where, and how an asset was created or transformed.
-In the JSON manifest, each assertion is specified by a [ManifestAssertion](../manifest/manifest-ref.mdx#manifestassertion) object. All the assertions in the manifest are in the `assertions` array. A ManifestAssertion object has two required properties, `label`, a string, and `data`, which can contain arbitrary information; and two optional properties, `kind` and `instance`.
+The JSON manifest contains an `assertions` array, whose elements are [AssertionDefinition](./json-ref/manifest-def/#assertiondefinition) objects. An AssertionDefinition object has two required properties: `label`, a string, and `data`, which can contain arbitrary information. When [reading an assertion](../json-ref/reader#manifestassertion), there are two optional properties, `kind` and `instance`.
The standard form of an assertion in a JSON manifest is:
@@ -26,204 +26,41 @@ The standard form of an assertion in a JSON manifest is:
]
```
-**Metadata assertions**
+:::important
+Every manifest has to start with either an opened or created action, which has to be the first action in the manifest. Each of these actions need to have an associated ingredient.
+:::
-_Metadata assertions_ include
-- [Creative work](#creative-work-assertion)
-- [Exchangeable image file (Exif) information](#exif-assertion)
-- [IPTC photo and video metadata](#iptc-metadata-assertion)
+### Changes from earlier releases
-Metadata assertions must include one or more `@context` properties in the `data` object, as explained in the [JSON-LD](https://www.w3.org/TR/json-ld/#the-context) specification. Follow the examples shown in each section.
+Changes include:
+- Old training and data mining assertions `c2pa.data_mining`, `c2pa.ai_training`, `c2pa.ai_generative_training`, and `c2pa.ai_inference` have been replaced by [CAWG training and data mining assertions](../writing/assertions-actions.md#cawg-training-and-data-mining-assertion)
+- `SoftwareAgent` is a [ClaimGeneratorInfo](../json-ref/manifest-def.mdx#claimgeneratorinfo) structure instead of a string.
+- Ingredients are now V3 ingredients
-### C2PA standard assertions
+## C2PA standard assertions
-The C2PA Technical Specification defines a [set of standard assertions](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_standard_c2pa_assertion_summary) and their corresponding labels. In addition, you can define [custom assertions](#custom-assertions) for your specific application.
+The C2PA Technical Specification defines a [set of standard assertions](https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_standard_c2pa_assertion_summary) and their corresponding labels. In addition, you can define [custom assertions](#custom-assertions) for your specific application.
The following table summarizes some of the most important standard assertions.
| Assertion | Label | Description |
|-----------|-------|-------------|
-| [Actions](#actions) | `c2pa.actions` | Creation, edits, and other actions on an asset, such as cropping, color or contrast adjustment, and so on. |
-| ["Do not train"](#do-not-train-assertion) | `c2pa.training-mining` | Whether the creator/owner of an asset grants permission to use it for data mining or AI/ML training. |
-| [Creative work](#creative-work-assertion) | `stds.schema-org.CreativeWork` | Indicates the asset is the product of creative effort. |
-| [Exif information](#exif-assertion) | `stds.exif` | Camera information such as maker, lens stored in Exchangeable image file format (Exif). |
| [Content bindings](#content-bindings) | `c2pa.hash.*`, `c2pa.soft-binding`, etc. | Uniquely identify portions of an asset and bind the assertion to it, for example using cryptographic hashes. |
-| [IPTC photo and video metadata](#iptc-metadata) | `stds.iptc` | Properties from the IPTC Photo and Video Metadata Standards, describing for example ownership, rights, and other metadata about a image or video asset. |
+| [Actions](#actions) (v2) | `c2pa.actions.v2` | Creation, edits, and other actions on an asset, such as cropping, color or contrast adjustment, and so on. |
:::note
The CAI SDK handles assertions for thumbnails, content bindings, and ingredients, so normally you don't need to think about them.
:::
-### Do not train assertion
-
-Assertions with the `c2pa.training-mining` label indicate whether permission is granted to use an asset in data mining, machine learning (ML) training, or inference. The latter is sometimes referred to as the "do not infer" assertion.
-
-| Entry Key | Whether permission is granted... | Possible values of `use` property |
-|-----------|-------------|-------------|
-| `c2pa.data_mining` | To extract text or data from the asset for purposes of determining "patterns, trends and correlations," including images containing text, where the text could be extracted via OCR. | `allowed`,
`notAllowed`,
or `constrained` |
-| `c2pa.ai_training` |To use the asset to train non-generative AI/ML models, such as those used for classification, object detection, and so on. | `allowed`,
`notAllowed`,
or `constrained` |
-| `c2pa.ai_generative_training` | To use the asset as training data for a generative AI/ML model that could produce derivative assets. | `allowed`,
`notAllowed`,
or `constrained` |
-| `c2pa.ai_inference` | To use the asset as input to a trained AI/ML model for the purposes of inferring a result. Sometimes referred to as the "do not infer" assertion. | `allowed`,
`notAllowed`,
or `constrained` |
-
-The value of each of these properties is an object with a `use` property that can have one of these values:
-
-- `allowed`: Permission is granted for this type of use.
-- `notAllowed`: Permission is NOT granted for this type of use.
-- `constrained`: Permission is not unconditionally granted for this use. You can provide more details (such as contact information) in the `constraints_info` text property.
-
-For more information, see the [C2PA Technical Specification](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_training_and_data_mining).
-
-For example:
-
-```json
-"assertions": [
- ...
- {
- "label": "c2pa.training-mining",
- "data": {
- "entries": {
- "c2pa.ai_generative_training": { "use": "notAllowed" },
- "c2pa.ai_inference": { "use": "notAllowed" },
- "c2pa.ai_training": { "use": "notAllowed" },
- "c2pa.data_mining": {
- "use": "constrained",
- "constraint_info" : "Contact foo@bar.com for more information."
- }
- }
- }
- }
- ...
-]
-```
-
-### Creative work assertion
-
-A creative work assertion states that an asset was the product of creative effort, such as an original photograph or artwork. [Schema.org](https://schema.org/) provides a set of types and metadata fields, including [CreativeWork](https://schema.org/CreativeWork), which describes a representation of creative effort. This assertion provides information about the asset, including who created it and the date/time of publication.
-
-A creative work 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"
- },
- "kind": "Json"
- },
- ...
-]
-```
-
-### 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.
-
-:::note
-Do not use the IPTC `plus:DataMining` property to specify whether permission is granted to use an asset in data mining or AI/ML training. Instead use the C2PA ["do not train" assertion](#do-not-train-assertion).
-:::
-
-For a summary reference to IPTC metadata properties, see [IPTC properties](iptc-properties).
-
-See also:
-- [Exploring c2patool and IPTC Photo Metadata](https://iptc.atlassian.net/wiki/spaces/PMD/pages/613613569/Exploring+c2patool+and+IPTC+Photo+Metadata) (Aug 2022).
-- [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."
- }
- },
- ...
-]
-```
-
### Content bindings
-Content bindings are standard assertions such as `c2pa.hash.boxes` and `c2pa.hash.data` that uniquely identify portions of an asset. For more information on content bindings, see the [C2PA Technical Specification](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_binding_to_content).
+Content bindings are standard assertions such as `c2pa.hash.boxes` and `c2pa.hash.data` that uniquely identify portions of an asset. For more information on content bindings, see the [C2PA Technical Specification](https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_binding_to_content).
:::note
The CAI SDK writes content bindings assertions, so normally you don't need to write them, just read them.
:::
-For example, the `c2pa.hash.data` assertion shown in the [detailed manifest example](examples.mdx/#detailed-manifest) specifies an exclusion hash:
+For example, the `c2pa.hash.data` assertion shown in the [detailed manifest example](../examples.mdx/#detailed-manifest) specifies an exclusion hash:
```json
"assertions": [
@@ -244,38 +81,31 @@ For example, the `c2pa.hash.data` assertion shown in the [detailed manifest exam
]
```
-### Custom assertions
+
## Actions
-An action is an assertion that provides information about creation, edits, and other things that have occurred to an asset. In the manifest, an `actions` assertion is an array of [ManifestAssertion](manifest-ref.mdx#manifestassertion) objects. For example:
+An action is an assertion that provides information about creation, edits, and other things that have occurred to an asset. In the manifest, an `actions` assertion is an array of [AssertionDefinition](../json-ref/manifest-def.mdx#assertiondefinition) objects.
+
+:::important
+Every manifest has to start with either an `c2pa.opened` or `c2pa.created` action, which has to be the first action in the manifest. Each of these actions need to have an associated ingredient.
+:::
+
+For example:
```json
...
"assertions": [
{
- "label": "c2pa.actions",
+ "label": "c2pa.actions.v2",
"data": {
"actions": [
{
@@ -298,21 +128,32 @@ Each object in the `actions` array has the following standard properties.
| `digitalSourceType` | No | A URL identifying a [IPTC term](https://cv.iptc.org/newscodes/digitalsourcetype/). See [Digital source type](#digital-source-type). | `http://cv.iptc.org/newscodes/`
`digitalsourcetype/digitalCapture` |
| `softwareAgent` | No | The software or hardware used to perform the action. | `"Adobe Firefly"` |
| `parameters` | No | Additional information describing the action; see [Parameters](#parameters) | Reference to ingredients in the `ingredientIds` array. |
+| `parameters` | No | Additional information describing the action; see [Parameters](#parameters) | Reference to ingredients in the `ingredientIds` array. |
-### Action names
+### V2 actions
-The value of the `action` property must be either one of the pre-defined [standard C2PA action strings](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_actions) of the form `c2pa.*` or a custom action name. The set of standard C2PA actions includes fundamental ones as `c2pa.created` for when an asset is first created, and others (`c2pa.cropped`, `c2pa.resized`, and so on) for when an asset's content is modified in some way.
+The [C2PA Technical Specification](https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_actions) describes expanded v2 actions. V1 actions have a label of `c2pa.actions` v2 actions have a label of `c2pa.actions.v2`. Actions are modelled after XMP ResourceEvents, but with a number of C2PA-specific adjustments.
-For the complete list of standard actions, see the [C2PA Technical Specification](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_actions).
+V1 actions are fully specified in the `actions` array. However, 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.
+
+
+### Action names
+
+The value of the `action` property must be either one of the pre-defined [standard C2PA action strings](https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_actions) of the form `c2pa.*` or a custom action name. The set of standard C2PA actions includes fundamental ones as `c2pa.created` for when an asset is first created, and others (`c2pa.cropped`, `c2pa.resized`, and so on) for when an asset's content is modified in some way.
+
+For the complete list of standard actions, see the [C2PA Technical Specification](https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_actions).
### Digital source type
Use the `digitalSourceType` property to specify how an asset was created or modified, for example "digital capture", "digitized from negative," or "trained algorithmic media."
-The value of `digitalSourceType` is one of the URLs specified by the International Press Telecommunications Council (IPTC) [NewsCodes Digital Source Type scheme](https://cv.iptc.org/newscodes/digitalsourcetype/) of the form `http://cv.iptc.org/newscodes/digitalsourcetype/negativeFilm/`, where `` is one of the codes shown in the following table.
+The value of `digitalSourceType` is one of the URLs specified by the International Press Telecommunications Council (IPTC) [NewsCodes Digital Source Type scheme](https://cv.iptc.org/newscodes/digitalsourcetype/) of the form `http://cv.iptc.org/newscodes/digitalsourcetype/`, where `` is one of the codes shown in the following table.
-| Code | Description |
+| Code | Description |`
|---|---|
| algorithmicallyEnhanced | Minor augmentation or correction by algorithm. |
| algorithmicMedia | Media created purely by an algorithm not based on any sampled training data, e.g. an image created by software using a mathematical formula. |
@@ -321,7 +162,7 @@ The value of `digitalSourceType` is one of the URLs specified by the Internation
| compositeSynthetic | Mix or composite of several elements, at least one of which is synthetic. |
| compositeWithTrainedAlgorithmicMedia | The compositing of trained algorithmic media with some other media, such as with inpainting or outpainting operations. |
| dataDrivenMedia | Digital media representation of data via human programming or creativity. |
-| digitalCreation | Media created by a human using non-generative tools. Use instead of retired digitalArt code. |
+| digitalCreation | Media created by a human using non-generative tools. Use instead of retired digitalArt code. |
| digitalCapture | The digital media is captured from a real-life source using a digital camera or digital recording device. |
| humanEdits | Augmentation, correction or enhancement by one or more humans using non-generative tools. Use instead of retired minorHumanEdits code. |
| negativeFilm | The digital image was digitized from a negative on film or any other transparent medium. |
@@ -347,7 +188,7 @@ For other possible values of `digitalSourceType`, see [Digital source type](#dig
"assertions": [
...
{
- "label": "c2pa.actions",
+ "label": "c2pa.actions.v2",
"data": {
"actions": [
{
@@ -381,10 +222,12 @@ The `parameters` property can contain any data that provide more details on the
]
```
+When creating an actions assertion that has an associated ingredient, the `parameters` object must include a `ingredientIds` property with an array of one or more [`instance_id` values](#the-instance_id-property) from ingredients. This is how you associate an action with one or more ingredients.
When creating an actions assertion that has an associated ingredient, the `parameters` object must include a `ingredientIds` property with an array of one or more [`instance_id` values](#the-instance_id-property) from ingredients. This is how you associate an action with one or more ingredients.
:::info
The [C2PA specification](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_parameters) requires that a `c2pa.transcoded`, `c2pa.repackaged`, `c2pa.opened`, or a `c2pa.placed` action have one or more associated ingredients, so it is very important to add the `ingredientIds` parameter with a matching ingredient.
+The [C2PA specification](https://c2pa.org/specifications/specifications/2.1/specs/C2PA_Specification.html#_parameters) requires that a `c2pa.transcoded`, `c2pa.repackaged`, `c2pa.opened`, or a `c2pa.placed` action have one or more associated ingredients, so it is very important to add the `ingredientIds` parameter with a matching ingredient.
:::
For example:
@@ -394,6 +237,7 @@ For example:
{
"action": "c2pa.opened",
"parameters": {
+ "ingredientIds": [
"ingredientIds": [
"xmp.iid:813ee422-9736-4cdc-9be6-4e35ed8e41cb"
]
@@ -406,13 +250,13 @@ For example:
The old `ingredientId` field is deprecated.
:::
-For more information on action parameters, see the [C2PA Technical Specification](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_parameters).
+For more information on action parameters, see the [C2PA Technical Specification](https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_parameters).
-### The instance_id property
+#### The instance_id property
When defining/writing a manifest, the `instance_id` property identifies an ingredient used in an action.
-Any `c2pa.opened` or `c2pa.placed` action must have an associated ingredient identified by the `ingredientIds` parameters field of the action with an array of ingredient `instance_id` values. For example:
+Any `c2pa.opened` or `c2pa.placed` action must have an associated ingredient identified by the `ingredientIds` parameters field of the action with an array of ingredient `instance_id` values.
```json
"ingredients": [
@@ -428,6 +272,7 @@ Any `c2pa.opened` or `c2pa.placed` action must have an associated ingredient ide
{
"action": "c2pa.*",
"parameters": {
+ "ingredientIds": [
"ingredientIds": [
""
],
@@ -442,30 +287,212 @@ For example, the following action identifies that the `c2pa.opened` action was p
```json
"ingredients": [
{
- "title": "test.jpeg",
+ "title": "crater-lake.jpeg",
"format": "image/jpeg",
- "instance_id": "xmp.iid:3250038a-22ca-459b-8392-de275f8b155c",
- "relationship": "parentOf"
+ "instance_id": "xmp.iid:7f136ee1-6e84-4d80-9de3-e1180ef2b690",
+ "relationship": "parentOf",
+ "label": "c2pa.ingredient.v3"
}
],
"assertions": [
{
- "label": "c2pa.actions",
+ "label": "c2pa.actions.v2",
"data": {
"actions": [
+ {
+ "action": "c2pa.opened",
+ "parameters": {
+ "org.cai.ingredientIds": [
+ "xmp.iid:7f136ee1-6e84-4d80-9de3-e1180ef2b690"
+ ],
+ "ingredients": [
+ {
+ "url": "self#jumbf=c2pa.assertions/c2pa.ingredient.v3",
+ "hash": "yb/F7GBepYRyaFM16gzj6t84CKDTnBxhnLqYjnB0iX0="
+ }
+ ]
+ }
+ },
+ ...
+ ]
+ }
+ }
+]
+```
+
+## CAWG metadata assertions
+
+Starting with version 2.2, the C2PA specification provides for a category of [metadata assertions](https://c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#_metadata) with a standardized serialization that replace the old Exif, IPTC, and Creative Work assertions in prior versions of the specification.
+
+Use _CAWG metadata assertions_ to include metadata from metadata standards such as XMP, IPTC, and Exif in a manifest. For more information, see the [CAWG Metadatda Assertion](https://cawg.io/metadata/1.1/#_assertion_definition) technical specification.
+
+Metadata assertions must include one or more `@context` properties in the `data` object, as explained in the [JSON-LD](https://www.w3.org/TR/json-ld/#the-context) specification. Follow the examples shown in each section.
+
+| Assertion | Label | Description |
+|-----------|-------|-------------|
+| [Exif information](#exif-assertion) | `stds.exif` | Camera information such as maker, lens stored in Exchangeable image file format (Exif). |
+| [IPTC photo and video metadata](#iptc-metadata) | `stds.iptc` | Properties from the IPTC Photo and Video Metadata Standards, describing for example ownership, rights, and other metadata about a image or video asset. |
+| [Training and data mining](#do-not-train-assertion) | `cawg.training-mining` | Whether the creator/owner of an asset grants permission to use it for data mining or AI/ML training. NOTE: Previously, this assertion's label was `c2pa.training-mining`. |
+
+### 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.
+
+:::note
+Do not use the IPTC `plus:DataMining` property to indicate whether permission is granted to use an asset in data mining or AI/ML training. Instead use the [CAWG training and data mining assertion](#cawg-training-and-data-mining-assertion).
+:::
+
+For a summary reference to IPTC metadata properties, see [IPTC properties](iptc-properties).
+
+See also:
+- [Exploring c2patool and IPTC Photo Metadata](https://iptc.atlassian.net/wiki/spaces/PMD/pages/613613569/Exploring+c2patool+and+IPTC+Photo+Metadata) (Aug 2022).
+- [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": [
{
- "action": "c2pa.opened",
- "parameters": {
- "ingredientIds": [
- "xmp.iid:3250038a-22ca-459b-8392-de275f8b155c"
- ],
- }
- },
- ...
+ "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."
+ }
+ },
+ ...
+]
```
-### V2 actions
+## CAWG training and data mining assertion
-This documentation covers C2PA v1 actions. The [C2PA Technical Specification](https://c2pa.org/specifications/specifications/1.4/specs/C2PA_Specification.html#_actions) also describes expanded v2 actions. V1 actions are fully specified in the actions array. However, a v2 action may either be specified by an element of the actions array or from an element in the templates array with the same action name.
+Assertions with the `cawg.training-mining` label provide information about whether an asset with C2PA metadata may be used as part of a data mining or AI/ML (artificial intelligence / machine learning) workflows, including whether permission is granted to use an asset in ML training or inference.
-There are some additional differences between v1 and v2 actions, for example in v2, `softwareAgent` is a [ClaimGeneratorInfo](../manifest/manifest-ref.mdx#claimgeneratorinfo) structure instead of a string. The CAI APIs can read all v2 actions and write most v2 actions.
+:::note
+Training and data mining assertions formerly had `c2pa.*` labels. See [Legacy training and data mining assertion](../reading/legacy.md#legacy-training-and-data-mining-assertion) for more information.
+:::
+
+| Entry Key | Whether permission is granted... | Possible values of `use` property |
+|-----------|-------------|-------------|
+| `cawg.data_mining` | To extract text or data from the asset for purposes of determining "patterns, trends and correlations," including images containing text, where the text could be extracted via OCR. | `allowed`,
`notAllowed`,
or `constrained` |
+| `cawg.ai_inference` | To use the asset as input to a trained AI/ML model for the purposes of inferring a result. Sometimes referred to as the "do not infer" assertion. | `allowed`,
`notAllowed`,
or `constrained` |
+| `cawg.ai_generative_training` | To use the asset as training data for a generative AI/ML model that could produce derivative assets. Sometimes referred to as the "do not train" assertion. | `allowed`,
`notAllowed`,
or `constrained` |
+| `cawg.ai_training` |To use the asset to train non-generative AI/ML models, such as those used for classification, object detection, and so on. | `allowed`,
`notAllowed`,
or `constrained` |
+
+The value of each of these properties is an object with a `use` property that can have one of these values:
+
+- `allowed`: Permission is granted for this type of use.
+- `notAllowed`: Permission is NOT granted for this type of use.
+- `constrained`: Permission is not unconditionally granted for this use. You can provide more details (such as contact information) in the `constraints_info` text property.
+
+For more information, see the [CAWG Training and Data Mining Assertion](https://cawg.io/training-and-data-mining/1.1/#_assertion_definition) technical specification.
+
+For example:
+
+```json
+"assertions": [
+ ...
+ {
+ "label": "cawg.training-mining",
+ "data": {
+ "entries": {
+ "cawg.ai_generative_training": { "use": "notAllowed" },
+ "cawg.ai_inference": { "use": "notAllowed" },
+ "cawg.ai_training": { "use": "notAllowed" },
+ "cawg.data_mining": {
+ "use": "constrained",
+ "constraint_info" : "Contact foo@bar.com for more information."
+ }
+ }
+ }
+ }
+ ...
+]
+```
+
+## Custom assertions
+
+In addition to the C2PA standard assertions, you can also define custom assertions if the standard assertions don't cover your specific needs. A custom assertion has a label string with [reverse domain name notation](https://en.wikipedia.org/wiki/Reverse_domain_name_notation) syntax, for example `com.adobe.product-foo.bar`.
+
+For example:
+
+```json
+"assertions": [
+ ...
+ {
+ "label": "com.mycompany.myproduct",
+ "data": {
+ "git_hash": "023bb51",
+ "lib_name": "Our C2PA C++ Library",
+ "lib_version": "2.5.1",
+ "target_spec_version": "1.2"
+ },
+ "kind": "Json"
+ },
+ ...
+]
+```
diff --git a/docs/manifest/writing/ingredients.md b/docs/manifest/writing/ingredients.md
new file mode 100644
index 0000000..47f0373
--- /dev/null
+++ b/docs/manifest/writing/ingredients.md
@@ -0,0 +1,73 @@
+---
+id: ingredients
+title: Writing 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_.
+
+[Old manifests](../reading/legacy.md) may contain deprecated v1 and v2 ingredients, but applications should only write v3 ingredients.
+
+Applications should write only v3 ingredients, with label starting with `c2pa.ingredient.v3` as described in the [C2PA specification](https://spec.c2pa.org/specifications/specifications/2.2/specs/C2PA_Specification.html#ingredient_assertion).
+
+The API will only write v3 ingredients to a v2 claim. It will write v2 ingredients to a v1 claim and will read any of the three formats.
+
+:::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
+
+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.
+
+When reading an ingredient, `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. you can use your own labels when creating new ingredients, but those labels are only temporary and will be replaced.
+
+Other important properties of the ingredient object include:
+- `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.
+
+For example:
+
+```json
+"ingredients": [
+ {
+ "title": "turkey.jpeg",
+ "format": "image/jpeg",
+ "instance_id": "xmp.iid:3250038a-22ca-459b-8392-de275f8b155c",
+ "relationship": "parentOf",
+ "label": "c2pa.ingredient.v3"
+ },
+ ...
+],
+```
+
+### Relationship
+
+The ingredient object's `relationship` property describes its relationship to the current asset. This property can have one of three values, as described in the table below.
+
+| Value of `relationship` | Description |
+|--------------------------|-------------|
+| `parentOf` | The current asset is a derived asset or asset rendition of this ingredient. This relationship value is also used with update manifests. There can be at most one parent ingredient in a manifest. |
+| `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. |
+
+Note that `parentOf` ingredients must have a matching `c2pa.opened` action as the first action in the manifest and `componentOf` ingredients must have an associated `c2pa.placed` action.
+
+## Validation results
+
+See [Validation results](json-ref/reader#validationresults) in the manifest JSON reference.
+
+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.
+- A composed asset's Content Credentials may be invalid, but one or more of its ingredients may have valid Content Credentials.
+
+:::note
+Ingredient certificates are validated when they are added to the manifest store, NOT during validation of the composed asset.
+:::
diff --git a/docs/manifest/writing/writing.md b/docs/manifest/writing/writing.md
new file mode 100644
index 0000000..7f81dea
--- /dev/null
+++ b/docs/manifest/writing/writing.md
@@ -0,0 +1,10 @@
+---
+id: writing-index
+title: Building and writing manifest data
+---
+
+Use a [ManifestDefinition](../json-ref/manifest-def.mdx) structure to define and construct manifest data for writing. The Rust library and other language libraries provide methods and objects for working with this structure. This JSON reference is generated from the JSON schema for the [ManifestDefinition](https://docs.rs/c2pa/latest/c2pa/struct.ManifestDefinition.html) object (_struct_ in Rust terminology).
+
+- [Writing ingredients](ingredients.md)
+- [Writing assertions and actions](assertions-actions.md)
+- [ManifestDefinition JSON reference](manifest/json-ref/manifest-def.mdx)
diff --git a/sidebars.js b/sidebars.js
index b28649e..187b3a2 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -29,47 +29,63 @@ const sidebars = {
},
{
type: 'category',
- label: 'Understanding manifests',
+ label: 'Working with manifests',
link: { type: 'doc', id: 'manifest/understanding-manifest' },
collapsed: true,
items: [
{
- type: 'doc',
- id: 'manifest/assertions-actions',
- },
- {
- type: 'doc',
- id: 'manifest/ingredients',
- },
- {
- type: 'doc',
- id: 'manifest/manifest-validation',
- },
- {
- type: 'doc',
- id: 'manifest/cawg-id',
- },
- {
- type: 'doc',
- id: 'manifest/manifest-examples',
- label: 'Examples',
+ type: 'category',
+ label: 'Reading manifest data',
+ link: { type: 'doc', id: 'manifest/reading/reading-index' },
+ collapsed: true,
+ items: [
+ {
+ type: 'doc',
+ id: 'manifest/reading/reading-ingredients',
+ },
+ {
+ type: 'doc',
+ id: 'manifest/reading/reading-cawg-id',
+ },
+ {
+ type: 'doc',
+ id: 'manifest/reading/legacy-manifests',
+ },
+ {
+ type: 'doc',
+ id: 'manifest/reading/manifest-validation',
+ },
+ {
+ type: 'doc',
+ id: 'manifest/json-ref/reader',
+ },
+ ],
},
{
type: 'category',
- label: 'JSON reference',
- link: { type: 'doc', id: 'manifest/json-ref/index' },
+ label: 'Writing manifest data',
+ link: { type: 'doc', id: 'manifest/writing/writing-index' },
collapsed: true,
items: [
{
type: 'doc',
- id: 'manifest/json-ref/manifest-def',
+ id: 'manifest/writing/ingredients',
},
{
type: 'doc',
- id: 'manifest/json-ref/reader',
+ id: 'manifest/writing/assertions-actions',
+ },
+ {
+ type: 'doc',
+ id: 'manifest/json-ref/manifest-def',
},
],
},
+ {
+ type: 'doc',
+ id: 'manifest/manifest-examples',
+ label: 'Examples',
+ },
],
},
{