# Platform integrations

**Whisper sits beside the C2PA / Content Credentials stack you already run and anchors exactly one thing: a publicly verifiable signer identity at the DNS/DANE boundary. That's the layer where, today, an off-list signer and a globally trusted newsroom produce a manifest with the same technical appearance, and the verifier has only a private, gate-kept trust list to tell them apart.**

Everything below is a **proposed** integration pattern (our design, not a vendor endorsement), and every one is written the same way: *Whisper complements the mechanism you have; it never replaces it, and it never forks C2PA.* We do not create the C2PA manifest, we do not embed the durable watermark, we do not assert that signed content is *true*, and we do not stop a screenshot from stripping the credential. Those are the manifest's, the watermark's, and the first-mile's jobs, and they are each already someone's. Whisper's job is the one seam C2PA depends on but does not itself provide: making the *signer* a manifest already references publicly and independently verifiable, expressed as an IPv6 `/128` and a DANE-EE pin that DNSSEC and RDAP can prove and one call can revoke.

> **One spine under all of them.** Each integration below reuses the same shipped primitive: a deterministic `/128` derived from a signer's *public* key plus the C2PA **signer-certificate serial** it already carries in every manifest, passed as `device_id` ([Signer & C2PA identity](/docs/signer-identity)), published with a DANE-EE `3 1 1` pin and an RDAP record, verifiable by anyone with no account. The integrations differ only in *where in the provenance chain* that signer identity is bound and checked.

## Anchor the trust decision, not the manifest

A Content Credential carries several trust mechanisms, each correct for its own layer, and the incumbents do each of them well. The mistake is to imagine a public signer anchor has to displace one of them. It doesn't. Whisper is deliberately confined to the one place none of them answer publicly: the moment a validator holds a valid signature and has to decide *whether to trust the signer behind it*: a decision that today resolves through a curated CA allow-list, an off-list "unknown source" penalty, or nothing at all.

