Tools

C2PA Command Line Tool: The Complete Guide to c2patool (2026)

49 views
C2PA Command Line Tool: The Complete Guide to c2patool (2026)

Whether you are a developer integrating content provenance into a pipeline, a journalist verifying photo origins, or a photographer protecting your work, c2patool is the Swiss-army knife you need. This guide covers everything — from installing the tool on Windows, macOS, and Linux to reading, creating, and verifying C2PA manifests like a pro.

Table of Contents

What is c2patool?

c2patool is the official open-source command-line tool created by the Content Authenticity Initiative (CAI) for working with C2PA (Coalition for Content Provenance and Authenticity) manifests. It is written in Rust and available on GitHub.

With c2patool you can:

  • Read C2PA manifest data embedded in images, videos, audio, and documents
  • Create new manifests and embed them (sign) into asset files
  • Verify digital signatures against configurable trust lists
  • Inspect ingredients, assertions, and provenance chains
  • Generate external (sidecar) or remote manifests for advanced workflows

c2patool supports a wide range of file formats including JPEG, PNG, WebP, TIFF, HEIC, HEIF, AVIF, MP4, MOV, WAV, MP3, PDF, SVG, and more.

Prerequisites

Before installing c2patool, ensure you have one of the following:

  • Pre-built binary — No dependencies needed (recommended for most users)
  • Rust toolchain — Required only if building from source via cargo

Installation (Windows, macOS, Linux)

There are four ways to install c2patool. Choose the method that works best for your operating system and workflow.

Method 1: Download Pre-built Binaries (All Platforms)

The easiest method. Download the latest release from GitHub Releases.

