Skip to main content

c2pa-ml

C2PA manifest embedding for AI/ML model container formats: GGUF, SafeTensors, and ONNX

crates.io docs.rs License

Overview

Associates a C2PA Manifest Store with an AI/ML model by writing it into the model container's own metadata slot, so the model stays loadable by its usual runtime. Three formats are supported:

Format Metadata slot Manifest encoding Specified?
ONNX protobuf metadata_props c2pa:manifest as Base64 yes
SafeTensors JSON header __metadata__ c2pa:manifest as Base64 yes
GGUF (llama.cpp) typed key/value metadata c2pa:manifest as a UINT8 array (raw bytes) no

ONNX and SafeTensors each have a normative clause in the C2PA Technical Specification, including the c2pa:manifest key, the hard binding, and a per-format multipleManifests failure code. This crate implements them as written.

GGUF has no specified embedding method. It is supported here as a crate extension, following the same shape so a dispatcher can treat all three alike — but there is no specified exclusion range for it, so binding::manifest_exclusion declines to invent one and returns UnknownFormat. Embedding and reading work; only the hard binding is unavailable.

A remote (or side-car) manifest can instead be referenced by URI under c2pa:manifest.uri, or both an embedded store and a URI can be written together. The specification defines no remote-URI key for these formats, so that too is a crate extension, namespaced to match.

A manifest embedded in a model should also declare what the asset is with the asset type assertion; this crate provides the canonical c2pa.types.model.* strings for that.

Zero dependencies on native targets; the WebAssembly/npm build uses only wasm-bindgen.

Quick Start

[dependencies]
c2pa-ml = "0.1"

Embed a manifest

use c2pa_ml::{embed_manifest, ManifestSource};

let model: &[u8] = /* .gguf / .safetensors / .onnx bytes */;
let store: Vec<u8> = /* C2PA Manifest Store bytes */;

// Embed a Manifest Store directly (format is auto-detected)...
let signed = embed_manifest(model, &ManifestSource::embedded(store)).unwrap();

// ...or reference a remote manifest by URI...
let signed = embed_manifest(model, &ManifestSource::remote("https://example.com/m.c2pa")).unwrap();

// ...or both.
let signed = embed_manifest(model, &ManifestSource::both("https://example.com/m.c2pa", vec![/* ... */])).unwrap();

Read a manifest

use c2pa_ml::{read_manifest, read_manifest_uri};

let store = read_manifest(&signed).unwrap();          // embedded Manifest Store bytes
let uri = read_manifest_uri(&signed).unwrap();        // Option<String>: active manifest URI

Verify presence

use c2pa_ml::verify;

let report = verify(&signed).unwrap();
assert!(report.is_compliant());
// report.format, report.has_embedded_manifest, report.has_remote_uri

Declare the asset type

use c2pa_ml::Format;

let model_type = Format::detect(&signed).unwrap().model_type();
assert_eq!(model_type.as_str(), "c2pa.types.model.onnx"); // for an ONNX model

Explicit format

ONNX has no magic number, so auto-detection matches it last as a best-effort protobuf shape check. When the format is known in advance, use embed_manifest_as, or call the per-format module (gguf, safetensors, onnx) directly.

use c2pa_ml::{embed_manifest_as, Format, ManifestSource};

let signed = embed_manifest_as(model, Format::Onnx, &ManifestSource::embedded(store)).unwrap();

Other languages

The same API is published for JavaScript and Python from this crate, so it also serves Node, pnpm, and browser/bundler users.

npm / pnpm (WebAssembly)

npm install c2pa-ml   # or: pnpm add c2pa-ml
import { embedManifest, readManifest, detectFormat } from "c2pa-ml";

const signed = embedManifest(model, store); // Uint8Array in, Uint8Array out
const manifest = readManifest(signed);

PyPI

pip install c2pa-ml
import c2pa_ml

signed = c2pa_ml.embed_manifest(model, store)  # bytes in, bytes out
manifest = c2pa_ml.read_manifest(signed)
fmt = c2pa_ml.detect_format(model)             # "GGUF" | "SafeTensors" | "ONNX" | None

Design

  • The Manifest Store and/or manifest URI are stored under the reserved keys c2pa:manifest / c2pa:manifest.uri in the format's native metadata slot
  • GGUF: metadata is re-serialized and the tensor-data region is re-padded to general.alignment; tensor-info offsets are relative to that region, so tensor data is never rewritten
  • SafeTensors: only the JSON header is rewritten; each tensor's data_offsets are relative to the data block and stay valid
  • ONNX: only the top-level protobuf field stream is rewritten; every other field (ir_version, graph, opset_import, …) is copied through verbatim
  • Embedding replaces any existing C2PA entries; remove_manifest restores the model to its unembedded bytes

