Skip to main content

Configuring SDK settings with Context

Regardless of which language you're working in, you use the Context and Settings classes to control SDK behavior including verification, trust anchors, thumbnails, signing, and more.

Overview of Context

Context encapsulates SDK configuration that controls how Reader, Builder, and other components operate, including:

  • Settings: Trust configuration, builder behavior, thumbnails, and more.
  • Signer configuration: Optional signing credentials that can be stored for reuse.

Using Context provides explicit, isolated configuration without thread-local state. It enables you to run different configurations simultaneously (for example for development with test certificates or production with strict validation), simplifies testing, and improves code clarity.

Context:

  • Can be moved but not copied. After moving, is_valid() returns false on the source.
  • Is used at construction: Reader and Builder copy configuration from the Context at construction time. The Context doesn't need to outlive them.
  • Is reusable: Use the same Context to create multiple Reader and Builder instances.

Overview of Settings

You can specify a declarative configuration for the SDK using Settings, that you can load from a JSON file or set programmatically.

Settings object structure

tip

For the complete reference to the Settings object, see SDK object reference - Settings.

Settings JSON has this top-level structure:

{
"version": 1,
"trust": { ... },
"cawg_trust": { ... },
"core": { ... },
"verify": { ... },
"builder": { ... },
"signer": { ... },
"cawg_x509_signer": { ... }
}
PropertyDescription
versionSettings format version (must be 1)
trustCertificate trust configuration for C2PA validation
cawg_trustCertificate trust configuration for CAWG identity assertions
coreCore SDK behavior and performance tuning
verifyValidation and verification behavior
builderManifest creation and embedding behavior
signerC2PA signer configuration
cawg_x509_signerCAWG identity assertion signer configuration

The version property must be 1. All other properties are optional.

info

If you don't specify a property, the SDK uses the default value. If you specify null, the property is explicitly set to null (not the default). This distinction matters when overriding default behavior.

For Boolean values, use JSON true and false, not the strings "true" and "false".

Creating and using Context

info

For more details on using Context and Settings in Rust, see Python library - Configuring SDK settings

Creating a Context

The simplest way to create a Context is with default settings:

from c2pa import Context

ctx = Context() # Uses SDK defaults

This is appropriate for quick prototyping or when the SDK defaults are acceptable.

Creating from inline JSON

from c2pa import Context

try:
ctx = Context.from_dict({
"verify": {
"verify_cert_anchors": True
},
"trust": {
"trust_anchors": "some url"
}
})
except Exception as e:
print(f"Exception loading settings: {e}")

Creating from a JSON file

import json
from c2pa import Context, Settings

with open("config/settings.json", "r") as f:
settings = Settings.from_json(f.read())

ctx = Context(settings)

Using Context with Reader

Reader uses Context to control how it validates manifests and handles remote resources:

  • Verification behavior: Whether to verify after reading, check trust, and so on.
  • Trust configuration: Which certificates to trust when validating signatures.
  • Network access: Whether to fetch remote manifests or OCSP responses.
info

Context is used only at construction time. Reader copies the configuration it needs internally, so the Context does not need to outlive the Reader. A single Context can be reused for multiple Reader instances.

ctx = Context.from_dict({"verify": {"remote_manifest_fetch": False}})
reader = Reader("image.jpg", context=ctx)
print(reader.json())

Reading an asset from a stream:

with open("image.jpg", "rb") as stream:
reader = Reader("image/jpeg", stream, context=ctx)
print(reader.json())

Using Context with Builder

Builder uses Context to control how it creates and signs C2PA manifests. The Context affects:

  • Claim generator information: Application name, version, and metadata embedded in the manifest.
  • Thumbnail generation: Whether to create thumbnails, and their size, quality, and format.
  • Action tracking: Auto-generation of actions like c2pa.created, c2pa.opened, c2pa.placed.
  • Intent: The purpose of the claim (create, edit, or update).
  • Verification after signing: Whether to validate the manifest immediately after signing.
  • Signer configuration (optional): Credentials stored in the context for reuse.
info

Context is used only when constructing the Builder. The Builder copies the configuration it needs internally, so the Context does not need to outlive the Builder. A single Context can be reused for multiple Builder instances.

ctx = Context.from_dict({
"builder": {
"claim_generator_info": {"name": "An app", "version": "0.1.0"},
"intent": {"Create": "digitalCapture"}
}
})

builder = Builder(manifest_json, context=ctx)

with open("source.jpg", "rb") as src, open("output.jpg", "w+b") as dst:
builder.sign(signer, "image/jpeg", src, dst)