Windows

  1. Download the c2patool-vX.X.X-x86_64-pc-windows-msvc.zip file
  2. Extract the ZIP to a folder, e.g., C:\c2patool
  3. Add the folder to your PATH environment variable:
    # PowerShell (run as Administrator)
    [Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\c2patool", "Machine")
  4. Open a new terminal and verify: c2patool --version

macOS

  1. Download the c2patool-vX.X.X-x86_64-apple-darwin.tar.gz (Intel) or c2patool-vX.X.X-aarch64-apple-darwin.tar.gz (Apple Silicon)
  2. Extract and move to your PATH:
    tar -xzf c2patool-*.tar.gz
    sudo mv c2patool /usr/local/bin/
    chmod +x /usr/local/bin/c2patool
  3. If macOS blocks the binary, allow it in System Preferences → Security & Privacy
  4. Verify: c2patool --version

Linux

  1. Download the c2patool-vX.X.X-x86_64-unknown-linux-gnu.tar.gz file
  2. Extract and install:
    tar -xzf c2patool-*.tar.gz
    sudo mv c2patool /usr/local/bin/
    chmod +x /usr/local/bin/c2patool
  3. Verify: c2patool --version

Method 2: Install via Cargo (All Platforms)

If you have the Rust toolchain installed, you can install c2patool directly from crates.io:

cargo install c2patool

This compiles c2patool from source and places the binary in ~/.cargo/bin/.

Method 3: Install via Homebrew (macOS / Linux)

brew install c2patool

Homebrew will manage updates for you — just run brew upgrade c2patool when a new version is available.

Method 4: Build from Source (All Platforms)

git clone https://github.com/contentauth/c2patool.git
cd c2patool
cargo build --release
# Binary will be at ./target/release/c2patool

Building from source gives you access to the latest features on the main branch.

Verify Your Installation

After installation, confirm c2patool is working:

c2patool --version
# Output: c2patool 0.26.27

You can also view the full help:

c2patool --help

Basic Syntax

Every c2patool command follows this pattern:

c2patool <ASSET_PATH> [OPTIONS] [SUBCOMMAND]

Where:

  • <ASSET_PATH> — Relative or absolute file path to the asset
  • [OPTIONS] — One or more command-line options (see full list below)
  • [SUBCOMMAND] — Optional: trust, fragment, or help

Quick Reference: Key Options

OptionShortDescription
--manifest <file>-mManifest definition file to add/embed
--output <path>-oOutput file or directory
--config <json>-cInline manifest definition (JSON string)
--parent <file>-pParent file (previous version of asset)
--ingredient-iCreate an ingredient report
--detailed-dShow detailed internal C2PA format
--infoShow high-level information report
--sidecar-sGenerate external manifest (.c2pa file)
--remote <url>-rEmbed remote manifest URL reference
--force-fForce overwrite existing output
--treeDisplay manifest tree structure
--certsShow certificate information
--no_signing_verifySkip post-signing verification (faster)
--version-VDisplay version

Reading Manifests

The most common use case: reading existing C2PA manifest data from a file.

# Read manifest and print to stdout (JSON)
c2patool photo.jpg

# Read manifest from a PNG
c2patool image.png

# Read manifest from a video
c2patool video.mp4

# Read manifest from a PDF
c2patool document.pdf

The tool outputs the manifest JSON to standard output, which you can pipe or redirect:

# Save manifest to a file
c2patool photo.jpg > manifest.json

# Pretty-print with jq
c2patool photo.jpg | jq '.manifests'

# Extract specific fields
c2patool photo.jpg | jq '.active_manifest'

If the file has no C2PA manifest, the tool will display an appropriate message.

Detailed & Info Reports

Detailed Report (-d)

The -d option displays the internal C2PA format of all manifests in the asset, great for debugging and deep inspection:

c2patool photo.jpg -d

When combined with --output, it saves to a file named detailed.json in the output folder.

Information Report (--info)

The --info option prints a high-level summary: manifest store size, number of manifests, validation status, and cloud manifest URLs.

c2patool photo.jpg --info

This is perfect for quick checks without reading the full manifest JSON.

Saving Manifest Data to a Directory

Use --output with a directory path to extract the full manifest including assertion thumbnails and ingredient data:

c2patool photo.jpg --output ./report

This creates a folder containing:

  • manifest_store.json — Full manifest data
  • Assertion thumbnails
  • Ingredient thumbnails
  • detailed.json (if -d was also used)

Creating Ingredients from Files

The --ingredient (-i) option creates an ingredient report from an asset. When combined with --output, it extracts thumbnails and the binary .c2pa manifest store.

c2patool photo.jpg --ingredient --output ./ingredient

The resulting ingredient JSON can be referenced in a manifest definition to carry the full provenance history into a newly created manifest — essential for maintaining the chain of trust.

Adding a Manifest to an Asset

This is where c2patool shines for content creators. Use -m to embed a C2PA manifest into a file:

c2patool image.jpg -m manifest.json -o signed_image.jpg

Important rules:

  • The output file extension must match the source — c2patool will not convert between file types
  • If the output path is the same as the source, the tool overwrites the original
  • Use -f to force overwrite if the output file already exists

Signing Certificates

If your manifest definition includes private_key and sign_cert fields, c2patool uses those for signing. Otherwise, it falls back to a built-in test certificate (suitable only for development).

You can also specify credentials via environment variables. See Creating and using an X.509 certificate for production signing.

⚠️ Security Warning: Accessing private keys directly on disk is fine during development, but in production use a Key Management Service (KMS) or Hardware Security Module (HSM).

Understanding the Manifest Definition File

A manifest definition is a JSON file that describes the provenance claims you want to embed. Here's a complete example:

{
  "claim_generator": "MyApp/1.0",
  "title": "My Photo",
  "assertions": [
    {
      "label": "c2pa.actions",
      "data": {
        "actions": [
          {
            "action": "c2pa.created",
            "digitalSourceType": "http://cv.iptc.org/newscodes/digitalsourcetype/digitalCapture"
          }
        ]
      }
    },
    {
      "label": "stds.schema-org.CreativeWork",
      "data": {
        "@type": "CreativeWork",
        "@context": "https://schema.org",
        "author": [
          {
            "@type": "Person",
            "name": "Photographer Name"
          }
        ]
      }
    }
  ],
  "private_key": "certs/my_key.pem",
  "sign_cert": "certs/my_cert.pem"
}

Key fields:

  • claim_generator — Identifies your application
  • title — Human-readable name of the asset
  • assertions — Array of provenance claims (actions, creative work metadata, etc.)
  • ingredients — References to source materials (optional)
  • private_key / sign_cert — Paths to signing credentials

Providing a Manifest on the Command Line

Use --config (-c) to provide the manifest definition directly as a JSON string instead of a file:

c2patool image.jpg   -c '{"assertions": [{"label": "org.contentauth.test", "data": {"my_key": "whatever I want"}}]}'

This is convenient for quick tests and CI/CD pipelines.

Specifying a Parent File

A parent file represents the state of an asset before the current edits. Use --parent (-p) to create a provenance chain:

# Direct parent file
c2patool edited.jpg -m manifest.json -p original.jpg -o signed_edited.jpg

# Using a previously-created ingredient as the parent
c2patool original.jpg --ingredient --output ./ingredient
c2patool edited.jpg -m manifest.json -p ./ingredient -o signed_edited.jpg

This links the new manifest to the parent's provenance chain, creating a complete edit history.

External (Sidecar) Manifests

Use --sidecar (-s) to generate the manifest as an external .c2pa file instead of embedding it in the asset:

c2patool image.jpg -s -m manifest.json -o signed_image.jpg
# Creates: signed_image.jpg (copy of original) + signed_image.c2pa (manifest)

Sidecar manifests are useful when you cannot or do not want to modify the original file, such as with file formats that have limited C2PA support.

Remote Manifests

Use --remote (-r) to embed an HTTP reference to the manifest inside the asset. The manifest itself is stored externally:

c2patool image.jpg -r https://cdn.example.com/manifests/image.c2pa -m manifest.json -o signed_image.jpg

This creates:

  • signed_image.jpg — Contains a URL pointer to the manifest
  • signed_image.c2pa — The actual manifest file (upload this to the URL)

Remote manifests keep file sizes small and allow manifest updates without re-distributing assets. The remote URL must be publicly accessible for verification to work.

You can combine -s and -r to embed both an inline manifest and a remote reference.

Signing with Your Own Signer

When the private key is not available on the local system (e.g., using a cloud HSM), use --signer-path to specify an external signing executable:

c2patool image.jpg   --manifest manifest.json   --output signed_image.jpg   --signer-path ./custom-signer   --reserve-size 20248   -f

The signer executable receives claim bytes on stdin and outputs signature bytes on stdout. Use --reserve-size to pre-allocate space for the signature in the output file. Run c2patool --help for details on calculating this value.

Trust Configuration

The trust subcommand validates that an asset was signed by a trusted certificate. A certificate is trusted if it appears on an allowed list or chains back to a trust anchor.

c2patool photo.jpg trust [OPTIONS]

Trust Subcommand Options

OptionEnvironment VariableDescription
--trust_anchors <pem>C2PATOOL_TRUST_ANCHORSPEM file or URL containing root certificates
--allowed_list <pem>C2PATOOL_ALLOWED_LISTPEM file or URL of allowed end-entity certificates
--trust_config <cfg>C2PATOOL_TRUST_CONFIGTrust configuration file with OID constraints

Example using local files:

c2patool photo.jpg trust   --allowed_list allowed_list.pem   --trust_config store.cfg

Example using remote URLs:

c2patool photo.jpg trust   --trust_anchors https://server.com/anchors.pem   --trust_config https://server.com/store.cfg

If c2patool cannot validate claims against the trust lists, the JSON output includes a validation_status field describing each validation problem.

ℹ️ Note: The trust subcommand makes HTTP requests each run. For bulk operations, cache trust list files locally to avoid performance overhead.

Using the Official C2PA Trust List

The official C2PA trust list is the production trust list used by tools in the C2PA conformance program, including Adobe's Content Authenticity Inspect tool.

c2patool photo.jpg trust   --trust_anchors='https://raw.githubusercontent.com/c2pa-org/conformance-public/refs/heads/main/trust-list/C2PA-TRUST-LIST.pem'

Or set it as an environment variable for persistent use:

macOS / Linux

export C2PATOOL_TRUST_ANCHORS='https://raw.githubusercontent.com/c2pa-org/conformance-public/refs/heads/main/trust-list/C2PA-TRUST-LIST.pem'

Windows (PowerShell)

[Environment]::SetEnvironmentVariable("C2PATOOL_TRUST_ANCHORS", "https://raw.githubusercontent.com/c2pa-org/conformance-public/refs/heads/main/trust-list/C2PA-TRUST-LIST.pem", "User")

With this set, simply run c2patool photo.jpg trust and the tool will validate against the official list.

Working with BMFF (Video) Content

The fragment subcommand adds a manifest to fragmented BMFF content (used in adaptive streaming formats like DASH and HLS):

c2patool video.mp4 fragment [OPTIONS]

This is useful for content providers who deliver video via adaptive bitrate streaming and need to embed provenance data in the initialization segment.

Performance Tips

  • Skip post-signing verification: Use --no_signing_verify to speed up signing operations in batch workflows. By default, c2patool validates the signature immediately after signing.
    c2patool image.jpg -m manifest.json -o signed.jpg --no_signing_verify
  • Cache trust lists locally: Download trust anchor PEM files and reference them locally to avoid HTTP requests on every invocation.
  • Batch processing: Pipe file lists through a loop for bulk operations:
    # Bash — sign all JPEGs in a folder
    for f in photos/*.jpg; do
      c2patool "$f" -m manifest.json -f -o "signed/${f##*/}"
    done
  • Use --force: Add -f to avoid errors when output files already exist during batch runs.