| Layer | Owner / mechanism | Whisper's role |
|---|---|---|
| Hard binding (the asset bytes) | C2PA manifest: `c2pa.hash.data` / `.bmff`, JUMBF-embedded | **none** (never creates the manifest or the hash) |
| Claim signature | COSE_Sign1 + in-band `x5chain` (RFC 9360) | **none** (the signature format stays exactly as C2PA defines it) |
| Durable soft binding | Watermark / fingerprint (survives a screenshot / re-encode) | **none** (anchors identity, not pixels; pair with it) |
| Signer trust decision (DNS/DANE) | Curated C2PA Trust List / off-list "unknown source" / self-signed | **anchors here** (the signer's own DNSSEC zone vouches for the cert serial, verifiable with no list to join) |

Read the last row as the whole thesis. C2PA is explicit that a verifier trusts a signer if its certificate is on an *allowed* list or chains to a root on a *trust-anchors* list, and it does **not mandate any particular list or PKI**: trust lists and anchors are *pluggable configuration inputs* to the validator. That is the honest opening. A DANE/DNSSEC anchor is therefore a legitimate *additional* trust source, not a fork of the standard. Identity today is a *claim* only a gate-kept list can adjudicate; Whisper turns it into a *network fact*: the signer's cert serial, pinned in DANE, published in the signer's own DNSSEC-signed zone, verifiable by anyone against the IANA root.

```
owned by the manifest / the signer's CA / watermarking          │  the trust decision: Whisper anchors here
  : Whisper never creates these                                  │
┌───────────────────────────────────────────────────────┐       │   ┌────────────────────────────────────────┐
│  Hard binding: asset bytes · c2pa.hash.data · JUMBF ✕ │       │   │  Is this signer trusted?                 │
│  Claim signature · COSE_Sign1 · x5chain (RFC 9360)   ✕ │  the  │   │  today: a curated list · off-list =      │
│  Durable soft binding · watermark / fingerprint      ✕ │ fence │   │         "unknown source"                 │
└───────────────────────────────────────────────────────┘       │   │            │ derive + publish            │
                                                                 │   │  Signer /128 · DNSSEC · DANE-EE 3 1 1    │
                                                                 │   │  the signer's own zone vouches for the   │
                                                                 │   │  cert serial   ✓ no list to join         │
                                                                 │   └────────────────────────────────────────┘
```
*Figure: the manifest, the signature, and the watermark stay theirs. Whisper never touches them. It anchors one layer: the signer-trust decision, made verifiable in public DNS instead of adjudicated by a gate-kept list.*

## C2PA validator trust config: the keystone

This is the integration everything else builds on, and it is the least invasive one imaginable: it changes *no bytes* in the manifest and *no code* in C2PA. The signer certificate stays a normal end-entity X.509 cert, carried in-band as a COSE_Sign1 `x5chain` exactly as the spec requires. What changes is the *validator's trust-anchor set* (a list C2PA already treats as a pluggable config input), which now consults one more source: a DANE `TLSA` record, published under the signer's own DNSSEC-signed domain, that pins the SPKI of that same signer certificate.

The effect is that "is this cert on the central list?" becomes "does the signer's own DNSSEC-signed zone vouch for this serial?": a question anyone can answer against the IANA root, with no list to join, no CA to pay, and no phone-home to a validator vendor. It is, deliberately, the mechanism C2PA's own experimental *Web Domain Trust Anchor* proposal reached for but did not use: that proposal fetches a self-signed cert from an HTTPS `/.well-known/c2pa.json` file, and flags domain-takeover and origin-fetch privacy as open problems. A DNSSEC/DANE anchor closes both: the binding is cryptographic to the root, and a resolver, not the origin, serves it.

```bash
# The signer cert is unchanged: still a normal COSE_Sign1 x5chain in the manifest.
# The validator gains ONE more trust anchor: a DANE TLSA pin of that same cert,
# published in the signer's own DNSSEC-signed zone. Anyone can pull it.
dig +dnssec TLSA _443._tcp.signer-4a7f2c9e.newsroom.<tenant>.agents.whisper.online
;; flags: qr rd ra ad          <- ad = DNSSEC-authenticated to the IANA root
;; _443._tcp....agents.whisper.online. 300 IN TLSA 3 1 1 b653a4ef...fcb82d1d
;;                                              v SPKI-SHA256 of the C2PA claim-signer EE cert

# The address IS the signer: forward-confirmed reverse DNS names it.
dig -x 2a04:2a01:c0de::51f0 +short
signer-4a7f2c9e.newsroom.<tenant>.agents.whisper.online.
```

Point a validator's trust config at the DANE source and the full walk confirms itself from the internet's own records, with no central list in the path:

```bash
# Verify the signer keylessly and trustlessly: DNSSEC + DANE + a signed ledger entry,
# Whisper's OWN API never trusted. This is the check a validator can run offline.
whisper verify --trustless signer-4a7f2c9e.newsroom.<tenant>.agents.whisper.online
dnssec   pass   DNSSEC-root   AAAA, PTR and TLSA(3 1 1) all DNSSEC-validated to the IANA root
dane     pass   DNSSEC-root   served leaf SPKI-SHA256 == TLSA pin == manifest x5chain leaf
ledger   pass   DNSSEC-root   mint entry present, signature verifies
CRYPTOGRAPHICALLY PROVEN, trust anchor: DNSSEC root (IANA) + DANE-EE

# Or the keyless RDAP object for the address: who holds this signer, since when.
curl https://whisper.online/ip/2a04:2a01:c0de::51f0
```

> **! The one honest caveat, stated plainly.** DNSSEC/DANE is *not* (yet) a formally recognized C2PA **conformance** trust anchor: today conformance centers on X.509 plus the curated C2PA Trust List. Position a DANE anchor as it truly is: a *complementary* public identity ecosystem, consumed by a validator that accepts additional trust sources, surfaced through a CAWG identity assertion (below), and offered as a proposal to the standard, **never** as "already C2PA-approved." The mechanism is legitimate because C2PA leaves trust lists pluggable; the recognition is a roadmap conversation, and we label it as one.

> **Complements the C2PA Trust List, does not replace it.** The Conformance Program and its curated CA anchors stay exactly where they are; a signer on that list keeps its status untouched. Whisper adds a second, domain-owner-controlled anchor for the signers the list does not reach: the independent creator, the stringer, the small newsroom, the AI agent. That is the documented "no Let's Encrypt for provenance" gap. See [DANE & TLSA](/docs/dane) for the byte-for-byte record and [Signer & C2PA identity](/docs/signer-identity) for the derivation.

```
  C2PA manifest              signer's DNSSEC zone          validator trust anchors
  COSE_Sign1 · x5chain  ──▶  TLSA 3 1 1 = SPKI-SHA256  ──▶  pluggable config input
  serial 4a:72:f9:c…  publish  of that same EE cert  consult  + DANE source (one more anchor)
  unchanged: no fork         domain owner controls it              │
                                                                   ▼
                             the manifest never changes;   trusted signer: no list to join, no CA fee
                             only the validator's trust     └─ op:'revoke' → gone at DNS-TTL
                             config gains one anchor
```
*Figure: the manifest and its `x5chain` are untouched. The only new artifact is a DANE `TLSA` pin in the signer's own zone; the only change is that a validator's already-pluggable trust set consults it. Revoke the signer with one `op:'revoke'` and the pin is gone at DNS-TTL.*

## CAWG: a did:web issuer root you control

The **CAWG Identity Assertion** (v1.2, DIF-ratified) is the layer that binds a named human or organization, distinct from the tool or device that signs the claim. A credential holder signs a `signer_payload` that hash-references the manifest's assertions (including the hard binding), and CAWG defines two credential types: `cawg.x509.cose` (an end-entity X.509 identity cert, COSE-signed) and `cawg.identity_claims_aggregation` (a W3C Verifiable Credential from an identity-claims aggregator). Both inherit the same unresolved question CAWG's own documents flag as urgent: *who anchors the root?*

Two parts of CAWG are already DNS-native, which is what makes the integration clean. First, the ICA credential's `issuer` is, in real deployments, a **did:web**, which resolves through DNS + HTTPS, so it is domain-anchored by construction. A Whisper DNSSEC-signed domain is therefore a first-class did:web *issuer root*: you run your *own* ICA issuer under a name verifiers trust via DNS, instead of re-centralizing on a third-party aggregator. Second, `verifiedIdentities[]` carries a `cawg.web_site` entry whose `uri` is a domain the actor controls. DANE-bind that URI, bind the `cawg.x509.cose` organization cert to the same zone, and a credential that was merely `cawg.identity.well-formed` (valid signature, no root found) becomes `cawg.identity.trusted`, *without* an S/MIME CA.

```bash
# The ICA issuer is a did:web under a Whisper DNSSEC domain: verifiers resolve it via DNS.
# did:web:newsroom.<tenant>.agents.whisper.online  ->  /.well-known/did.json
curl -s https://newsroom.<tenant>.agents.whisper.online/.well-known/did.json | jq '.verificationMethod[0]'
{ "id": "did:web:newsroom.<tenant>.agents.whisper.online#key-1",
  "type": "JsonWebKey2020",
  "publicKeyJwk": { "kty": "EC", "crv": "P-256", "x": "…", "y": "…" } }

# DANE-bind the cawg.web_site.uri + the cawg.x509.cose org cert to the SAME zone.
# "well-formed but unrooted" becomes "trusted", no S/MIME CA in the path.
dig +dnssec TLSA _443._tcp.newsroom.<tenant>.agents.whisper.online +short
3 1 1 c0dea11f...5e0d51f0     ; the org identity cert, pinned in the newsroom's own zone
```

> **Complements CAWG, does not replace it.** The identity-assertion format, the `signer_payload` binding, and the aggregator path all stay exactly as CAWG specifies. `device_id` here is simply the CAWG identity, and the derivation is the same shipped one. Whisper only makes the *issuer root* and the `cawg.web_site` domain resolvable and revocable through DNSSEC/DANE, so cross-org trust needs no shared private list. Note the honest limit: a C2PA/CAWG signature is not a qualified eIDAS signature, and DANE recognition in the standard is a roadmap conversation. See [did:web & VCs](/docs/did-web).

## The signing pipeline: CAI / c2pa-rs, sign with a DANE-anchored key

This is where the shipped *spine* attaches. The CAI open-source signing tools, `c2pa-rs` and its `c2pa-python` / `c2pa-node` bindings (the same libraries the ecosystem already uses to build and sign manifests), take a signer's key and end-entity certificate and emit the COSE_Sign1 claim signature. The integration is to sign with a key whose certificate is **DANE-anchored under a Whisper domain**: the manifest is produced exactly as before, but the signer it references is now self-verifying, with no Trust-List slot and no annual CA fee.

The spine derives that signer's `/128` from the key it already holds. Submit the signer's *public* `SubjectPublicKeyInfo` and pass the C2PA signer-certificate serial as `device_id`; the private key never leaves the signing host, only the public SPKI is ever an input. The derivation is deterministic and tenant-bound: the same key and serial always yield the same `/128` (idempotent re-provisioning), the mapping is unlinkable to outsiders so a publisher's signers cannot be enumerated from their addresses, the serial alone yields nothing without the key, and the result is DNSSEC-anchored, DANE-EE `3 1 1` pinned, and RDAP-registered the instant it is minted.

```
# The spine: derive the signer's /128 from the C2PA signing key it already holds +
# its signer-certificate serial (passed as the generic device_id).
CALL whisper.agents({op:'connect', args:{
  tier:                'wireguard',
  identity_public_key: '<base64 SPKI of the C2PA signing key>',
  device_id:           '4a:72:f9:c1:1b:3d:5e:8f:00:11'   // the C2PA signer-cert serial
}}) YIELD op, ok, status, result, error
   RETURN op, ok, status, result, error
```

Send it with stock tools: the control plane is one HTTP endpoint, the key travels only in the header:

```bash
curl -s https://graph.whisper.security/api/query \
  -H "X-API-Key: whisper_live_xxx" \
  -H "content-type: application/json" \
  --data @- <<'JSON'
{"query":"CALL whisper.agents({op:'connect', args:{tier:'wireguard', identity_public_key:'<base64 SPKI>', device_id:'4a:72:f9:c1:1b:3d:5e:8f:00:11'}}) YIELD op, ok, status, result, error RETURN op, ok, status, result, error"}
JSON
{ "op":"connect", "ok":true, "status":"created",
  "result":{ "address":"2a04:2a01:c0de::51f0",
             "fqdn":"signer-4a7f2c9e.newsroom.<tenant>.agents.whisper.online",
             "wireguard":{ /* peer, keys, allowed-ips */ } } }
```

Then sign as you already do. The CAI pipeline is unchanged; the only difference is the certificate you hand it is the one now pinned in your DNSSEC zone:

```bash
# c2pa-rs (or c2pa-python / c2pa-node) signs the manifest exactly as before:
# the signer cert it embeds is the DANE-anchored one. No SDK change.
c2patool photo.jpg --manifest claim.json \
  --signer-cert signer.pem --signer-key signer.key \
  --output photo-signed.jpg
# manifest embedded: c2pa.hash.data (hard binding) + COSE_Sign1 + x5chain(signer.pem)
# the x5chain leaf's SPKI == the TLSA 3 1 1 pin in the signer's DNSSEC zone
```

The behaviour is honest and predictable, which is the point:

| Re-provision with… | Result |
|---|---|
| the *same* key + serial | `200`: the **same** `/128` returns (idempotent) |
| a *different* serial on the same tenant's key | `409`: the identity is already bound; no silent rebind |
| a non-string serial | `400`: a clear input error, never an opaque 500 |

> **Complements the CAI SDKs, does not replace them.** `c2pa-rs` and the CAI tools stay the signing engine; Whisper only supplies a signer certificate whose trust is anchored in public DNS. A dedicated `--signer-serial` CLI flag is **on the roadmap, not shipped**: today the serial rides in the generic `device_id`, which *is* live. The full derivation, unlinkability property, and DANE mechanics are on [Signer & C2PA identity](/docs/signer-identity).

## Newsroom & camera signers: per-unit revocable device certs

In-camera C2PA signing embeds and signs a manifest *at capture* with a device or manufacturer signing certificate. That's the first-mile provenance that newsroom procurement increasingly requires, shipping now across professional bodies and the first native smartphones. Each such device is an end-entity claim signer; the holder is a *device*, and `device_id` is the device signer-cert serial. The same shape covers a newsroom's own fleet of signing appliances and stringer devices.

The live gap this closes is **revocation granularity**. In 2025, a camera vendor had to suspend its authenticity service and revoke its *entire* set of C2PA device certificates after a security vulnerability: a fleet-wide reset because the trust was pinned per-model, not per-unit, and not restored for a long time. Per-unit identities derived from each device's own hardware key, DNSSEC/DANE-anchored and *individually* revocable, turn that into a one-device, one-call operation: revoke the compromised unit at DNS-TTL and every other camera keeps verifying.

```
# Provision a per-unit device signer from its hardware key + its device-cert serial.
CALL whisper.agents({op:'connect', args:{
  tier:                'wireguard',
  identity_public_key: '<base64 SPKI of the camera's secure-element key>',
  device_id:           'CAM-8830-A7F2-0C41'          // the device signer-cert serial
}})

# A compromised unit: one call, gone worldwide at DNS-TTL. The rest of the fleet is untouched.
CALL whisper.agents({op:'revoke', args:{agent:'2a04:2a01:c0de::cade'}})
# after the TTL: dig -x returns nothing, verify returns false, for THIS unit only
```

```
  per-model cert: the 2025 failure mode      │   per-unit DANE identity: one call, one unit
  one shared device-cert covers the fleet    │   each unit: its own /128 · DANE pin
    [ ✕ ] [ ✕ ] [ ✕ ] [ ✕ ]                  │     [ ✕ ] [ ✓ ] [ ✓ ] [ ✓ ]
  one compromise → fleet-wide revoke, all    │   op:revoke one unit at DNS-TTL,
  dark                                       │   the rest keep verifying
```
*Figure: a per-model certificate makes a single compromise a fleet-wide outage. A per-unit DANE-anchored identity bounds the blast radius to one device and revokes it in a DNS TTL, the granularity the 2025 incident lacked.*

> **Complements in-camera signing and the device CA, does not replace them.** The hardware root of trust stays where it was born: the private key never leaves the secure element, because Whisper consumes only the *public* SPKI, and the device still signs its manifest exactly as C2PA specifies. Whisper adds an independent, domain-controlled anchor that survives a CA incident and a per-unit off-switch. See [Reverse DNS & FCrDNS](/docs/reverse-fcrdns).

## Sign-outputs for AI agents: the agent is its own C2PA signer

When a generative model emits media, the C2PA assertion that marks it is standardized: `c2pa.actions` with `c2pa.created`, plus the IPTC `digitalSourceType` of `trainedAlgorithmicMedia` (fully synthetic) or `compositeWithTrainedAlgorithmicMedia` (AI-assisted). What is *not* settled is *who signed it*: agent and tool stacks have no path to a Trust-List-recognized signer identity. This is the highest-ceiling integration and the most greenfield, and it maps directly onto Whisper's core: an agent's routable `/128` identity *is* a C2PA signer identity.

The agent signs its own C2PA claim, and where it needs to attest a named creator, a CAWG identity assertion, with a Whisper-anchored, DNSSEC/DANE-verifiable, *revocable* identity derived from the key it already holds. A verifier confirms the signer against the DNS root with no list membership; a compromised or retired agent signer is revoked in one call at DNS-TTL, closing the exposure window a stolen signing key otherwise keeps open until an optional OCSP check, if ever.

```
# The per-agent identity is SHIPPED; an agent signing its OWN C2PA claim (sign-outputs) is a proposed pattern.
# Provision the per-agent leaf, then point your C2PA tool's external-signer hook at it.
CALL whisper.agents({op:'connect', args:{
  tier:                'wireguard',
  identity_public_key: '<base64 SPKI of the agent's signing key>',
  device_id:           'agent:renderer-eu-01'          // the agent id, as device_id
}})
  -> 2a04:2a01:c0de::a6e7   DNSSEC + DANE live, RDAP-registered
```

> **i Shipped vs proposed, honestly.** The per-agent `/128` identity, the DANE pin, keyless verify, revoke, and `op:lookups` are **shipped & live**. An agent signing its own C2PA claim under that identity ([sign-outputs](/docs/sign-outputs)) is a **proposed**, forward-looking pattern: today you assemble it by pointing your C2PA tool's external-signer hook at the shipped per-agent leaf, and a turnkey Whisper-native sign-outputs helper is on the roadmap. We flag it as forward-looking rather than dress it up as done.

## See who verified your content: the loop no one else closes

Because C2PA certificates travel in-band in the manifest, a validator makes *no network call* to verify a signer. That means a signer has **zero** visibility into who checked their content, where, or how often. Provenance today is write-only from the signer's side; the only network events are an optional OCSP/CRL fetch and the timestamp authority. This is a genuinely empty quadrant, and a public DNS/DANE anchor fills it as a side-effect.

When a signer identity is DNSSEC/DANE-anchored, a verifier resolving or RDAP-querying that anchor generates lookups against Whisper's own authoritative DNS. `op:'lookups'` returns *who* resolved or queried a signer identity's `PTR`/`AAAA`/`TLSA` records and its RDAP object: a verification-analytics stream C2PA structurally cannot provide, and an early-warning tripwire. A spike of resolutions against a signer you retired, or an impostor cert's serial being checked in the wild, shows up here before it shows up as a takedown.

```
# Who has been resolving / RDAP-querying this signer identity, and when.
# The owner-facing companion to op:'logs' (the signer's OWN activity).
CALL whisper.agents({op:'lookups', args:{agent:'2a04:2a01:c0de::51f0', window:'7d'}})
{ "agent":"2a04:2a01:c0de::51f0", "window":"7d",
  "lookups":[
    {"kind":"TLSA","resolver_asn":"AS15169","count":1840,"first":"…","last":"…"},
    {"kind":"RDAP","source":"verify.example-platform","count":221},
    {"kind":"PTR","resolver_asn":"AS8075","count":96} ] }
```

```
  today (C2PA): write-only
  Verifier ──▶ in-manifest x5chain (no network call) ──▶ Signer: sees nothing ✕

  DANE-anchored: closed loop
  Verifier ──▶ Whisper authoritative DNS (DNSSEC · TLSA · RDAP resolved) ──▶ op:lookups
                                                                   who verified · where · how often ✓
```
*Figure: C2PA verification is offline by design, so the signer learns nothing. Anchor the signer in public DNS and the verifier's own resolutions become `op:'lookups'`, the first verification-analytics loop in the provenance stack.*

> **An honest boundary.** This sees who resolved the *signer anchor*, not who looked at your content. A verifier that validates purely offline still generates no signal, and the counts reflect DANE-aware verifiers, not the whole audience. It is an early-warning and adoption signal, not surveillance of every viewer. See [Egress governance](/docs/egress-governance) for the owner-facing surface.

## The SIEM feed: Splunk, Sentinel & OpenCTI today

Identity, attribution, and verification analytics are only useful to a trust-and-safety or newsroom-security team if they land in the tools it already runs. Whisper emits every finding as a *signed* JSON evidence chain: a `whisper.identify` attribution result naming the operator behind an impersonation host, an `op:'lookups'` spike against a retired signer, an identity mint or revoke from the transparency log. It is machine-readable enrichment for your existing detection and threat-intel, not another console an analyst babysits.

**The Splunk connector is shipped today.** It maps each signed finding onto CEF and ECS fields and forwards it into Splunk, so a signer-impersonation tripwire or a rotating-egress attribution becomes a correlatable event beside the rest of your trust-and-safety telemetry:

```bash
# The signed finding the Splunk connector maps to CEF / ECS and forwards.
curl -s https://graph.whisper.security/api/query \
  -H "X-API-Key: whisper_live_xxx" \
  -H "content-type: application/json" \
  -d '{"query":"CALL whisper.identify(\"185.12.x.x\")"}' | jq '.result.evidence'
# -> a replayable, signed evidence chain -> CEF: deviceVendor=Whisper cs1=operator …
#    (the connector emits one event per finding; the chain re-verifies offline)
```

> **Nothing issued in the dark.** Every signer-identity mint and every revoke is written to a public, append-only [Merkle transparency log](/docs/transparency) (RFC 6962 `tlog-tiles`, Ed25519-signed, anchored to Bitcoin via OpenTimestamps): an auditable, non-repudiable issuance-and-revocation trail a publisher, a platform, and a regulator can replay, and a natural evidence base for an **EU AI Act Art. 50** disclosure record. *Honest status:* the log is tamper-evident, signed, and Bitcoin-anchored today, but it is **not yet independently witnessed**; our two authoritative nodes co-signing is availability, not independence. It already speaks the C2SP `tlog-witness` protocol, so any external witness can co-sign; that step is on the roadmap and we label it as such rather than overclaim.

The **Microsoft Sentinel** connector and **OpenCTI** threat-intelligence integration ship today, mapped onto Sentinel's connector framework and OpenCTI's knowledge graph for continuous-monitoring and disclosure workflows. **STIX 2.1 over TAXII** export is on the roadmap, not shipped. It is listed honestly under [On the roadmap](#on-the-roadmap) below.

## Shipped today vs proposed

Honesty about what runs matters more here than anywhere. The *identity primitive* under every integration is live and provable right now; the *integration guides* themselves are proposed patterns for wiring that primitive into each part of the provenance chain. DANE recognition inside C2PA conformance is a proposal to the standard, not a done deal.

| Building block | Status |
|---|---|
| Deterministic `/128` from a signer's public key + C2PA signer-cert serial (as `device_id`) | **shipped, live** |
| Provision via the control plane (`op:'connect'`, WireGuard tier) | **shipped, live** |
| Keyless verify: `whisper verify --trustless`, `/verify-identity`, `dig -x`, RDAP | **shipped, live** |
| DANE-pin a signer / device / org certificate over DNSSEC (`3 1 1`) | **shipped, live** |
| Revoke: `/128` + PTR + DANE torn down at DNS-TTL speed | **shipped, live** |
| Verification analytics & governance: `op:'lookups'`, `op:'firewall'`, `op:'budget'`, policy | **shipped, live** |
| Attribution graph over the public API (`CALL whisper.identify(…)`) | **shipped, live** |
| **Splunk** connector: signed findings mapped to CEF / ECS | **shipped, live** |
| The integration *guides* on this page (validator trust config, CAWG, CAI signing, camera/newsroom, agent-signing) | **proposed**, our design, not a vendor endorsement |
| DANE/DNSSEC as a recognized C2PA *conformance* trust anchor | **proposed**, complementary today; a proposal to the standard, not approved |

> A dedicated `--signer-serial` CLI flag is **on the roadmap, not shipped**: signer provisioning today goes through the control-plane call shown in the signing-pipeline section above, which *is* live, with the C2PA signer-cert serial passed as the generic `device_id`. The CLI verbs that exist are `whisper verify --trustless`, `whisper create --register`, `whisper kill --revoke`, `whisper policy`, and `whisper logs`.

## On the roadmap

These feed provenance and attribution evidence into the tools a trust-and-safety desk, a newsroom PSIRT, and a compliance team already run. They are **roadmap, not yet shipped**, listed here so you can see where this goes:

- **Microsoft Sentinel connector**: *shipped today*, alongside the **Splunk** connector.
- **OpenCTI** threat-intelligence integration: *shipped today*.
- **STIX 2.1 over TAXII export**: *roadmap*. Maps identity, verification-analytics, and egress evidence onto standard TI transports for continuous-monitoring and Art. 50 disclosure workflows.
- **First-class typed `--signer-serial` argument**: *roadmap*. Today the generic `device_id` already accepts a C2PA signer-cert serial, a CAWG identity, or an agent id.
- **DANE/DNSSEC as a recognized C2PA conformance trust anchor**: *roadmap / a proposal to the standard*. Complementary and CAWG-surfaced today; formal recognition is a standards conversation, not a shipped claim.
- **Independent witnessing of the transparency log**: *roadmap*. Tamper-evident and Bitcoin-anchored today; external co-signing via C2SP `tlog-witness` is the next step.

## Next

- [Signer & C2PA identity](/docs/signer-identity): the shipped derivation these integrations all build on
- [Provenance-gap cure](/docs/provenance-gap-cure), the primary wedge: a publicly verifiable signer, no trust-list gatekeeper
- [EU AI Act · C2PA · ISO 22144](/docs/content-compliance): where the evidence lands for Art. 50 and Recital 133

[← Provenance-gap cure](/docs/provenance-gap-cure) · [EU AI Act · C2PA · ISO 22144 →](/docs/content-compliance)
