# The provenance gap — why C2PA-signed content still shows "unknown source"

> Your content is C2PA-signed. Your verifier still says **"unknown source."** The manifest
> is well-formed, the signature is valid, the bytes are tamper-evident — and the receiver
> still can't tell whether to trust it, because a validator trusts a signer only if its
> certificate is on an explicit trust list or chains to a listed anchor, and there is
> **no Let's Encrypt for provenance** to get onto that list. Whisper makes the signer
> publicly verifiable in your own DNS. Additive to C2PA and CAWG, never a replacement.

The signature is the easy part. Deciding whether to trust the *signer* is the whole game.
A C2PA validator can build the signer's chain with no network call — the certificates
travel in-band — and still return **"unknown source"** for an independent creator, a small
newsroom, a stringer, or an AI agent, because their certificate isn't on the curated
allow-list and there's no free, automated path onto it.

**We make the signer publicly verifiable.** Anchor your C2PA signer cert under your **own
DNSSEC domain** with a `DANE` record, so any verifier can resolve it with **no list to
join, no gatekeeper, no ~$289/yr toll** — and revoke it worldwide at DNS-TTL. **Prove who
signed it — anchored in DNS, not a committee's allow-list.**

`whisper verify --trustless` — anchored at the IANA DNS root. Our own API is not in the trust path.

- **$40B** — projected deepfake fraud by 2027, up from ~$12.3B in 2023 (Deloitte)
- **~74%** — of ~1M new web pages carried detectable AI content (Apr 2025 crawl)
- **0.1%** — of people reliably told real footage from a deepfake (n=2,000, iProov)
- **28%** — trust in the media, a record low; more (36%) have none (Gallup)
- **~$289/yr** — per commercial C2PA cert, and no free automated path to the list
- **whole fleet** — of C2PA device certs revoked after one 2025 camera-vendor vuln (per-model, not per-unit)

---

## The anatomy of a Content Credential

**The signature is the easy part. Deciding whether to trust the signer is the whole game.**
C2PA got the cryptography right. What it deliberately left *pluggable* — who anchors trust —
is exactly where an independent signer falls off the edge.

A **Content Credential** is three things bound together:

- **Assertions** record what happened — actions, hashes, capture metadata — and one of
  them, the *hard binding* (`c2pa.hash.data`), hashes the asset's own bytes, so any later
  edit breaks it.
- A **claim** hash-references that set of assertions.
- A **claim signature** — a `COSE_Sign1` over the claim — seals the whole structure.

The part that matters for identity: the signer's **X.509 chain travels in-band**. Per
`RFC 9360`, the intermediates are embedded in the COSE header (`x5chain`), so a verifier
builds the chain **with no network call**. The signer is an X.509 *end-entity* certificate
(EKU `c2pa-kp-claimSigning`, OID 1.3.6.1.4.1.62558.2.1); its **serial number** is the
natural device identifier. The chain proves internal consistency — but a chain is only a
chain. Whether it means anything comes down to one question the manifest cannot answer by
itself: *is this signer's certificate on a trust list you accept, or does it chain to a
root that is?* If yes, you get a name. If no, you get **"unknown source"** — and a manifest
signed with an untrusted cert has the **same technical appearance** as one from a verified
org.

```
One manifest → the verifier builds the chain (no network call) → one trust decision:

  is the signer on a trust list, or chained to a listed anchor?
        │
        ├─ YES → VERIFIED — "signed by news.example.org"
        └─ NO  → "unknown source"  (off-list CA · self-signed)

Two byte-identical, validly-signed manifests, opposite verdicts — purely on
whether the signer's cert is on a list you happen to accept.
```

C2PA is explicit that it does *not* mandate a particular PKI — trust lists and anchors are
configuration inputs to the validator. That's the honest opening: a DNSSEC/DANE anchor is a
*legitimate alternative trust source*, not a fork of the standard. So why is the only
well-trodden path a curated list you have to pay and petition to join?

---

## Gap 1 · there is no on-ramp

**There's a Let's Encrypt for the web. There is none for provenance.** The web got
universal HTTPS the day getting a trusted certificate became free and automatic. Content
provenance never had that day.

**Today · trust is a curated allow-list you pay and petition to join.** The official C2PA
Trust List and Conformance Program (launched mid-2025) is a C2PA-managed set of X.509
anchors for CAs issuing to conforming signers, gated by a Product-Security-Architecture
submission and assurance levels. For large platforms it works. But there is **no free,
automated, ACME-style path** onto it for an independent creator, a small newsroom, a
stringer, or an AI agent — commercial C2PA certs run **~$289/yr**, and the recognized-CA
set is controlled by a small coalition. Content signed by an off-list CA displays
**"unknown source,"** and the spec permits self-signed and off-list certs — an
"anyone can sign anything" gray zone with no open way to make an off-list signer *publicly
verifiable.*