Common Workflows & Recipes

1. Verify an Image from Social Media

# Quick check
c2patool downloaded_photo.jpg --info

# Full manifest extraction
c2patool downloaded_photo.jpg --output ./verification_report

# Verify against official trust list
c2patool downloaded_photo.jpg trust   --trust_anchors='https://raw.githubusercontent.com/c2pa-org/conformance-public/refs/heads/main/trust-list/C2PA-TRUST-LIST.pem'

2. Photographer: Sign Your Photos

# Create a manifest definition (save as my_manifest.json)
# Then sign your photo
c2patool RAW_0001.jpg -m my_manifest.json -o signed_RAW_0001.jpg

# Verify the signed photo
c2patool signed_RAW_0001.jpg

3. Developer: Automate in CI/CD

# Use inline config for quick CI signing
c2patool asset.png   -c '{"claim_generator": "CI/CD Pipeline v1.0", "assertions": [{"label": "c2pa.actions", "data": {"actions": [{"action": "c2pa.created"}]}}]}'   -o signed_asset.png   --no_signing_verify

4. Edit Chain: Preserve Provenance

# Step 1: Extract ingredient from original
c2patool original.jpg --ingredient --output ./ingredient

# Step 2: Sign the edited version with parent reference
c2patool edited.jpg -m edit_manifest.json -p ./ingredient -o final_signed.jpg

