AI & Agents

How to Extract and Verify C2PA Content Credentials

C2PA Content Credentials are cryptographically signed manifests that record an asset's origin, edits, and provenance chain. This guide covers extracting manifests with c2patool CLI, reading them programmatically with the JavaScript SDK, verifying signatures against trust lists, and comparing C2PA to traditional EXIF metadata.

Fast.io Editorial Team 9 min read
Audit log interface showing file activity and verification history

What C2PA Content Credentials Are

C2PA Content Credentials are cryptographically signed metadata manifests that record where a piece of content came from, what tools created or edited it, and whether AI was involved. They are the technical backbone of content provenance on the web.

The standard comes from the Coalition for Content Provenance and Authenticity (C2PA), whose founding members include Adobe, Arm, Intel, Microsoft, and Truepic. The related Content Authenticity Initiative (CAI), which promotes adoption of the standard, has grown to over 5,000 members including camera manufacturers like Nikon and Canon, social platforms like LinkedIn, and news organizations like The New York Times and BBC.

A C2PA manifest contains four core pieces:

  • Claim: The assertion about the content, including who created it, what software was used, and when
  • Assertions: Specific data points like edit actions, ingredients (source files), and the digital source type (photograph, AI-generated, composite)
  • Signature: A cryptographic signature from a trusted certificate authority that binds the claim and assertions to the content's hash
  • Hard binding: A SHA-256 hash of the asset's bytes, linking the manifest to the exact content it describes

When someone modifies the asset, even by a single pixel, the hash no longer matches. The signature verification fails, and the credential is flagged as invalid. This is what separates C2PA from traditional metadata like EXIF: you cannot silently edit it without breaking the cryptographic chain.

The standard supports images (JPEG, PNG, WebP, TIFF, HEIC, AVIF, DNG), video (MP4, MOV), audio (MP3, WAV), and PDF files. Camera manufacturers including Nikon, Leica, and Sony already ship cameras that sign photos with C2PA credentials at capture time.

Extracting C2PA Manifests with c2patool

c2patool is the official command-line utility for reading and writing C2PA manifests. It is open source, maintained by the Content Authenticity team at Adobe, and available on all major platforms.

Installing c2patool

On macOS with Homebrew:

brew install c2patool

On any platform with Rust's Cargo:

cargo install c2patool

You can also download prebuilt binaries from the GitHub releases page at github.com/contentauth/c2patool.

Reading a manifest

Point c2patool at any file to get a JSON summary of its C2PA manifests:

c2patool photo.jpg

This prints the active manifest's claim, assertions, and validation status to stdout. If the file has no C2PA data, c2patool returns an error.

Getting detailed output

For the full JUMBF-level data including all nested structures:

c2patool photo.jpg --detailed

Saving the manifest to a directory

To extract the manifest, any embedded thumbnails, and ingredient data to files on disk:

c2patool photo.jpg --output ./manifest-report

This creates a directory with the manifest JSON, thumbnail images, and a binary .c2pa file containing the raw manifest store.

Extracting certificates

To inspect the signing certificate chain:

c2patool photo.jpg --certs

This outputs the PEM-encoded certificates used to sign the manifest, which you can then verify against known certificate authorities.

Viewing the manifest tree

For a quick structural overview:

c2patool photo.jpg --tree

This prints a text tree showing assertions, ingredients, and their relationships without the full JSON detail.

A practical example

Here is what the output looks like when you run c2patool on an image exported from Adobe Photoshop with Content Credentials enabled:

{
  "active_manifest": {
    "claim_generator": "Adobe Photoshop 26.0",
    "title": "landscape-edit.jpg",
    "format": "image/jpeg",
    "claim_generator_info": [{
      "name": "Adobe Photoshop",
      "version": "26.0"
    }],
    "assertions": [{
      "label": "c2pa.actions",
      "data": {
        "actions": [
          { "action": "c2pa.opened" },
          { "action": "c2pa.color_adjustments" },
          { "action": "c2pa.exported" }
        ]
      }
    }],
    "signature_info": {
      "issuer": "Adobe Inc.",
      "cert_serial_number": "0a3f..."
    }
  },
  "validation_status": []
}

