LatentCast
A person in a dark suit at a desk, holding up a translucent glowing identity card beside an open laptop.

Two Layers of Marking: Watermark and C2PA in Production

Why two layers, and what each one is for

Article 50(2) requires that AI-generated output is marked in a machine-readable format and detectable as artificially generated2. The Code of Practice turns that requirement into a concrete build, and for video distributed online the build is two marking layers, not one1.

The reason is simple. Signed provenance (C2PA) is a structured record attached to a file that says what made it and how5. It can carry as much detail as you want, but it dies the moment the file is re-encoded. A watermark lives in the pixels and survives transcoding, but it holds only a few hundred bits, nowhere near enough for a provenance record.

So we pair them. Our watermark payload carries a content identifier, and the signed manifest carries the same identifier in a soft-binding assertion. When a stream has been re-encoded and the manifest is gone, the identifier recovered from the pixels resolves back to the record we still hold. The regulatory reading behind all of this is the first piece in this series; this one is about what it took to build.

The watermark, and what a real CDN did to it

We use Video Seal, Meta’s open-source video watermarking model, MIT licensed for both code and weights3, running on our own GPUs. The 256-bit payload has three parts: a magic value that identifies the scheme, a content identifier, and a truncated checksum.

The checksum matters more than it looks. Without it, detection has a single failure mode: silence. With it, detection can tell “there is no watermark here” apart from “there is a watermark here but the payload is damaged”, and it refuses to report a corrupted identifier instead of resolving to the wrong video. In a compliance context, a false identification is far worse than a non-identification.

The Code of Practice asks for marking that survives recompression and format change1. You cannot claim that from reading a library’s documentation, so we measured it.

RenditionScheme recognisedIdentifier recovered
1080pYesExact
720pYesExact
480pYesPayload damaged, nothing reported
360pYesPayload damaged, nothing reported
240pYesPayload damaged, nothing reported
One production render, 1917 frames at 1920x1080, pushed through our CDN's full transcode ladder and detected against the CDN's own MP4 output for every rendition it produced.

The failure mode is the interesting half. At 480p and below the magic value still comes back, so the signal is there, but the identifier carries bit errors after the downscale. The layout does exactly what it was designed to do: it reports nothing rather than something wrong.

The marking stays intact in the master file, in the signed manifest, and in the resolutions that carry most viewing. A clip captured from a 480p stream is not attributable by watermark today. Embedding strength is still at the library defaults; raising it trades image quality against low-resolution survival, and we have not finished tuning that.

For anyone sizing hardware: embedding runs at about 128 frames per second on the GPU. The end-to-end step sits near 0.75x realtime because ffmpeg decode and encode dominate. C2PA signing costs half a second of a sixty-second pipeline.

What actually arrives from upstream providers

We check every asset that enters our system for provenance, which turns “upstream providers sign their output” from an assumption into a measurement.

Google signs every image its models generate: a real manifest, signed with its own certificate, timestamped, declaring the content as created with a generative model. It also declares the watermark it applied, but as free text in a description, not as a structured soft binding, so no verifier can parse it into anything actionable. Beyond Google we see very little. Most providers hand over plain bytes with no provenance at all.

That matches the only published survey we know of: researchers at Maastricht University worked through 50 image-generation systems and found 38% carrying any machine-readable marking, with adoption lowest among providers building on third-party APIs4.

Audio is its own case. No vendor we use ships C2PA-signed generated audio by default; the industry has converged on watermarking instead. That is a technical divergence, not laziness: audio gets re-encoded constantly, which is brittle for a cryptographic manifest and fine for a watermark.

Why provenance does not survive a video pipeline

Our output video is a fully re-rendered composition. Background images, generated clips, voice tracks, the avatar, the logos: everything gets decoded, composited and re-encoded into new frames. Not a single byte of any input file survives into the output. Any manifest embedded in an input dies with its bytes. That is not a defect of the pipeline; it is what video composition is.

The consequence is architectural: provenance has to be captured at the ingestion boundary, on the raw bytes as they arrive, before the pipeline touches them9. We store the manifest and its validation result at import, and at render time we attach it back to the output as a C2PA ingredient. The output manifest then carries the chain: Google’s signature on a background image is preserved and verifiable inside our final video, even though the image itself was long since re-encoded into frames.

The tooling deserves a few words. Everything in the C2PA space wraps the same Rust core, c2pa-rs: we use the c2patool CLI at ingestion and the Python bindings in our marking service. Format support is uneven and worth knowing before you design around it:

  • Images (PNG, JPEG, WebP, TIFF, GIF) and MP4/MOV sign fine.
  • PDF can be read but not signed. The underlying library does not support it, and since every tool wraps that library, “use another tool” is not an escape hatch.
  • WebM and Office documents are not supported at all.
  • Audio is signable on paper, but detached-sidecar signing rewrites the ID3 tag, so the sidecar ends up binding bytes you do not store. We keep audio out of the signing path.

Assets in the unsupported categories are recorded by identity: format, hash, where they came from, when. The gap is visible instead of invisible.

For assets that arrive with no provenance at all, we mint a signed import record at ingestion: we received these bytes, at this time, from this source, and their history before that point is unknown. It lives in a detached sidecar next to the file, so the asset bytes stay untouched and every hash and reference held elsewhere keeps working.