Scope

This crate implements embedding and extraction only. Manifest construction, signing, and content (hard/soft) binding are out of scope; use the official C2PA SDK to build and sign manifests. The c2pa.hash.data assertion should exclude the metadata region carrying the Manifest Store.

Related Crates

Part of a family of single-purpose crates, one per C2PA embedding method. Each is standalone and independently versioned.

Crate Description
c2pa-structured-text Structured text: ASCII-armoured manifest in a comment or front matter
c2pa-unstructured-text Unstructured text: invisible Unicode variation-selector run
c2pa-html HTML: script and link elements in the document head
c2pa-http HTTP: the c2pa-manifest Link header, with a Tower middleware
c2pa-text-binding Soft binding and content fingerprinting for text assets
c2pa-vtt WebVTT caption and subtitle embedding
c2pa-zip ZIP-based documents: EPUB, DOCX, ODT, OXPS
c2pa-warc WARC web archive embedding (ISO 28500)
c2pa-fonts OpenType/TrueType (SFNT) font embedding
c2pa Official C2PA SDK

Security

Found a vulnerability? Please report it privately — see SECURITY.md.

License

Licensed under either of Apache License, Version 2.0 or MIT License at your option.

Built by WritersLogic

Metadata

Release files for c2pa-ml 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for c2pa-ml 0.2.0
File Size Uploaded
c2pa_ml-0.2.0.tar.gz 52.7 kB Details

Built distributions (wheels)

Table of built distributions (wheels) for c2pa-ml 0.2.0
File
c2pa_ml-0.2.0-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details
c2pa_ml-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details
c2pa_ml-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details
c2pa_ml-0.2.0-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details
c2pa_ml-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl CPython 3.9 abi3 macOS 10.12+ x86-64 Details

Total release size: 1.2 MB

Release files / c2pa_ml-0.2.0.tar.gz

Download URL c2pa_ml-0.2.0.tar.gz
Size 52.7 kB
Tags Source
SHA-256 checksum
How to use checksums
f468cc1c31bf24b73945d186e45c9c6a495313256daeecec0193a2b65d32831c
BLAKE2b-256 checksum
How to use checksums
0ac0369809a06dd8aabd850608a2a51024926d20d84d6bbece91d197c47c92be
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 3, 2026.

Transparency log

Release files / c2pa_ml-0.2.0-cp39-abi3-win_amd64.whl

Download URL c2pa_ml-0.2.0-cp39-abi3-win_amd64.whl
Size 136.3 kB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
a557fc4a4b940dffb151fa3aecf8d1029225fc82fb050aad427fcb62da62e070
BLAKE2b-256 checksum
How to use checksums
6705290984a824328a2e39478094d78b8ffba4f2567a5d00850f67457563b85a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 3, 2026.

Transparency log

Release files / c2pa_ml-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL c2pa_ml-0.2.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 270.4 kB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
641e0e29d249b927dabe23c8feb83a8203fbb1bd3aa7b33a16539ed3e6d4fe45
BLAKE2b-256 checksum
How to use checksums
1b6634c92446657e8effb48224a53db3553dfb8ccb9a1339c8ffa5dcb47f5433
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 3, 2026.

Transparency log

Release files / c2pa_ml-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL c2pa_ml-0.2.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 267.0 kB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
26cfce28faab5ea9d10d8d2284703cb2a75c4ac480720690e528dc38251c8167
BLAKE2b-256 checksum
How to use checksums
722cdecf0760ff92825086955081c42835b6bbed95ab6ed2b37b7af35a1b69f9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 3, 2026.

Transparency log

Release files / c2pa_ml-0.2.0-cp39-abi3-macosx_11_0_arm64.whl

Download URL c2pa_ml-0.2.0-cp39-abi3-macosx_11_0_arm64.whl
Size 238.5 kB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
d64d61e8014acbd6e00b5262c774c259d90528067f402e3307a96efd997df2ef
BLAKE2b-256 checksum
How to use checksums
7b08286c05155ff78092a36a3be20abeb789a0771150bbb316dce6e173c30c54
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 3, 2026.

Transparency log

Release files / c2pa_ml-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl

Download URL c2pa_ml-0.2.0-cp39-abi3-macosx_10_12_x86_64.whl
Size 241.0 kB
Tags CPython 3.9 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
ca90ff8e21223f18ce48a26a5c557e8f9206bb26e924bb974fe394f3549a94b3
BLAKE2b-256 checksum
How to use checksums
b8944e0f48f9e7357bf945567917adb7f1e10ac87e2c73b8c3a94c69e6f98e4e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

6 release files

0.1.0

6 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page