An empty validation_status array means the signature is valid and the content has not been tampered with. If validation fails, this array contains error codes explaining what broke.

Hierarchical data structure showing nested relationships

Reading C2PA Manifests with the JavaScript SDK

For applications that need to verify content credentials at scale or in a web context, the C2PA JavaScript libraries let you read manifests programmatically.

Server-side with c2pa-node

The @contentauth/c2pa-node package provides Node.js bindings to the C2PA Rust SDK:

npm install @contentauth/c2pa-node

Reading a manifest from a file:

import { createC2pa } from '@contentauth/c2pa-node';
import { readFile } from 'node:fs/promises';

const c2pa = createC2pa();

async function readManifest(filePath, mimeType) {
  const buffer = await readFile(filePath);
  const result = await c2pa.read({ buffer, mimeType });

if (!result) {
    console.log('No C2PA manifest found');
    return null;
  }

const { active_manifest, manifests, validation_status } = result;

console.log('Creator:', active_manifest.claim_generator);
  console.log('Actions:', active_manifest.assertions);
  console.log('Valid:', validation_status.length === 0);

return result;
}

await readManifest('./photo.jpg', 'image/jpeg');

The active_manifest contains the most recent claim in the provenance chain. The manifests object holds all claims, including those from earlier stages like the original camera capture and intermediate edits. The validation_status array is empty when all signature checks pass.

Browser-side with c2pa-js

For client-side verification, the @contentauth/c2pa package runs entirely in the browser using WebAssembly:

import { createC2pa } from '@contentauth/c2pa';

const c2pa = await createC2pa({
  wasmSrc: '/path/to/toolkit_bg.wasm',
  workerSrc: '/path/to/c2pa.worker.min.js'
});

const result = await c2pa.read(imageBlob);

This approach keeps files local. No server upload is required, which matters for privacy-sensitive verification workflows where you cannot send assets to a third-party service.

TypeScript alternative

The @trustnxt/c2pa-ts package is a pure TypeScript implementation that handles manifest reading, validation, and creation without native Rust dependencies. It is useful when you need a lighter deployment footprint or want to avoid compiling native bindings for your target platform.

Fastio features

Track content provenance across your media library

Fast.io workspaces include Metadata Views that extract structured fields from documents, images, and media into a queryable grid. Describe the data you need in plain English. Versioned storage, audit trails, and Intelligence Mode included. 50GB free, no credit card required.

How C2PA Verification Works

Understanding the verification process helps you interpret what c2patool and the SDKs are actually checking when they validate a manifest.

Step 1: Hash verification. C2PA binds a manifest to its asset using a SHA-256 hash. The verifier computes the hash of the current file bytes and compares it to the hash stored in the manifest. If even one byte has changed since signing, the hashes will not match and verification fails.

Step 2: Signature validation. The manifest is signed with a certificate issued by a trusted certificate authority (CA). Verification checks three things: that the signature is mathematically valid, that the signing certificate was issued by a recognized CA, and that the certificate has not been revoked.

Production C2PA certificates come from authorities like DigiCert, GlobalSign, and Entrust. Self-signed certificates work for development and testing, but production deployments need a certificate from a CA on the C2PA trust list. Annual costs for production certificates range from roughly $50 to $500 depending on the provider.

Step 3: Trust list matching. The C2PA standard maintains trust lists that define which certificate authorities are recognized signers. When c2patool runs with trust configuration enabled, it checks the signing certificate against these lists:

c2patool photo.jpg trust --allowed_list ./trusted-certs.pem

A valid signature from an unrecognized CA produces a warning rather than a hard failure. This lets organizations maintain their own trust boundaries while still reading manifests signed by other parties.