One lesson from building this is worth passing on. Validate your manifests with the tool your readers will use, for us c2patool and Content Credentials Verify7, and gate on that validation. A status column that says “signed” is not evidence; the artefact is.

The output manifest, and why signing goes last

The cryptography picks the order for you. The C2PA hard binding hashes the final bytes of the file, so signing must be the last operation that touches them, and watermarking re-encodes. Watermark, then sign, then upload untouched.

The reference between the layers runs one way only. The manifest names the watermark’s identifier; the watermark can never name the manifest, because a hash of the signed file cannot live inside that same file.

We went looking for an industry baseline to copy and didn’t find a strong one. Reading real manifests from major generators, the typical output is one actions assertion with a couple of actions and little else. Google’s manifest does not even say which model made the image; its legibility comes almost entirely from the certificate issuer. One field does real work: a structured software agent naming the product and version. We confirmed against the reference verifier that its “AI tool used” section appears only because we emit that field7, and not every generator does.

The finished video carries its ingredients. A recent render lists fifteen: the generated backgrounds, the generated clips, the voice tracks, the avatar, the brand logos. Each carries its own provenance, preserved from upstream where it existed and minted by us where it did not. Anyone checking a delivered file, including the ones we send in our own outreach, can see what it was built from, not just be told AI was involved somewhere.

One vocabulary choice cost us a round trip. IPTC defines the terms for how a file was made8. By the definitions, compositeSynthetic (“mix or composite of several elements, at least one of which is Generative AI”) describes our render best, so we used it. Then we tested both terms on the reference verifier with the same sample signed twice7: compositeSynthetic produced no AI disclosure at all, while compositeWithTrainedAlgorithmicMedia produced a clear sentence, “This video combines multiple pieces of content. At least one was generated with an AI tool”, plus the tool section. We kept the term that displays and pinned it in a test. A disclosure obligation is settled by what appears on screen in front of a person; a blank panel is a weak marking, however defensible the reading behind it.

Certificates: where we are

You can sign a manifest with a certificate you operate yourself, and that is compliant: the Code of Practice asks that provenance records are signed and timestamped in a secure and tamper-evident manner1. It does not ask for a trust-listed certificate. What the trust-listed certificate changes is what a verifier displays: a recognised issuer instead of an unknown one.

For us the self-operated certificate is explicitly an interim step. LatentCast is going through the C2PA Conformance Program6: our product is registered, the security architecture documentation is nearly ready, and the trust-listed certificate is issued once the assessment is passed. We expect to come back in a few weeks with a follow-up post saying the program is complete and our videos sign under a trust-listed certificate.

The swap itself is a configuration change. The certificate travels inside each manifest, so files signed under the interim chain keep verifying against the certificate they carry. They will keep showing the unknown issuer, but their signatures stay valid, and only files signed after the swap get the trusted display. Timestamping is what makes this hold: the timestamp proves the signature was made while the certificate was valid, so the signature outlives the certificate that made it.

One practical note if you build this yourself: the signing tool will not accept a bare self-signed certificate. You need a small CA-signed chain (a root plus a signing leaf is enough) with digital-signature key usage and an email-protection EKU on the leaf. And when a certificate misses a profile requirement, the error is simply “the certificate is invalid”; it does not tell you which requirement you missed.

FAQs

Why is C2PA not enough on its own for video?
A signed manifest is bound to the bytes of the file, so re-encoding breaks it, and every streaming platform re-encodes. The manifest survives on the master you hand someone directly; it is gone from anything a viewer streams.
Does a watermark survive a CDN transcode?
Ours recovers the identifier exactly at 1080p and 720p through a production CDN ladder. At 480p and below the payload carries bit errors, and the system reports nothing rather than resolving to a wrong answer.
Should I watermark before or after signing?
Watermark first, sign last. The C2PA hard binding hashes the final bytes of the file, so any step that touches bytes after signing invalidates the manifest.
Do I need a trust-listed certificate to comply with the Code of Practice?
No. Signed and timestamped in a tamper-evident manner is the requirement, and a certificate you operate yourself meets it. But treat that as the starting point, not the destination: a trust-listed certificate is clearly better, because verifiers show a recognised issuer instead of an unknown one.
What do you put in a manifest for an asset whose origin you do not know?
What you can truthfully assert: that you received it, when, from where, and that its prior provenance is unknown. We mint that as a detached sidecar so the asset bytes stay untouched.

Sources

  1. Code of Practice on Transparency of AI-Generated ContentEuropean Commission, June 2026
  2. Article 50: Transparency Obligations for Providers and Deployers of Certain AI SystemsEU Artificial Intelligence Act
  3. Video Seal: open-source video watermarkingMeta AI Research
  4. Missing the Mark: Adoption of Watermarking for Generative AI Systems in PracticeRijsbosch, van Dijck and Kollnig, Maastricht University, 2025
  5. Coalition for Content Provenance and AuthenticityC2PA
  6. C2PA Conformance ProgramC2PA
  7. Content Credentials VerifyContent Authenticity Initiative
  8. International Press Telecommunications CouncilIPTC
  9. Transparency as Architecture: Structural Compliance Gaps in EU AI Act Article 50 IISchmitt, Kruse, Sahitaj and Schöning, March 2026