**Tomorrow · the signer vouches for itself, in DNS.** A signer whose end-entity certificate
(or its public key) is published under a **DNSSEC-signed TLSA/DANE record on the signer's
own domain** is self-verifying: any verifier configured with a DANE trust source resolves
it against the **IANA DNS root** — no central list, no gatekeeper, no annual CA fee. The
domain you already own becomes the trust anchor. "Signed by `news.example.org`" is checkable by
anyone with `dig`, not by whoever holds the allow-list.

> **"C2PA already floated a 'Web Domain Trust Anchor.' Isn't this the same idea?"**
> Same instinct — but it reached for the weaker mechanism. C2PA's own experimental Web
> Domain Trust Anchor uses a *self-signed* certificate served from an HTTPS
> `/.well-known/c2pa.json` file — **not DNSSEC** — and its own write-up flags two open
> problems: *domain takeover* (a hijacked origin serves a new anchor) and *verifier
> privacy* (every validation fetches from the signer's origin, revealing who is verifying
> what). A DNSSEC-signed DANE record is the mechanism that proposal didn't use:
> cryptographically chained to the root so a swapped file can't forge it, and resolvable
> through ordinary recursive DNS caches so the signer's origin never sees the individual
> verifier.

---

## Gap 2 · you can't pull one bad signer without pulling them all

**When a camera fleet's key was compromised in 2025, the fix was to revoke *every* device
cert.** In-camera Content Credentials now sign a manifest at the moment of capture with a
device or manufacturer signing certificate — the first mile of provenance, adopted across
major camera makers and the first native smartphone implementations. The holder is a
*device*; the signer identifier is the device signer cert's serial. Good first-mile
hygiene — but the trust and revocation model underneath it is per-*model*, per-CA, and
slow.

**The incident, at the class level (no vendor named):** in 2025 a camera vendor **suspended
its authenticity service and had to revoke its entire set of C2PA device certificates**
after a security vulnerability — and, as of mid-2026, had not restored it. That's the sharp
end of a structural problem C2PA already concedes: **revocation checking is optional,**
academic testing has found conforming validators accepting revoked or compromised certs and
returning contradictory verdicts, and the privacy-driven drift away from CRLs toward
optional OCSP means a compromised signer can stay "trusted" long after it should be gone.

**The fix — per-unit identity, revocable in DNS.** Give each device an identity **derived
from the hardware key it already holds**, anchored in DNSSEC/DANE and **individually
revocable**. One compromised unit is one `op:revoke` away from gone — at DNS-TTL,
worldwide — instead of a fleet-wide certificate recall that takes an authenticity service
offline for a year. Per-*unit* trust, not per-*model* collapse.

> **"A stolen signing key mints spec-valid manifests until it's revoked. What does DNS
> actually buy me?"**
> It shrinks the exposure window from "until OCSP, if ever" to minutes. It does not
> retroactively un-sign what a stolen key produced before you noticed — nothing can. But
> instead of waiting on a CRL round-trip, an optional OCSP responder, and a trust-list
> committee, you pull the signer's DANE record and its `dig -x` name resolves to nothing at
> the record's TTL. The damage is *bounded*, not merely logged.

---

## The cure · signer key → a name anyone can verify

**The key already in your signer becomes an address the whole internet can resolve.**
Whisper has one primitive: **the address is the identity.** A routable IPv6 **/128** out of
`2a04:2a01::/32` (announced by **AS219419**), deterministically derived from a key,
DNSSEC-anchored, **DANE-EE** pinned, RDAP-registered — re-derivable and verifiable by anyone
with `dig`.

**Point it at your C2PA signer.** Derive the signer's /128 from the public key it already
uses to sign claims, with the **C2PA signer cert serial as the `device_id`** domain
separator (a camera's device serial, a newsroom's signing key, an agent's key — whatever
native identifier the signer carries). The private key never leaves the signer; only the
public SPKI and the serial are inputs, and the address is a one-way function of them. Then
publish the signer certificate under a **DANE-EE `3 1 1`** record in your DNSSEC-signed
zone. Now the exact certificate a C2PA manifest references is publicly, independently
resolvable — the identity ecosystem C2PA depends on but doesn't provide.

```
C2PA signer key           →   /128                    →   a signer any verifier trusts
X.509 EE cert · serial        2a04:2a01:c0d::51            whisper verify --trustless
key never leaves signer       routable identity            no trust list · no CA fee
(public SPKI + serial only)   [DNSSEC + DANE-EE 3 1 1]     under YOUR DNSSEC domain
                                                                    │
                                              op:revoke → this signer gone at DNS-TTL (per-unit)
```

