Skip to content

Content Attestation

At negotiation time, the Exchange describes content by metadata: title, tokens, URI, pricing. At delivery time, the agent receives bytes from the CDN. Nothing cryptographically ties the negotiated metadata to the delivered content — unless someone pre-committed verifiable claims about those bytes.

The Exchange does not ingest or deliver content. It holds catalog metadata only. The CDN delivers directly to the agent. Content attestation solves this by having a trusted party sign claims about the content before negotiation.

LevelAttesterTrust ModelAuto-Disputable Claims
0 — NoneNobodyNo attestationCDN delivery failure only (4xx/5xx)
1 — Self-attestedProviderProvider signs own claims (Ed25519)Delivery failure + content hash mismatch
2 — Third-partyVerification vendorIndependent measurementDelivery failure + token count discrepancy (with CDN corroboration)

Content identifiers (DOI, ISBN, IPTC GUID) are orthogonal to attestation level. A Level 0 article may carry a DOI — that identifies what content it is but does not verify that the delivered bytes match.

message ResourceAttestation {
string verifier = 1;
string kid = 2;
google.protobuf.Timestamp attested_at = 3;
string uri = 4;
google.protobuf.Struct claims = 5;
string signature = 6;
}
FieldDescription
verifierDomain of the attesting party. Keys published at https://{verifier}/.well-known/ramp-verifier.json
kidKey ID from the verifier’s JWKS. Enables key rotation
attested_atWhen the attester measured the content. Agents use this for freshness checks
uriContent URI this attestation covers. Must match the Offer URI
claimsJSON claims about the content (max 4KB). See Claims Vocabulary
signatureEd25519 over JCS-canonicalized (RFC 8785) representation of all other fields

Example: Provider Self-Attestation (Level 1)

Section titled “Example: Provider Self-Attestation (Level 1)”
{
"verifier": "nytimes.com",
"kid": "nyt-2026-Q1",
"attested_at": "2026-03-18T09:00:00Z",
"uri": "https://nytimes.com/2026/03/18/tech/ai-content-licensing.html",
"claims": {
"content_hash": "sha256:a1b2c3d4e5f6...",
"hash_method": "sha256",
"estimated_quantity": 3200,
"word_count": 2424,
"language": "en"
},
"signature": "base64-encoded-ed25519-signature"
}

Example: Third-Party Vendor Attestation (Level 2)

Section titled “Example: Third-Party Vendor Attestation (Level 2)”
{
"verifier": "doubleverify.com",
"kid": "dv-2026-Q1",
"attested_at": "2026-03-18T08:45:00Z",
"uri": "https://example-news.com/article/breaking-story",
"claims": {
"estimated_quantity": 2450,
"language": "en",
"iab_categories": ["News", "Technology"],
"content_hash": "doubleverify-v1:x9y8z7...",
"hash_method": "doubleverify-v1"
},
"signature": "base64-encoded-ed25519-signature"
}

Every party that signs attestations MUST publish their keys and claims schema at:

https://{verifier-domain}/.well-known/ramp-verifier.json
{
"verifier": "nytimes.com",
"name": "The New York Times",
"claims_schema": {
"content_hash": {
"type": "string",
"description": "SHA-256 hash of delivered content bytes"
},
"estimated_quantity": {
"type": "integer",
"description": "Estimated consumption quantity computed by NYT CMS"
},
"language": {
"type": "string",
"description": "ISO 639-1 language code"
}
},
"keys": [
{
"kid": "nyt-2026-Q1",
"algorithm": "ed25519",
"public_key": "MCowBQYDK2VwAyEA...",
"valid_from": "2026-01-01T00:00:00Z",
"valid_until": "2026-12-31T23:59:59Z"
}
]
}

Key rotation follows the JWKS pattern: new keys are added with overlapping valid_from, old keys are retained for verification until all signed attestations using them have expired from catalogs.

ClaimTypeAuto-Disputable?Description
estimated_quantityintegerYes (with CDN corroboration)Estimated consumption quantity (tokens, pages, seconds, etc.)
word_countintegerNoWord count (~estimated_quantity * 0.76 for text)
languagestringNoISO 639-1 language code
iab_categoriesstring[]NoIAB Content Taxonomy 3.1 codes
content_hashstringYes (Level 1 only)Hash in method:hexdigest format
hash_methodstringNoAlgorithm for content_hash
titlestringNoArticle headline

Only estimated_quantity and content_hash are auto-disputable — they are objectively measurable and independently verifiable. Vendors may add proprietary claims (e.g., brand_safety, sentiment) documented in their ramp-verifier.json claims_schema.

  1. Build a JSON object with the five signed fields: verifier, kid, attested_at, uri, claims
  2. Apply JCS canonicalization (RFC 8785) — lexicographic key sorting, no whitespace, ECMAScript number format
  3. Sign the canonical bytes with Ed25519
canonical_bytes = utf8_encode(jcs_output)
signature = ed25519_sign(canonical_bytes, private_key)
attestation.signature = base64_encode(signature)

An offer may carry multiple attestations from different parties:

Agent Trust PolicyBehavior
Trust provider onlyVerify provider attestation (Level 1), ignore vendor
Trust vendor onlyUse vendor attestation (Level 2), ignore provider
Trust both, prefer vendorVendor’s estimated_quantity for unit cost calculation, provider’s content_hash for delivery verification
Require bothOnly transact if both are present. Highest assurance

The protocol does not mandate a maximum attestation age. Suggested thresholds:

Content TypeMax Attestation Age
Breaking news1—4 hours
Daily news24 hours
Evergreen articles7—30 days
Academic papers90+ days