C2PA Image Signer
Sign your ComfyUI images so nobody can scrub your name off them
- image
- signed_image
This node stamps an invisible, tamper-proof "I made this" onto your images. You feed it a finished picture, it embeds a C2PA manifest into the file, and saves the signed copy to your output folder. Anyone can then check that signature to confirm the image is genuinely yours, that it hasn't been edited since you signed it, and - if you want - what model and prompt made it.
C2PA is the Content Credentials standard backed by Adobe, BBC, and Microsoft. The name is a lie in the best possible way: it doesn't call any API and needs no key. Everything happens locally, offline, via a binary called c2patool that the node shells out to.
Why you'd bother
For AI art, provenance is the whole game. The same EU rules that are forcing synthetic-media labeling (think Article 50 transparency) are nudging platforms toward checking this stuff, and tools like Photoshop already surface C2PA credentials in the corner of your screen. If you share images publicly, signing them means the "is this real?" answer points back at you instead of vanishing into the void.
It's worth being clear about what you get though: C2PA is provenance, not protection. Anyone can crop, re-encode, or screenshot the signature away. What it does is make it trivial to prove authorship at signing time - and honest to detect when it's gone.
How it works
The node is a thin wrapper around c2patool from the contentauth/c2pa-rs project. For each image in your batch it:
- Saves your tensor to a temp PNG,
- writes a manifest JSON containing your private key path, cert path, and
alg: es256, - runs
c2patool input.png -m manifest.json -o output.png -f, - copies the signed file into
ComfyUI/output/.
Batch signing just loops that per image, appending _batch000, _batch001 to filenames. Under the hood it sets C2PATOOL_ALLOWED_LIST to your cert so the built-in self-signed test certs validate.
The inputs that matter
- private_key_path and cert_path - full paths to your key and cert. Use forward slashes (
C:/ComfyUI/custom_nodes/...), backslashes won't parse. - filename_prefix - default
C2PA_signed; you getC2PA_signed_20261006_094628.png. - manifest_json - optional, advanced. Extra assertions to embed: your name as author, the model used, a "Do Not Train" claim, whatever. Start with
{}. - workflow_json + include_workflow_metadata - optionally embed your whole exported workflow so verifiers can see exactly how the image was made. Leave disabled unless you mean it; your prompt and file paths ride along in that JSON.
The single output, signed_image, is the same tensor you put in - the real artifact is the file it saved for you.
Installing it
Two parts. First the node itself, via ComfyUI Manager (search "C2PA Image Signer") or:
cd ComfyUI/custom_nodes
git clone https://github.com/mikecaronna/comfyui_c2pa_signer
Then the actual dependency: c2patool is not a pip package - there's no requirements.txt to run. You download the binary from the c2pa-rs releases page, extract it, and put its folder on your PATH (Windows: Environment Variables → Path). Test with c2patool --version, then restart ComfyUI. That PATH step is where most people get stuck.
Gotchas
- Don't put a Save Image node after this. ComfyUI re-encodes the pixels and strips the manifest. The signer already saves the file - let it.
- The test certs are public. The repo ships (well, claims to ship) standard es256 test certs from the c2patool project. Everyone on earth has these, so they prove "someone signed this," not "you did." Great for learning, wrong for claiming authorship. Note
keys/is gitignored, so a fresh clone may not actually contain them - if yours is empty, grab the es256 test pair from the c2pa-rs test fixtures. - "c2patool not found" means the binary isn't on PATH. Restart ComfyUI after fixing it.
For real-world use you'd get a proper certificate from a CA - the mechanics are identical, you just point the node at your own key and cert.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| private_key_path | STRING | — | |
| cert_path | STRING | — | |
| filename_prefix | STRING | C2PA_signed | — |
| manifest_jsonopt | STRING | {} | — |
| workflow_jsonopt | STRING | — | |
| include_workflow_metadataopt | COMBO | disable | 2 options: enable, disable |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| signed_image | IMAGE | — |