c2pa-check 0.0.0-stage → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -2
- package/bin/c2pa-check.js +15 -0
- package/package.json +23 -3
package/README.md
CHANGED
|
@@ -1,3 +1,111 @@
|
|
|
1
|
-
#
|
|
1
|
+
# c2pa-check
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Verify Content Credentials (C2PA) in files and URLs, and fail a build when provenance disappears.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
brew install c2pa-design/tap/c2pa-check # macOS / Linux
|
|
7
|
+
npx c2pa-check photo.jpg # no install
|
|
8
|
+
cargo install c2pa-check # from source
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```console
|
|
12
|
+
$ c2pa-check image.jpg
|
|
13
|
+
image.jpg
|
|
14
|
+
Content Credentials PRESENT
|
|
15
|
+
Manifest VALID
|
|
16
|
+
Trust TRUSTED (2026-08-13-a1b2c3d4e5f6)
|
|
17
|
+
Signer OpenAI Inc. · DigiCert
|
|
18
|
+
Digital source trainedAlgorithmicMedia (AI generated)
|
|
19
|
+
Actions c2pa.created
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
c2pa-check 'dist/**/*.{jpg,png,webp}' --coverage 100 # CI gate
|
|
24
|
+
c2pa-check https://cdn.example.com/hero.jpg --expect trusted
|
|
25
|
+
c2pa-check photo.jpg --format json | jq .result.credential.status
|
|
26
|
+
c2pa-check inspect photo.jpg # manifest tree
|
|
27
|
+
c2pa-check trust status # which list judged it
|
|
28
|
+
c2pa-check mcp # stdio MCP server
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Exit codes: `0` pass · `1` expectation or coverage failed · `2` usage · `3` unreadable asset ·
|
|
32
|
+
`4` network.
|
|
33
|
+
|
|
34
|
+
## In CI
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
- uses: c2pa-design/c2pa-check-action@v1
|
|
38
|
+
with:
|
|
39
|
+
paths: "public/**/*.{jpg,png,webp}"
|
|
40
|
+
coverage: 100
|
|
41
|
+
format: junit
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Add `urls:` to check what your CDN actually serves after a deploy — that is where credentials
|
|
45
|
+
usually disappear.
|
|
46
|
+
|
|
47
|
+
## Keep the credential through conversion
|
|
48
|
+
|
|
49
|
+
Re-encoding, resizing or compressing a file drops its manifest, and copying the old manifest back
|
|
50
|
+
does not help: the signature covers the old bytes. `carry` writes a new manifest into the
|
|
51
|
+
converted copy with the original as its `parentOf` ingredient, so the chain back to the
|
|
52
|
+
generator survives.
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
npx -y c2pa-check carry --from hero.png --to hero.webp # one pair, in place
|
|
56
|
+
npx -y c2pa-check carry 'public/**/*.{webp,avif}' --from-dir src/ # pairs by file name
|
|
57
|
+
c2pa-check carry --from clip.mov --to clip.mp4 --force # non-picture media
|
|
58
|
+
c2pa-check keygen --out-dir .c2pa # cert.pem + key.pem for CI
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
| Signer (first that is set) | Signed as | Verifies as |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `C2PA_SIGN_CERT` + `C2PA_SIGN_KEY` (PEM, a path, or `*_FILE`) | your certificate | `valid_trusted` if your CA is on the C2PA trust list |
|
|
64
|
+
| `C2PA_DESIGN_API_KEY` (or `C2PA_API_KEY`) | "<your verified domain> via c2pa.design" | `valid_untrusted` |
|
|
65
|
+
| nothing | a local key in `~/.config/c2pa-check/identity` | `valid_untrusted` |
|
|
66
|
+
|
|
67
|
+
Pictures are compared first (PDQ distance ≤ 31); a different picture or an original without a
|
|
68
|
+
credential is refused with exit `1`. With an API key, c2pa.design checks the carry again and
|
|
69
|
+
signs only an honest one; if hosted signing is unavailable, `carry` signs locally and warns.
|
|
70
|
+
Never `COPY` or `ARG` a key into a Docker image: use `RUN --mount=type=secret`.
|
|
71
|
+
|
|
72
|
+
## For AI agents
|
|
73
|
+
|
|
74
|
+
The agent skill lives in [c2pa-design/skills](https://github.com/c2pa-design/skills):
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npx skills add c2pa-design/skills
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
MCP only: `claude mcp add c2pa-check -- npx -y c2pa-check mcp`.
|
|
81
|
+
|
|
82
|
+
## How trust works
|
|
83
|
+
|
|
84
|
+
A signature proves the bytes have not changed since signing. It says nothing about *who*
|
|
85
|
+
signed. "Trusted" means the signer's certificate chains to the official
|
|
86
|
+
[C2PA trust list](https://github.com/c2pa-org/conformance-public/tree/main/trust-list), which is
|
|
87
|
+
compiled into every release; `c2pa-check trust status` prints the snapshot date and whether
|
|
88
|
+
upstream has moved, `trust update` fetches a newer one, and `--offline` pins CI to the bundled
|
|
89
|
+
copy. `docs/TRUST.md` has the details.
|
|
90
|
+
|
|
91
|
+
Absence of a credential proves nothing: most files on the internet carry none.
|
|
92
|
+
|
|
93
|
+
## Library
|
|
94
|
+
|
|
95
|
+
`c2pa-check-core` produces the same normalized document (schema v1,
|
|
96
|
+
`crates/c2pa-check-core/schema/result.v1.json`) that the browser tools and the c2pa.design API
|
|
97
|
+
return, so a local check and a hosted check never disagree.
|
|
98
|
+
|
|
99
|
+
```rust
|
|
100
|
+
let bundle = c2pa_check_core::TrustBundle::bundled();
|
|
101
|
+
let report = c2pa_check_core::verify(&bytes, "image/jpeg", &bundle, &Default::default())?;
|
|
102
|
+
println!("{}", report.credential.status.as_str());
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Licence
|
|
106
|
+
|
|
107
|
+
[MIT](LICENSE-MIT) OR [Apache-2.0](LICENSE-APACHE). Contributions under DCO, no CLA.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
Monitor production provenance across your whole pipeline at **[c2pa.design](https://c2pa.design)**.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const { spawnSync } = require("node:child_process");
|
|
3
|
+
|
|
4
|
+
const pkg = `c2pa-check-${process.platform}-${process.arch}`;
|
|
5
|
+
const exe = process.platform === "win32" ? "c2pa-check.exe" : "c2pa-check";
|
|
6
|
+
let bin;
|
|
7
|
+
try {
|
|
8
|
+
bin = require.resolve(`${pkg}/${exe}`);
|
|
9
|
+
} catch {
|
|
10
|
+
console.error(`c2pa-check: no prebuilt binary for ${process.platform}-${process.arch}; use cargo install c2pa-check`);
|
|
11
|
+
process.exit(2);
|
|
12
|
+
}
|
|
13
|
+
const r = spawnSync(bin, process.argv.slice(2), { stdio: "inherit" });
|
|
14
|
+
if (r.error) throw r.error;
|
|
15
|
+
process.exit(r.status ?? 1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "c2pa-check",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.6",
|
|
4
|
+
"license": "MIT OR Apache-2.0",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/c2pa-design/c2pa-check.git"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://c2pa.design",
|
|
10
|
+
"description": "Verify Content Credentials from the command line and fail a build when provenance disappears.",
|
|
11
|
+
"bin": {
|
|
12
|
+
"c2pa-check": "bin/c2pa-check.js"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"bin"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=18"
|
|
19
|
+
},
|
|
20
|
+
"optionalDependencies": {
|
|
21
|
+
"c2pa-check-linux-x64": "0.1.6",
|
|
22
|
+
"c2pa-check-linux-arm64": "0.1.6",
|
|
23
|
+
"c2pa-check-darwin-arm64": "0.1.6",
|
|
24
|
+
"c2pa-check-darwin-x64": "0.1.6"
|
|
25
|
+
}
|
|
6
26
|
}
|