Step 4: Provenance chain validation. If the manifest references ingredients (source files that were combined or edited to produce the current asset), the verifier checks each ingredient's manifest recursively. This creates a provenance chain from the final output back to the original captures.

For AI-generated content, the chain typically starts with a single manifest from the generation tool. The digitalSourceType assertion will be set to trainedAlgorithmicMedia (fully AI-generated) or compositeWithTrainedAlgorithmicMedia (mixed human and AI content). OpenAI's ChatGPT image generation, Adobe Firefly, and Google's Imagen all embed these markers when C2PA signing is enabled.

What validation status codes mean

When verification fails, the validation_status array contains specific error codes:

  • signingCredential.untrusted: The certificate is not on a recognized trust list
  • assertion.hashedURI.mismatch: The content has been modified since signing
  • timeStamp.mismatch: The timestamp signature is invalid or expired
  • manifest.inaccessible: A referenced ingredient manifest cannot be found

An empty array means all checks passed. In production systems, you will want to log these codes and route files with validation failures to a manual review queue.

How C2PA Differs from EXIF Metadata

Photographers and media teams often ask how C2PA compares to the EXIF metadata they already work with. The two solve different problems.

EXIF is descriptive metadata. It records technical details about how a photo was captured: camera model, lens, shutter speed, aperture, GPS coordinates, and timestamps. It has been around since 1995 and virtually every camera and image editor reads and writes it.

The problem with EXIF is that anyone can edit it. Tools like ExifTool let you rewrite any field, and most image editors strip or modify EXIF data during export. There is no way to tell whether EXIF data has been tampered with after the fact.

C2PA solves this with cryptographic binding. The manifest is signed with a certificate from a trusted authority, and the signature covers both the manifest data and a hash of the file contents. Change the file, and the signature breaks. Change the manifest, and the signature breaks. There is no way to silently modify C2PA data without detection.

Here is a practical comparison across the dimensions that matter most:

Authenticity: EXIF tells you what camera settings were used but cannot prove the photo is unaltered. C2PA proves the content has not changed since the manifest was signed.

Edit history: EXIF stores a single snapshot of metadata that gets overwritten at each stage. C2PA records a chain of actions: opened, cropped, color-adjusted, exported. Each step can carry its own signed manifest.

AI disclosure: EXIF has no standard field for AI generation. C2PA includes the digitalSourceType assertion with values like trainedAlgorithmicMedia that explicitly mark AI-generated content.

Interoperability: C2PA can wrap existing metadata standards. EXIF, IPTC, and XMP data can be included as assertions within a C2PA manifest, making them tamper-evident too. C2PA does not replace EXIF. It protects it.

Adoption: EXIF is universal across every camera and editor. C2PA is newer but gaining ground quickly, with support from camera manufacturers (Nikon, Canon, Leica, Sony), software companies (Adobe, Microsoft, Google), and distribution platforms (LinkedIn, BBC).

Building Content Verification into Your File Workflow

Verifying individual files with c2patool is straightforward. The harder problem is building verification into a workflow where hundreds or thousands of media files arrive daily.

Batch verification

For bulk processing, a shell script can iterate over files in a directory:

for file in ./incoming/*.jpg; do
  echo "--- $file ---"
  c2patool "$file" 2>/dev/null || echo "No C2PA data"
done

For structured output, pipe the JSON to jq and extract the fields you care about:

c2patool photo.jpg | jq '{
  creator: .active_manifest.claim_generator,
  valid: (.validation_status | length == 0),
  actions: [.active_manifest.assertions[].data.actions[]?.action]
}'

Integrating verification with file storage

When your team receives media assets through upload portals or file shares, you want verification to happen automatically on arrival. A webhook-driven pipeline works well: the storage platform notifies your verification service when files land, your service runs c2patool or the C2PA SDK, records the results, and flags files that fail verification for manual review.

Fast.io's Metadata Views offer another approach for teams that need structured provenance data alongside their files. Metadata Views let you describe the fields you want extracted from uploaded files in natural language. The AI designs a typed schema and populates a sortable, filterable spreadsheet across every matching file in the workspace. For media teams tracking content provenance, you could create a view that surfaces creation dates, authoring tools, and modification history without building a custom extraction pipeline.

If your workflow needs both verification results and file storage in one place, Fast.io workspaces provide versioned file storage with granular permissions, audit trails that log every access and modification, and Intelligence Mode that auto-indexes files for semantic search. When a verified asset arrives, it becomes immediately searchable by its content and metadata.

Online verification tools

For quick one-off checks, several free tools verify C2PA credentials without any installation:

  • Content Credentials Verify at contentcredentials.org/verify is the official verification tool from the Content Authenticity Initiative
  • C2PA Viewer at c2paviewer.com provides drag-and-drop verification with raw manifest inspection
  • Digimarc browser extension verifies C2PA credentials on images as you browse the web in Chrome, Edge, or Brave

All three run verification client-side, so your files are not uploaded to a remote server during the check.

AI-powered document analysis and audit summary interface

Frequently Asked Questions

How do I check if an image has C2PA Content Credentials?

The quickest method is to drag the image into contentcredentials.org/verify or c2paviewer.com. Both run verification in your browser without uploading the file. For command-line checks, install c2patool and run "c2patool photo.jpg" to see the manifest JSON. If no C2PA data is present, the tool returns an error message.

What tools can extract C2PA metadata?

c2patool is the official CLI from the Content Authenticity team. For JavaScript applications, use @contentauth/c2pa-node on the server or @contentauth/c2pa in the browser via WebAssembly. The @trustnxt/c2pa-ts package offers a pure TypeScript alternative. For non-technical users, the Content Credentials Verify website and the Digimarc browser extension both extract and display C2PA data visually.

Can C2PA detect AI-generated images?

C2PA does not analyze pixels to detect AI generation. Instead, it records what the creating tool declares. When AI tools that support C2PA (like Adobe Firefly, ChatGPT image generation, or Google Imagen) create an image, they embed a digitalSourceType assertion set to trainedAlgorithmicMedia or compositeWithTrainedAlgorithmicMedia. If the AI tool does not embed C2PA manifests, or if someone strips the manifest after generation, C2PA cannot identify the image as AI-made.

How does C2PA differ from EXIF metadata?

EXIF records descriptive data like camera settings and GPS coordinates, but anyone can edit or strip it without detection. C2PA manifests are cryptographically signed and hash-bound to the file content. Any modification to the file or the manifest invalidates the signature. C2PA can also wrap EXIF, IPTC, and XMP data as assertions within the signed manifest, making traditional metadata tamper-evident.

What file formats support C2PA Content Credentials?

c2patool currently supports JPEG, PNG, WebP, TIFF, HEIC, AVIF, DNG, MP4, MOV, MP3, WAV, and PDF. The most common use cases are JPEG and PNG images with embedded manifests, but video support through MP4 and MOV is increasingly important as platforms adopt C2PA for video provenance.

Do I need special software to add C2PA manifests to my files?

For individual files, Adobe Photoshop and Lightroom include built-in C2PA support, and cameras from Nikon, Leica, and Sony can sign photos at capture time. For programmatic signing, c2patool accepts a manifest definition JSON and a signing certificate. Self-signed certificates work for testing, but production use requires a certificate from a trusted CA like DigiCert or GlobalSign, typically costing $50 to $500 per year.

Related Resources

Fastio features

Track content provenance across your media library

Fast.io workspaces include Metadata Views that extract structured fields from documents, images, and media into a queryable grid. Describe the data you need in plain English. Versioned storage, audit trails, and Intelligence Mode included. 50GB free, no credit card required.