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+
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 github.com/richardwooding/c2pa
import "github.com/richardwooding/c2pa"
Requires Go 1.25+. Full API docs on pkg.go.dev.