c2pa-check 0.1.6 → 0.2.0
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 +84 -6
- package/bin/c2pa-check.js +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -26,10 +26,43 @@ c2pa-check photo.jpg --format json | jq .result.credential.status
|
|
|
26
26
|
c2pa-check inspect photo.jpg # manifest tree
|
|
27
27
|
c2pa-check trust status # which list judged it
|
|
28
28
|
c2pa-check mcp # stdio MCP server
|
|
29
|
+
c2pa-check 'dist/**/*.jpg' --format junit --output c2pa-check.xml # report to a file
|
|
30
|
+
c2pa-check doctor # key, quota, network, webhook secret, Node
|
|
29
31
|
```
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
`
|
|
33
|
+
`--format text|json|ndjson|junit` (default `text`) and `--output PATH` (default: stdout) apply
|
|
34
|
+
to the check command. JUnit marks every target that is not `valid_trusted` as a failure.
|
|
35
|
+
|
|
36
|
+
| Exit | Meaning |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `0` | pass |
|
|
39
|
+
| `1` | expectation or coverage failed · `doctor` found a failing check · `carry --strict` found an unpaired file |
|
|
40
|
+
| `2` | usage or I/O error |
|
|
41
|
+
| `3` | unreadable asset (missing or unreadable local file, over 64 MiB, malformed manifest) |
|
|
42
|
+
| `4` | a URL could not be fetched |
|
|
43
|
+
| `5` | `carry` refused (rule in `--json`) |
|
|
44
|
+
|
|
45
|
+
## Check your setup
|
|
46
|
+
|
|
47
|
+
```console
|
|
48
|
+
$ npx -y c2pa-check doctor
|
|
49
|
+
ok api_key live key c2pa_live_AbC…
|
|
50
|
+
ok network https://api.c2pa.design/v1 answered HTTP 200
|
|
51
|
+
ok whoami live key, organization Acme, plan team, signatures 940 of 1000 left until 2026-11-01
|
|
52
|
+
ok webhook_secret valid (whsec_ + base64)
|
|
53
|
+
ok node Node.js 22.11.0
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
| Check | Reads | Fails when |
|
|
57
|
+
|---|---|---|
|
|
58
|
+
| `api_key` | `C2PA_API_KEY` (deprecated fallback `C2PA_DESIGN_API_KEY`) | not `c2pa_live_` / `c2pa_test_` + 32 letters and digits (unset is a warning) |
|
|
59
|
+
| `network` | `C2PA_API_BASE` (deprecated fallback `C2PA_DESIGN_API_URL`, default `https://api.c2pa.design/v1`) | no HTTP answer |
|
|
60
|
+
| `whoami` | `GET {C2PA_API_BASE}/whoami` | the key is refused; an exhausted quota is a warning |
|
|
61
|
+
| `webhook_secret` | `C2PA_WEBHOOK_SECRET` | not `whsec_` + standard base64 (unset is skipped) |
|
|
62
|
+
| `node` | the Node.js running `npx` | older than 18 |
|
|
63
|
+
|
|
64
|
+
`doctor --json` prints `{ok, api_base, checks: [{name, state, detail, data?}]}` with `state`
|
|
65
|
+
`ok | warn | fail | skip`; the `whoami` check carries the API answer in `data`.
|
|
33
66
|
|
|
34
67
|
## In CI
|
|
35
68
|
|
|
@@ -39,8 +72,21 @@ Exit codes: `0` pass · `1` expectation or coverage failed · `2` usage · `3` u
|
|
|
39
72
|
paths: "public/**/*.{jpg,png,webp}"
|
|
40
73
|
coverage: 100
|
|
41
74
|
format: junit
|
|
75
|
+
output: c2pa-check.xml
|
|
42
76
|
```
|
|
43
77
|
|
|
78
|
+
The action installs the release named by `version` (default `v0.2.0`) and checks it against the
|
|
79
|
+
release's `SHA256SUMS` before running it. Every release publishes `SHA256SUMS` and a GitHub
|
|
80
|
+
build-provenance attestation (`gh attestation verify c2pa-check-<target>.tar.gz -R
|
|
81
|
+
c2pa-design/c2pa-check`); the npm packages are published with npm provenance
|
|
82
|
+
(`npm audit signatures`).
|
|
83
|
+
|
|
84
|
+
Outside GitHub Actions, any image with Node.js 18+ runs `npx -y c2pa-check@0.2.0`
|
|
85
|
+
(`node:22-bookworm-slim` is the smallest that also has the glibc tools most pipelines expect;
|
|
86
|
+
the binary itself is static musl, so `node:22-alpine` works too). Pin the version so `npx` hits
|
|
87
|
+
its cache instead of resolving `latest` on every run, and cache `~/.npm` between jobs; or skip
|
|
88
|
+
Node entirely and download the static binary from the release.
|
|
89
|
+
|
|
44
90
|
Add `urls:` to check what your CDN actually serves after a deploy — that is where credentials
|
|
45
91
|
usually disappear.
|
|
46
92
|
|
|
@@ -56,19 +102,50 @@ npx -y c2pa-check carry --from hero.png --to hero.webp # one pair, in
|
|
|
56
102
|
npx -y c2pa-check carry 'public/**/*.{webp,avif}' --from-dir src/ # pairs by file name
|
|
57
103
|
c2pa-check carry --from clip.mov --to clip.mp4 --force # non-picture media
|
|
58
104
|
c2pa-check keygen --out-dir .c2pa # cert.pem + key.pem for CI
|
|
105
|
+
c2pa-check carry --from hero.png --to hero.webp --json # machine-readable result
|
|
59
106
|
```
|
|
60
107
|
|
|
61
108
|
| Signer (first that is set) | Signed as | Verifies as |
|
|
62
109
|
|---|---|---|
|
|
63
110
|
| `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
|
-
| `
|
|
111
|
+
| `C2PA_API_KEY` (deprecated fallback `C2PA_DESIGN_API_KEY`) | "<your verified domain> via c2pa.design" | `valid_untrusted` |
|
|
65
112
|
| nothing | a local key in `~/.config/c2pa-check/identity` | `valid_untrusted` |
|
|
66
113
|
|
|
67
|
-
Pictures are compared first
|
|
68
|
-
credential is refused with exit `
|
|
114
|
+
Pictures are compared first by perceptual hash; a different picture or an original without a
|
|
115
|
+
credential is refused with exit `5`. With an API key, c2pa.design checks the carry again and
|
|
69
116
|
signs only an honest one; if hosted signing is unavailable, `carry` signs locally and warns.
|
|
70
117
|
Never `COPY` or `ARG` a key into a Docker image: use `RUN --mount=type=secret`.
|
|
71
118
|
|
|
119
|
+
`carry --json` prints one object (an array for several files):
|
|
120
|
+
|
|
121
|
+
```json
|
|
122
|
+
{"status": "refused", "rule": "different_picture", "message": "the two files are not the same picture",
|
|
123
|
+
"source": "hero.png", "derived": "hero.webp"}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
`status` is `carried | composed | skipped | refused | error | unpaired | ambiguous`; `output`
|
|
127
|
+
is the file written; `credential_status` is how the written file verifies. `rule` is set on a
|
|
128
|
+
refusal: `different_picture`, `source_unsigned`, `low_quality`, `not_comparable`, or the rule
|
|
129
|
+
c2pa.design returned with `carry_rejected` (`source_invalid`, `ingredient_mismatch`,
|
|
130
|
+
`action_not_allowed`, `generator_changed`, `certificate_mismatch`, …). Refusals exit `5`.
|
|
131
|
+
|
|
132
|
+
### Composites and generated assets
|
|
133
|
+
|
|
134
|
+
An atlas, sprite sheet or collage is a new work, not a conversion. `--compose` signs the
|
|
135
|
+
rendered file with every source attached as a `componentOf` ingredient (each keeps its own
|
|
136
|
+
manifest) and a `c2pa.created` action (digital source type `composite`), plus `c2pa.placed`
|
|
137
|
+
per source:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
c2pa-check carry --compose a.png b.png c.png --to atlas.webp
|
|
141
|
+
c2pa-check carry --compose base.png logo.png --to banner.webp --edited # base.png is parentOf
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`--edited` records `c2pa.opened` on the first source (as `parentOf`), `c2pa.edited`, and
|
|
145
|
+
`c2pa.placed` for the rest. Composites are signed with `C2PA_SIGN_CERT` / `C2PA_SIGN_KEY` or
|
|
146
|
+
the local key; hosted signing does not accept composites yet, so with only an API key the
|
|
147
|
+
composite is signed locally and `carry` warns.
|
|
148
|
+
|
|
72
149
|
## For AI agents
|
|
73
150
|
|
|
74
151
|
The agent skill lives in [c2pa-design/skills](https://github.com/c2pa-design/skills):
|
|
@@ -77,7 +154,8 @@ The agent skill lives in [c2pa-design/skills](https://github.com/c2pa-design/ski
|
|
|
77
154
|
npx skills add c2pa-design/skills
|
|
78
155
|
```
|
|
79
156
|
|
|
80
|
-
MCP only: `claude mcp add c2pa-check -- npx -y c2pa-check mcp`.
|
|
157
|
+
MCP only: `claude mcp add c2pa-check -- npx -y c2pa-check mcp`. `initialize` echoes the client's
|
|
158
|
+
`protocolVersion` when supported (`2026-07-28`, `2025-11-25`, `2025-06-18`, `2025-03-26`), else `2026-07-28`.
|
|
81
159
|
|
|
82
160
|
## How trust works
|
|
83
161
|
|
package/bin/c2pa-check.js
CHANGED
|
@@ -10,6 +10,6 @@ try {
|
|
|
10
10
|
console.error(`c2pa-check: no prebuilt binary for ${process.platform}-${process.arch}; use cargo install c2pa-check`);
|
|
11
11
|
process.exit(2);
|
|
12
12
|
}
|
|
13
|
-
const r = spawnSync(bin, process.argv.slice(2), { stdio: "inherit" });
|
|
13
|
+
const r = spawnSync(bin, process.argv.slice(2), { stdio: "inherit", env: { ...process.env, C2PA_CHECK_NODE_VERSION: process.versions.node } });
|
|
14
14
|
if (r.error) throw r.error;
|
|
15
15
|
process.exit(r.status ?? 1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "c2pa-check",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"license": "MIT OR Apache-2.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"node": ">=18"
|
|
19
19
|
},
|
|
20
20
|
"optionalDependencies": {
|
|
21
|
-
"c2pa-check-linux-x64": "0.
|
|
22
|
-
"c2pa-check-linux-arm64": "0.
|
|
23
|
-
"c2pa-check-darwin-arm64": "0.
|
|
24
|
-
"c2pa-check-darwin-x64": "0.
|
|
21
|
+
"c2pa-check-linux-x64": "0.2.0",
|
|
22
|
+
"c2pa-check-linux-arm64": "0.2.0",
|
|
23
|
+
"c2pa-check-darwin-arm64": "0.2.0",
|
|
24
|
+
"c2pa-check-darwin-x64": "0.2.0"
|
|
25
25
|
}
|
|
26
26
|
}
|