FervorCreative AI
Live Latest 04.09.26 · morning 36 tools tracked 28 workflows indexed 77 topics Hot: MiniMax H3, ComfyUI, LTX-2.5

A provenance node that runs inside ComfyUI can attest the generation graph itself, which no downstream signer can do, but two of its defaults will hand a first-time user an unmarked file or someone else's brand id.

ProvcheckComfyUIC2PATrustMarklicensing-provenancecreative-workflowslocal-creative-aiai-editingopen-weights

Provcheck Signs Your ComfyUI Renders From Inside the Graph. Check Two Settings First.

The free, Apache-2.0 node that watermarks and C2PA-signs images, audio and video with no account and no upload, how to wire it up in about ten minutes, and the two settings that will silently hand you an unmarked file.

Sign a finished render in Photoshop and the signature can honestly say the file passed through Photoshop. Sign it inside ComfyUI, while the graph is still in memory, and the signature can say which model made it, which seed, which sampler, and which prompt.

ComfyUI already writes most of that into PNG metadata on its own, so the facts are not the new part. The new part is that they arrive cryptographically attested by a key you control, which nothing downstream of your render can do for you. That is the whole argument for putting a provenance node in the graph rather than after it, and as of the end of August there is a free one that does it. The node is called "Provcheck (Free C2PA Watermark)," it handles images, audio and video from one node, it runs offline with no account and no upload, and it is Apache 2.0.

It also ships with two defaults that will bite a first-time user, and one of them fails without saying anything. Both take about thirty seconds to fix once you know. So let me walk through what this actually does, then the fix.

Why the graph position matters

C2PA Content Credentials are the open provenance standard behind Adobe, Microsoft, the BBC and most of the camera makers. The idea is straightforward: a cryptographically signed manifest travels with the file, saying who signed it, what produced it, and what happened to it since.

The usual way to attach one is after the fact. You finish a render, you run a signing tool over the file, and the manifest records what that tool could observe, which is a finished file and a timestamp.

A node inside ComfyUI observes something else. It can read the graph that is executing around it. Turn on record_provenance and the manifest carries a curated summary of the generation: model, seed, sampler, prompts. Turn on include_full_workflow and it embeds the whole redacted graph. The maintainers were careful here in a way I appreciate: secrets like api_key and token get dropped, and file paths get shortened to basenames, even with the full workflow switched on. So the record does not leak your directory structure or your keys back out into a file you are about to publish.

include_full_workflow defaults to off, which is the right call. Your prompts are often the work.

There is a second half to this. The signature can be bound to an atproto identity, which in practice means your Bluesky handle. You mint a key locally, publish its fingerprint to your DID, and anyone verifying the file downstream can cross-check that the certificate on it is one you actually published. The private key never leaves your machine. Nothing gets uploaded for verification either, because the verifier runs offline.

Two mechanisms, worth keeping separate in your head. The watermark is a signal embedded in the pixels or the waveform, using TrustMark-B on images and silentcipher on audio. The signature is a manifest attached to the container. The watermark survives some things the manifest does not, like a screenshot or a re-encode. The manifest carries information the watermark cannot, like a whole workflow. Most people will want both, which is why one node does both.

The two defaults that will get you

One: c2pa_sign is on by default, and signing writes a file rather than passing a tensor.

This is not a bug, it is physics. A C2PA manifest lives in a file container. A decoded ComfyUI tensor is just numbers in memory and has nowhere to put one. So when c2pa_sign is on, the node writes the signed file to your ComfyUI output/ directory itself, named <filename_prefix>_00000.png, and the tensor that continues down your graph carries no manifest at all.

Wire it the way you would wire any other node, with a SaveImage after it, and here is what you get: two files. One saved by SaveImage, unsigned. One written by the node, signed. If you then grab "the render" out of your output folder by habit and post it, you have a fifty-fifty chance of posting the unsigned one.

The fix is to stop treating this like a normal filter node when signing is on. Wire the image output into a PreviewImage if you want to see it, and let the node write the artifact. No SaveImage in the chain.

Two: brand_id defaults to 2, which is not yours.

The brand id is a 5-bit value, 0 to 31, that rides inside the watermark payload so a detector can map a mark back to a known brand. The default is 2, and the README says plainly what that is: the public rAIdio.bot brand id, described as "an ergonomic default, not a requirement."

I read that as an honest convenience choice that will still produce a confusing outcome. If you never touch it, every mark you embed says brand 2. Not yours, not anonymous, somebody else's. That is a strange thing to find in your own published work. Register your own brand id and set it, or at minimum know what you are stamping.

The failure mode that says nothing

Here is the one to take seriously, and full credit to the maintainers for documenting it in plain language rather than burying it.

Image watermarking runs TrustMark on ONNX Runtime, and it needs a 1.22.x runtime specifically. provcheck-kit needs it to embed, and provcheck needs it to detect. If the runtime is missing or the version does not match, the README says the image mark "silently no-ops."

Read that again in the context of what this tool is for. To my mind that is about as bad a shape as a failure can take in a provenance tool, because you walk away believing your work is marked. Audio and video go through silentcipher and do not need the runtime, so the failure is image-specific, which makes it easier to miss if you tested on a video.

Verify it before you trust it. The node has a read mode. Mark one image, then feed that same file back into a second Provcheck node with mode: read, and check the detected boolean. If it comes back false on a file you just marked, your ONNX runtime is wrong. Set ORT_DYLIB_PATH to a 1.22.x runtime, or install one.

The round trip costs you one extra render, and I would run it after any change to your Python environment rather than only once at install.

Put this into practice