# Step 3: Verify the chain
c2patool final_signed.jpg

5. Check if an Image is AI-Generated

# Read the manifest and look for digitalSourceType
c2patool ai_image.jpg | jq '.manifests[].assertions[] | select(.label == "c2pa.actions")'

# Look for: "digitalSourceType": "trainedAlgorithmicMedia"

Troubleshooting

Common Issues

ProblemSolution
No manifest foundThe file does not contain C2PA data. Not all images have manifests.
Output file already existsAdd -f to force overwrite.
Unsupported file typec2patool only supports specific formats. Check the supported formats list.
Signing failedCheck your private_key and sign_cert paths. Ensure the certificate is a valid X.509 cert.
Trust validation failedThe signing certificate is not on the trust list. This doesn't mean the manifest is fake — it may use a test certificate.
macOS: "unidentified developer"Go to System Preferences → Security & Privacy and click Open Anyway.
Windows: SmartScreen warningClick More info → Run anyway. The binary is safe but not code-signed by Microsoft.

Frequently Asked Questions

Is c2patool free?

Yes. c2patool is fully open-source under a dual MIT / Apache 2.0 license.

Can I use c2patool in production?

Absolutely. However, do not use the built-in test certificate for production signing. Obtain a proper X.509 certificate from a certificate authority and ideally use a KMS/HSM to protect your private key.

What file formats are supported?

JPEG, PNG, WebP, TIFF, GIF, HEIC, HEIF, AVIF, MP4, MOV, MP3, WAV, RIFF, PDF, SVG, and more. Check the official documentation for the latest list.

Does c2patool strip EXIF data?

No. c2patool preserves existing metadata including EXIF. It adds C2PA data alongside existing metadata.

Can I remove a C2PA manifest?

c2patool does not have a built-in "strip" command. However, certain image editing tools can remove C2PA data when re-saving files.

How does c2patool differ from the C2PA Rust SDK?

c2patool is a CLI wrapper around the c2pa-rs Rust SDK. If you need programmatic access in your application, use the SDK directly. c2patool is ideal for command-line workflows, scripting, and quick inspections.

Online Alternative: C2PA Checker

Don't want to install anything? Use C2PA Checker to verify C2PA manifests directly in your browser.

  • ✅ No installation required
  • ✅ Supports all C2PA file formats
  • ✅ Detects AI-generated content via digitalSourceType
  • ✅ Verifies digital signatures
  • ✅ Multi-file batch verification (up to 20 files)
  • ✅ Also available as a Chrome Extension
  • ✅ Completely free — no signup needed

For automated workflows, CI/CD pipelines, and advanced use cases, c2patool is the better choice. For quick one-off checks, C2PA Checker is the fastest path.

#c2pa-command-line-tool #c2patool #c2pa #command-line #content-credentials #content-provenance #digital-authenticity #cli #open-source #manifest #verification