ARC Save (sign on arrival)
C2PA-sign your images before they touch disk
- images
ComfyUI's default SaveImage already stuffs your entire workflow into the PNG as text chunks - model, sampler, seed, prompt. Drag it back onto the canvas and the whole graph rebuilds. Clever, but it's not proof: that metadata is plain text anyone can edit, and most image hosts strip it the moment they re-encode (Reddit recompresses, workflow gone). ARC Save comes from the other school: sign the file on arrival, so the provenance is cryptographically bound before the bytes ever hit disk.
What it is
ARC Save is a drop-in replacement for SaveImage, built by ArcVelvet (arcvelvet.com, a closed-alpha provenance service that runs C2PA signing on its own servers). Same input shape, same output directory, same feel - swap it in and every saved PNG carries a signed C2PA manifest with platform-attested identity, the generation graph, and a verify URL anyone can open. It's for people who publish images and want a tamper-evident "I made this."
One honest trade: signing happens server-side, so your image bytes leave your machine, get signed against ArcVelvet's keys, and come back credentialed. The unsigned original never touches disk - but if your rule is "no bytes leave this box, ever," this node isn't for you. Attested identity costs a round trip.
How it works
The node encodes your tensor to PNG with the exact path SaveImage uses (same numpy ops, same PIL call, compress_level=4), POSTs the bytes to ArcVelvet's arcIngest endpoint, and gets back a receipt with a signedFileUrl. It downloads the signed PNG, writes it to your output directory, and drops a sidecar <prefix>_<vaultItemId>.arc.json alongside. Fail-loud per image: one retry after two seconds on transient errors (HTTP 503, timeout, connection error); everything else - bad auth, rate limit, size cap - raises immediately with the server's error code. No silent unsigned fallback.
The inputs that matter
There are only four, and three are boring:
images- the IMAGE tensor, typically straight out of VAE Decode.filename_prefix- defaultArcVelvet; becomes<prefix>_<vaultItemId>.png.title- optional, baked into the signed assertion.include_prompt_text- the one to think about. Default OFF is the right default: the manifest keeps the full workflow structure (model, sampler, seed, connectivity) but replaces text-encoder prompt values with[REDACTED:sha256:<hex>]envelopes - you can reveal the plaintext later and anyone can verify the hash. ON and your wording rides verbatim, cryptographically bound to the image: useful for attribution disputes or dataset provenance.
There are no graph outputs; this is a terminal node. Two files land in ComfyUI/output/: the signed PNG and the .arc.json sidecar with vaultItemId, verifyUrl, contentHash, and traceId. Open the verify URL in any browser for the provenance record; append &format=file to download the signed bytes.
Installing it
Here's the gotcha: there's no ComfyUI Manager entry yet - the pack's Manager PR is drafted but explicitly not opened, so you install by hand:
cd ComfyUI/custom_nodes
git clone https://github.com/arcvelvetOS/comfyui-arc-save
Then restart ComfyUI and the node appears under image/save. Dependencies are just numpy, Pillow, and requests - no model downloads, nothing heavy.
It does need an API key, because signing is a hosted service. Grab one at arcvelvet.com → Credentials → Issue API key - it's shown exactly once, so copy it then - then put it in arc_config.json in the node directory, or set ARC_API_KEY. Closed alpha means new keys sit behind a quick approval check.
Where people get burned
- Rate limits are real. Five signings per minute per key, twenty per account. A batch of 6+ images halts partway with
ERR_RATE_LIMITED, loudly and by design. Images already signed are kept, and rerunning dedups on content hash so you don't double-charge - but for big batches, split upstream or wait a minute and rerun. - The cert is still warming up. Files verify cryptographically, but third-party C2PA inspectors (Adobe's, contentauthenticity.org) will note an unrecognized issuer until ArcVelvet's production certificate is provisioned. That's a certificate-trust step, not a defect; the embedded verify URL is the authoritative surface meanwhile.
- Prompt moderation means transmission. Prompts are scanned in-flight via OpenAI's
omni-moderationendpoint - your wording is transmitted to OpenAI for the scan, then out of scope at both companies. The redacted manifest is a separate thing from that transmission. - It's a phone-home node. Arbitrary Python that holds your key and calls the network by design - the exact shape of thing that got weaponized once in this ecosystem. The repo is small, MIT, readable, and ArcVelvet is a real company with a support address. Read it once, never screenshot your config, and revoke the key if it ever leaks.
Reach for ARC Save when provenance is the point: publishing, archiving, attribution. For casual local saves, SaveImage is fine and free - this one adds a signature and a trip across the network. Make sure you want both before you pay either.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | Image tensor from upstream node (typically VAE Decode). | |
| filename_prefix | STRING | ArcVelvet | — |
| title | STRING | Optional creator-supplied title baked into the signed assertion. | |
| include_prompt_text | BOOLEAN | false | OFF (default): prompt text in CLIPTextEncode-style nodes is SHA-256-hashed before signing ("[REDACTED:sha256:...]" envelope). Workflow structure is preserved; you can reveal the plaintext later and anyone can verify the hash. ON: prompt rides verbatim — useful when you want your wording cryptographically bound to the file. |
Outputs (0)
No outputs