Skip to content
c2pa

go · no cgo · content credentials

C2PA provenance, pure Go.

Read and validate C2PA / Content Credentials manifests in JPEG and PNG — a fast, best-effort claim reader for triage, plus a full cryptographic verifier — with no c2pa-rs and no cgo.

MIT licensed · pure-Go crypto/CBOR/COSE · Go 1.25+

read.go
info := c2pa.Read(ctx, c2pa.JPEG, f) // or c2pa.PNG
if info.Present {
    fmt.Println(info.ClaimGenerator) // "Adobe Firefly"
    fmt.Println(info.AIGenerated)    // declared AI-generated?
    fmt.Println(info.SignedBy)       // claimed signer (unverified)
}

what you get

Two modes, one pure-Go library.

A fast reader that surfaces what a file claims, and a full verifier that proves it — the complete C2PA validation algorithm, no c2pa-rs and no cgo.

Pure Go, no cgo

No c2pa-rs dependency and no cgo — pure-Go crypto, CBOR, and COSE all the way down, so it cross-compiles and vendors like any other Go package.

Read for triage

Fast, best-effort, never-errors surfacing of what a file claims: creating tool, title, format, AI-generated flag, claimed signer, and signing time.

Validate in full

The complete C2PA validation algorithm, executed in pure Go, reporting per-step C2PA status codes — success, informational, and failure — for every check.

Signatures & chains

Verifies COSE signatures (ES256/384/512, PS256/384/512, EdDSA), the certificate chain against the C2PA profile, and assertion plus hard-binding hashes.

Timestamps & revocation

RFC 3161 timestamp verification, opt-in OCSP/CRL revocation, and recursive ingredient validation with cycle detection for nested manifests.

Batteries included

Official C2PA conformance trust lists embedded in the binary, overridable anchors, and tunable options — for both JPEG and PNG.

usage

Triage fast, or verify in full.

Read tells you what a file claims — accurate-as-recorded, not proven. Validate runs the whole algorithm and reports C2PA status codes you can trust.

// Read — fast, unverified triage
info := c2pa.Read(ctx, c2pa.JPEG, f)
if info.Present {
    fmt.Println(info.ClaimGenerator) // tool
    fmt.Println(info.AIGenerated)    // AI?
    fmt.Println(info.SignedBy)       // claimed
}
// Validate — full cryptographic proof
res, err := c2pa.Validate(ctx, c2pa.JPEG, f, opts)
if res.Valid {
    fmt.Println("verified, signed at", res.SignedAt)
}
for _, s := range res.Status {
    fmt.Println(s.Code, s.Severity) // C2PA codes
}
  • claimSignature.validated
  • signingCredential.trusted
  • assertion.dataHash.match
  • timeStamp.validated
  • signingCredential.untrusted
  • assertion.dataHash.mismatch

install

Add it to your module.

Pure-Go dependencies only, no cgo. Requires Go 1.25+.

go get go get github.com/richardwooding/c2pa
import import "github.com/richardwooding/c2pa"

Requires Go 1.25+. Full API docs on pkg.go.dev.