A Rust CLI for validating C2PA media assets, evaluating conformance rubrics, and detecting provenance signals. Built on c2pa-rs, this tool validates signed assets against trust lists, evaluates asset profiles, and runs composable YAML rubrics that test conformance traits and signal detection across manifest chains.
This is the Encypher fork of contentauth/c2pa-conformance-tool-cli, adding rubric evaluation, signals analysis, untrusted asset support, and security patches.
Validation - Read C2PA manifests from binary assets, sidecar .c2pa files, or crJSON reports. Verify signatures, hash bindings, timestamps, and trust chain against configurable trust lists.
Rubric evaluation - Evaluate composable YAML rubrics against an asset's crJSON representation. Rubrics define traits (boolean expressions over crJSON fields) grouped by category. Two evaluation modes:
- Conformance mode evaluates the rubric against the whole crJSON document (structural correctness, deprecated assertions, trust status, claim constraints)
- Signals mode evaluates the rubric per-manifest, detecting inception signals (capture, GenAI, composite) and transformation signals (editorial AI, non-editorial) across the full provenance chain
Profile evaluation - Evaluate YAML profiles (legacy format from upstream) against each asset's crJSON indicators.
The tool validates any format supported by c2pa-rs:
| Category | Formats |
|---|---|
| Image | JPEG, PNG, WebP, AVIF, DNG, GIF, HEIC, HEIF, SVG, TIFF |
| Video | MP4, MOV, AVI, M4V |
| Audio | AAC/M4A, MP3, WAV |
| Document |
For formats where c2pa-rs lacks codec support (FLAC, DOCX, EPUB, ODT, OXPS, OTF, JXL), use -crjson mode with pre-extracted crJSON files.
git clone https://github.com/encypherai/c2pa-conformance-tool-cli.git
cd c2pa-conformance-tool-cli
cargo build -releaseThe binary is at target/release/c2pa-validate.
cargo test -release - -include-ignoredThis runs 100+ tests including golden fixture tests for conformance and signals rubrics.
Validate a signed image against the default C2PA trust list:
c2pa-validate image.jpgEvaluate conformance rubrics against a signed asset:
c2pa-validate -rubric testfiles/rubrics/asset-rubric-conformance0.1-spec2.2.yml image.jpgDetect provenance signals across a manifest chain:
c2pa-validate -rubric testfiles/rubrics/asset-rubric-signals-local.yml -rubric-mode signals image.jpgEvaluate a pre-extracted crJSON file (for formats c2pa-rs cannot read):
c2pa-validate -crjson -rubric testfiles/rubrics/asset-rubric-conformance0.1-spec2.2.yml asset_crjson.jsonExtract crJSON from a binary asset without rubric evaluation:
c2pa-validate -emit-crjson -o asset_crjson.json image.jpgc2pa-validate [OPTIONS] [INPUT]...
| Option | Description |
|---|---|
INPUT... |
Files or glob patterns to validate |
-o, -output FILE_OR_DIR |
Output file or directory |
-f, -format json|yaml|markdown|html |
Output format (default: json) |
-strict |
Fail on warnings, not only invalid assets |
-v, -verbose |
Increase verbosity (repeat for debug) |
| Option | Description |
|---|---|
-t, -trust-mode default|itl|custom |
Trust list mode |
-trust-list FILE_OR_URL |
PEM trust list (required for custom mode) |
-settings FILE |
Overlay c2pa-rs settings (JSON/TOML) |
| Option | Description |
|---|---|
-rubric FILE |
YAML rubric file to evaluate against crJSON |
-rubric-dir DIR |
Directory of rubric YAML files; evaluates all |
-rubric-mode conformance|signals |
Evaluation mode (default: conformance) |
-rubric-strict |
Fail if any rubric trait evaluates to false |
-crjson |
Treat inputs as pre-existing crJSON files |
-emit-crjson |
Extract crJSON from binary assets and write to output |
| Option | Description |
|---|---|
-cert-profile PEM_OR_DER |
Validate a certificate against a C2PA profile schema |
-cert-schema SCHEMA_FILE |
C2PA certificate profile JSON schema to validate against |
-emit-cert-json |
Emit the certificate's JSON representation to stdout |
| Option | Description |
|---|---|
-profile FILE |
YAML profile to evaluate against each asset's crJSON |
default- Official C2PA Conformance Trust List onlyitl- Official list first, then the Interim Trust Listcustom- Your own PEM trust list (requires-trust-list)
When rubric evaluation is requested and all trust scenarios fail (e.g., self-signed certificates from pre-conformant products), the tool falls back to untrusted extraction. The crJSON is still produced and evaluated; the trusted_success trait reflects the trust failure.
Rubrics are composable YAML files that define boolean traits evaluated against crJSON. Each trait has:
- An
expression: a json-formula expression over the crJSON document - A
reportText: human-readable description when the trait passes - An optional
failText: description when the trait fails
Rubric expressions support named expressions with positional parameters ($arg0, $arg1, ...) and automatic normalization of bare json-formula keywords (true/false/null to true()/false()/null()). JSON literal form (`true`, `null`) is preferred in rubric YAML and works across all three json-formula implementations (Python, Rust, JavaScript). Report text templates support {{matches}} substitution, which is replaced with the comma-joined expression result for failIfMatched statements.
| File | Purpose |
|---|---|
asset-rubric-conformance0.1-spec2.2.yml |
C2PA Spec 2.2 conformance (16 traits) |
asset-rubric-conformance0.2-spec2.2.yml |
Updated conformance (17 traits) |
asset-rubric-conformance0.2-spec2.4.yml |
C2PA Spec 2.4 conformance (24 traits) |
asset-rubric-signals-local.yml |
Signal detection (13 trait categories) |
asset-rubric-integrity.yml |
Integrity verification traits |
Conformance rubrics check structural correctness of the active manifest:
well_formed_data_present/well_formed_success- Validation results exist and contain no structural failuresvalid_data_present/valid_success- Integrity validation present with no hash mismatchestrusted_data_present/trusted_success- Trust validation present with signing credential trustedactive_manifest_urn- Active manifest uses standardurn:c2pa:prefixno_deprecated_assertions/no_deprecated_actions- No use of deprecated C2PA assertions or actionsinception_action_position- Inception action is first in the first created actions assertioningredient_relationship_values- All ingredients have valid relationship valuesupdate_manifest_constraints- Update manifest constraints satisfied
Signals mode produces per-manifest context including:
assertedBy- Identity from the signing certificate (CN, O, OU fields)mimeType- Media type derived from parent ingredient referencesallActionsIncluded- Whether the manifest claims completeness of its action listingredients- Resolved ingredient references with manifest indices and relationshipslocalInceptions- Detected inception signals (capture, GenAI, composite, unknown provenance)localTransformations- Detected transformation signals (editorial AI, non-editorial edits)
The tool validates X.509 certificates against the C2PA conformance program's certificate profile JSON schemas. This verifies that CA-issued certificates conform to the structural requirements for root CAs, issuing CAs, claim signing leaves, and OCSP responders before submitting to the conformance program.
- Parses PEM or DER certificates using
x509-parser - Serializes the certificate to the JSON format expected by the C2PA profile schemas, including
_pyasn1_decodedfields for custom C2PA extensions (assurance level, CPL record ID) - Validates the JSON against the schema using Draft 2020-12 JSON Schema validation
| Schema | Validates |
|---|---|
rootCA.cert.schema.json |
Root CA (self-signed, keyCertSign + cRLSign) |
claimSigningIssuingCA.cert.schema.json |
Issuing CA (pathlen:0, keyCertSign + cRLSign) |
claimSigningLeaf.al1.cert.schema.json |
Claim signing leaf AL1 (digitalSignature + contentCommitment, c2pa-kp-claimSigning EKU, assurance level, CPL record) |
ocspResponderLeaf.cert.schema.json |
OCSP responder (id-kp-OCSPSigning, OCSP No Check) |
Schemas are in testfiles/c2pa-cert-schemas/ and originate from the C2PA conformance program.
Validate a claim signing leaf certificate:
c2pa-validate -cert-profile leaf.pem -cert-schema testfiles/c2pa-cert-schemas/claimSigningLeaf.al1.cert.schema.jsonValidate an entire CA hierarchy:
c2pa-validate -cert-profile root.pem -cert-schema testfiles/c2pa-cert-schemas/rootCA.cert.schema.json
c2pa-validate -cert-profile issuing.pem -cert-schema testfiles/c2pa-cert-schemas/claimSigningIssuingCA.cert.schema.json
c2pa-validate -cert-profile leaf.pem -cert-schema testfiles/c2pa-cert-schemas/claimSigningLeaf.al1.cert.schema.json
c2pa-validate -cert-profile ocsp.pem -cert-schema testfiles/c2pa-cert-schemas/ocspResponderLeaf.cert.schema.jsonInspect the certificate JSON without schema validation:
c2pa-validate -cert-profile leaf.pem -emit-cert-jsonJSON output for CI integration:
c2pa-validate -cert-profile leaf.pem -cert-schema schema.json -f jsonThe exit code is 0 on pass, 1 on schema validation failure.
To validate certificates from your CA against C2PA profiles:
- Export each certificate in the chain as PEM (root, issuing CA, leaf, OCSP responder)
- Run each against the corresponding schema
- Fix any reported errors (the schema error paths point to the exact field)
- Re-run until all four pass
The test suite includes positive and negative validation tests. Generate your own test certificates, place them in the test-certs directory, and run:
cargo test -release -test cert_profile_validationThe testfiles/encypher-assets/ directory contains 29 signed test assets across all C2PA-supported media formats, each with a companion Reader JSON file. For 7 formats where c2pa-rs lacks native codec support (FLAC, DOCX, EPUB, ODT, OXPS, OTF, JXL), pre-converted crJSON files are included for rubric evaluation via -crjson mode.
c2pa-conformance-tool-cli/
crates/
c2pa-validate/ # Main CLI crate
vendor/
c2pa-rs/ # Vendored C2PA SDK (c2pa v0.78.0)
profile-evaluator-rs/ # Rubric + profile evaluation engine
json-formula-rs/ # json-formula expression evaluator (upstream-compatible)
testfiles/
rubrics/ # Rubric YAML files and golden fixtures
c2pa-cert-schemas/ # C2PA certificate profile JSON schemas
encypher-assets/ # 29 signed test assets across all formats
profiles/ # Legacy profile YAML files
samples/ # Upstream sample assets
This fork adds the following to contentauth/c2pa-conformance-tool-cli:
- Rubric evaluation engine -
-rubric,-rubric-dir,-rubric-mode,-rubric-strictflags for composable YAML rubric evaluation in conformance and signals modes - crJSON extraction -
-emit-crjsonto extract crJSON from binary assets;-crjsonto evaluate pre-existing crJSON files - Signals analysis - Per-manifest signal detection (inception and transformation signals) with ingredient resolution across manifest chains
- Untrusted asset support - Automatic fallback to
verify_trust: falsewhen trust verification fails, enabling rubric evaluation on assets signed with certificates not yet in a trust list - Certificate profile validation -
-cert-profile,-cert-schema,-emit-cert-jsonflags for validating X.509 certificates against C2PA certificate profile JSON schemas (root CA, issuing CA, claim signing leaf, OCSP responder) - Evaluator-layer expression handling - Parameterized named expressions (
$argN) and bare-keyword normalization handled in the evaluator, keeping json-formula-rs upstream-compatible - Security patches - Bumped
rustls-webpki(3 CVEs),rustls, andrandto patched versions - 29 test assets - Signed conformance test assets across all supported C2PA media formats
- 100+ tests - Golden fixture tests for conformance and signals rubrics, cert profile validation, integration tests for all CLI modes
Apache-2.0. See LICENSE for details.