- **"Unknown source" becomes "signed by your domain."** A verifier with a DANE trust source
  resolves the exact signer cert the manifest references — publicly, off no list.
- **No coalition, no ~$289/yr toll.** The trust anchor is the domain you already own. An
  independent, a stringer, or an agent gets a verifiable signer identity with zero CA
  gatekeeping.
- **Cross-org trust with no shared list.** Two organizations that both trust the DNS root
  verify each other's signers today — no private allow-list to join.
- **Revoke one signer, not the fleet.** A leaked key is one `op:revoke`: the DANE record is
  pulled and `dig -x` returns nothing at TTL. Per-unit, worldwide.

**Additive to C2PA — it does not replace the manifest.** Whisper does not create the
Content Credential or embed a watermark. The manifest, edit history, hard binding, and
in-camera capture stay exactly as they are and stay excellent. Whisper anchors the *signer*
those manifests already reference — the publicly verifiable, DNSSEC/DANE-anchored identity
layer *on top.*

**The cert serial is the public index — the /128 is its cryptographic counterpart.** The
serial flows through every manifest; it isn't a secret. The /128 is bound to the signer's
key *and* the serial — so the serial alone yields nothing. You cannot go serial → /128
without the key, there is no enumerable directory, and RDAP/reverse-DNS return the registry
object, never anything private. Because the derivation is **tenant-bound**, the same signing
key under two organizations yields two unrelated /128s.

**The formal seam is CAWG — and it is already DNS-native.** The Creator Assertions Working
Group identity assertion (v1.2, ratified Dec 2025) binds a named creator or organization,
distinct from the tool's claim signer. In real deployments its issuer is a `did:web` — a
domain name resolved through DNS — and its `verifiedIdentities[]` carries a required
`cawg.web_site` URI the actor controls. A Whisper DNSSEC-anchored domain identity is a
first-class `did:web` root and a natural DANE binding for that `cawg.web_site` URI: it turns
CAWG's own "well-formed but unrooted" state into *trusted* without an S/MIME CA. CAWG is the
standards-blessed path to surface a DANE-anchored signer; we ride it, we don't fork it.

This is the layer the **EU AI Act** reaches for by name. Recital 133 lists acceptable
techniques including *"cryptographic methods for proving provenance and authenticity of
content"* and asks that detection be *"made accessible… to enable the public to effectively
distinguish AI-generated content"* — a public DNSSEC/DANE anchor is exactly that, versus a
private curated allow-list. It *evidences and strengthens* an Article 50(2) machine-readable
mark; it does not, by itself, make anyone compliant.

---

## Close the loop · who verified your content

**Everyone else's provenance is write-only. You never see who checked your content.**
Because a C2PA manifest carries its certs in-band, verification needs no network call —
which means the signer has **zero visibility** into who verified their content, where, or
how often. Anchor the signer in DNS and it fills itself.

- **Who verified your content is a query.** When a verifier resolves your DANE-anchored
  signer, it leaves DNS/TLSA/RDAP lookups against Whisper's servers. `op:lookups` returns
  who checked this identity, where, and how often — provenance-verification analytics C2PA
  structurally cannot provide, and an early warning that someone is probing or
  impersonating your signer.
- **Nothing issued in the dark.** Every identity mint and every revoke lands in a public,
  append-only RFC 6962 Merkle transparency log, Ed25519-signed and anchored to Bitcoin via
  OpenTimestamps — an auditable trail for a regulator or a court. *Honest status:*
  tamper-evident and anchored today; independent third-party witnessing is the next step.
- **Govern and kill a signer.** `op:firewall` and `op:policy` constrain what a signing
  agent or device may reach; `op:budget` caps it; `op:revoke` pulls a compromised signer
  worldwide at DNS-TTL. The control plane, not just a name.
- **Give an AI agent a signer it can prove.** The same primitive gives an AI tool or agent
  a signer identity of its own — sign each output's C2PA claim (and a CAWG identity
  assertion) under a DANE-verifiable, revocable identity derived from the agent's existing
  key.

When someone stands up a look-alike domain to impersonate your byline, the same attribution
graph that powers `whisper.identify` names who really operates it — a reproducible, signed
evidence chain, not a screenshot.

---

## Prove it in 60 seconds · no account

Two tiers, by design. **No key:** anyone can verify a signer's identity, resolve it, and
read the DANE record a C2PA validator would pin against — trustless, anchored at the IANA
root. **Your key:** anchor a signer to a /128, see who verified it, revoke it worldwide.