The ten-minute version, no account, no signing.

  1. Install the node. Either git clone https://github.com/CreativeMayhemLtd/ComfyUI-Provcheck into your ComfyUI/custom_nodes/, or search "Provcheck" in ComfyUI-Manager. The Python dependencies are numpy, Pillow and torch, all of which ship with ComfyUI, so a plain clone needs nothing else.
  2. Get the binaries. The node is a thin wrapper; the actual watermark and C2PA math live in the provcheck and provcheck-kit CLIs. Download them from the releases page and put the folder on your PATH. Confirm with provcheck-kit --version. Note that the release bundles are currently unsigned, so Gatekeeper on macOS and SmartScreen on Windows will both warn you on first launch.
  3. Install one detector family. The binary ships slim, around 20 MB, and pulls weights on demand. Run provcheck-kit weights install trustmark, which is 62 MB, for images. There is deliberately no --all shortcut; consent is per family. If you are marking audio, provcheck-kit weights install silentcipher is 11 MB.
  4. Wire the simplest graph: LoadImage into the Provcheck node, node's image output into SaveImage. Set mode: write, watermark: on, c2pa_sign: off.
  5. Run it. Watermark-only returns the marked tensor, so the normal SaveImage is correct here and the PNG it writes carries the TrustMark.
  6. Verify. Load that PNG into a second Provcheck node with mode: read and confirm detected comes back true.

That is a working watermark with no identity setup at all.

Adding the signature, once.

provcheck-kit init                 # mint a local ES256 signing key
provcheck-kit login -u <handle>    # link your atproto/Bluesky handle
provcheck-kit publish              # anchor the fingerprint to your DID

One wrinkle on the middle command: the node's README writes it as a bare provcheck-kit login <handle>, while the main provcheck repo, which is where the CLI actually lives, writes it as provcheck-kit login -u me.bsky.social. I have used the flag form above because the CLI's own repo is the authoritative one. If it rejects the flag, drop it and pass the handle bare, and check provcheck-kit login --help before assuming either.

Then set c2pa_sign: on and embed_identity: on, remove the SaveImage from the chain, and set brand_id to yours. Files now trace back to your handle. If the identity is not set up, the sign step fails and the node falls back to watermark-only passthrough with a console warning rather than crashing a long render, which is the correct behavior for something sitting in the middle of a queue.

For video, feed a CreateVideo output into the node. The mark rides the audio track, which means two things worth planning around: the audio gets re-encoded to AAC, and a silent clip carries no watermark at all. Give it a few seconds of real audio. Frames are preserved untouched, and the container gets signed when c2pa_sign is on.

One more setting people miss: timeout_secs defaults to 120 and covers each item. On a CPU-only host or a long clip, raise it. The silentcipher embed is not fast.

Honest limitations

It is not a deepfake detector, and the maintainers say so. This is the ceiling, stated in the repo: detecting whether unmarked media is AI-generated is "a separate problem and is not shipped at any version." Provcheck answers "does this file carry a valid mark or signature." It never answers "was this generated." An unmarked file tells you nothing, which is most files.

A watermark is not permanent, and the project does not claim it is. The README's own framing is that provcheck is a detector, not a promise. The one invariant they hold is that a stripped asset must never verify, which is the right invariant, but it means the honest use here is proving your own authorship, not policing someone else's theft.

The keyed version is a different product. Creative Mayhem's Backfire mark, the one designed so that AI stripping tools amplify it rather than remove it, is BUSL-1.1, source-available, and never bundled into the Apache binary. If you came here for that specific capability, this node is not it.

The project is small. Eleven stars on the main repo as of today, maintained by a Berlin studio called Creative Mayhem UG, and built primarily to serve their own rAIdio.bot and Doomscroll.FM pipelines. That origin explains both the quality of the audio path and the brand id default. Weigh it as you would any tool with one maintainer.

And a small documentation inconsistency worth flagging. The changelog announces a ComfyUI node twice: once at v0.9.0 on June 29 as "ComfyUI stamping node lands," and again at v1.4.0 on August 31 as "A free, Apache-2.0 ComfyUI node also lands." I could not resolve which is the release that matters from the changelog alone. It does not affect anything you run, but if you are trying to date this feature, that is why the dates disagree.

What this is actually for

I do not think most people should install this to fight anything. The theft use case is the one everyone reaches for and it is the weakest one, because a determined stripper wins and the maintainers admit it.

The use I would defend is smaller and more durable. If you make things with generative tools and you expect to still be pointing at that work in three years, a signed file with your handle in it and a record of how it was made is a better archive than a folder of PNGs and your memory of which checkpoint you were on. The provenance is for you first. That it also helps a downstream ingester is a bonus.

Whether that is worth ten minutes depends on how much you expect anyone, including future you, to ask where a file came from. I have started assuming the answer is more often than I would like.

If you wire this into a bigger pipeline than a single graph, especially a render queue, I would want to hear how the timeout behaved and whether the fail-closed passthrough saved you or hid something from you. That is the part I have not stress-tested.


Sources: ComfyUI-Provcheck · provcheck · releases · C2PA


Medium metadata

Title: Provcheck Signs Your ComfyUI Renders From Inside the Graph. Check Two Settings First.

Subtitle: The free, Apache-2.0 node that watermarks and C2PA-signs images, audio and video with no account and no upload, how to wire it up in about ten minutes, and the two settings that will silently hand you an unmarked file.

Tags: ComfyUI, Generative AI, Content Authenticity, Open Source, AI Art

Suggested kicker: A node inside the graph can attest the seed, the sampler and the prompt. A signer downstream can only attest a file.