```bash
# keyless — re-derive and verify any signer's identity, trustless
$ whisper verify --trustless 2a04:2a01:c0d::51
  ✓ DNSSEC chain valid to the IANA root
  ✓ DANE-EE (TLSA) leaf matches the C2PA signer cert
  ✓ RDAP: registered under AS219419 · 2a04:2a01::/32
  signer: VERIFIED — signed by news.example.org, no trust list consulted

# the address is the signer — reverse DNS names it
$ dig -x 2a04:2a01:c0d::51 +short
  signer-4a7f21.c2pa.news.example.org.

# read the exact DANE record a C2PA validator would pin the signer cert against
$ dig +dnssec TLSA _443._tcp.signer-4a7f21.c2pa.news.example.org +short
  3 1 1  <sha-256 of the signer cert SPKI>      ; RRSIG present — chained to the root
```

```bash
# anchor a C2PA signer to a /128 — pass the signer cert serial as device_id
$ export WHISPER_API_KEY=whisper_live_xxx
$ curl -s https://graph.whisper.security/api/query -H "X-API-Key: $WHISPER_API_KEY" --data-urlencode "q=CALL whisper.agents({op:'connect', args:{tier:'wireguard',
       identity_public_key:'<base64 SPKI of the signer key>',
       device_id:'4A7F21C0DE9B11EF...'}})"   # device_id = the C2PA signer cert serial
  → identity 2a04:2a01:c0d::51   DNSSEC + DANE-EE (3 1 1) live

# who verified my content? — op:lookups fills the empty quadrant C2PA can't
$ whisper lookups 2a04:2a01:c0d::51
  312 resolves · 47 TLSA pins · 5 RDAP reads / 24h
  spike: 1 source → 128 TLSA pins in 9m   (a verifier fleet — or someone probing your signer)

$ whisper kill --revoke 2a04:2a01:c0d::51   # leaked key → gone at DNS-TTL, per-unit not per-model
```

---

## Where Whisper fits

**C2PA proves the pixels weren't changed. A watermark proves it came from a generator.
Whisper proves *who signed it* — publicly.** The manifest, edit history, in-camera capture,
and durable watermark are done well by the incumbents and stay exactly where they are. What
none of them provides is a signer identity that is publicly verifiable off any central list,
revocable in one DNS call, and able to tell you who verified your content.

| | C2PA / CAI | Watermarking | Whisper |
|---|---|---|---|
| Tamper-evident manifest (who / how / edits) | ✓ | — | additive |
| Invisible signal surviving screenshot / re-encode | — | ✓ | — |
| **Publicly-verifiable signer** off any central trust list | — | — | ✓ |
| Signer revocation at DNS-TTL, one call | — | — | ✓ |
| Who verified your content (analytics) | — | — | ✓ |

It lands as a machine-readable feed into your stack, too — the **Splunk** connector (signed
JSON → CEF/ECS) ships today, with Microsoft Sentinel, OpenCTI, and STIX 2.1 over TAXII on
the roadmap. Enrichment that makes your trust-and-safety pipeline sharper, not a console
your team has to babysit.

### Honest scope · read this before you buy

- **A DANE anchor is additive, not official membership.** A DNSSEC/DANE-anchored signer is a
  *legitimate, pluggable trust source* a validator can be configured to consult — because
  C2PA does not mandate a PKI. It is **not** official C2PA Trust-List membership and **not**
  a conformance route. The standards-blessed path to surface it is a **CAWG** identity
  assertion and/or a proposal to the standard. We position it as a complementary identity
  ecosystem, never as "already C2PA-approved."
- **Provenance is not truth.** A valid signature proves *who* signed and that the bytes are
  intact — not that the content is real. A genuine signer can sign a staged or misleading
  image. What we add is accountability and attribution: the signer is publicly named. We are
  **not a deepfake detector** — absence of a credential is not proof of fakery, most content
  is unsigned, and we raise the value of signed-authentic rather than flagging
  unsigned-synthetic. Pair us with detection and watermarking.
- **A screenshot or re-encode still strips the manifest.** That's a C2PA-wide limitation,
  not ours to solve by signing — the mitigation is durable soft-binding / watermarking. A
  public anchor helps you *detect* where credentials were stripped via verification
  analytics; it can't *prevent* it. And revocation shrinks a stolen key's exposure window
  dramatically — it does not un-sign what the key produced before you pulled it.

---

## Prove who signed it — anchored in DNS, not a committee's allow-list

The address is the signer — routable, DNSSEC-anchored, publicly verifiable off any central
list, revocable worldwide in one call. Keyless to try, one call to anchor, one more to
revoke. "Unknown source" becomes "signed by your domain."

- **Prove your content** → https://console.whisper.security/sign-up
- **For newsrooms** → /for-newsrooms
- Or run `whisper verify --trustless` right now.

Identity on the wire for content provenance. AS219419 · 2a04:2a01::/32.
