Manifests

CAWG Identity Assertions

Overview

CAWG identity assertions let you prove control over a digital identity and record a creator’s role in an asset’s lifecycle.
You can embed these assertions in a C2PA manifest during asset signing, or validate them during verification.

Identity assertions are useful when you want to:

  • Organizations: Prove authorship using X.509 certificates tied to trusted entities (e.g. publishers, media companies).
  • Individuals: Prove authorship using verified signals from identity providers (e.g. websites, social accounts, affiliations).

Good to Know

Que can validate all CAWG identity assertions. Signing is only supported when using X.509 certificates.


Quickstart

Here’s the minimal example to add a CAWG identity assertion during signing:

import { Que } from "que-sdk";

const que = new Que({
  apiKeyAuth: process.env["QUE_API_KEY_AUTH"] ?? "",
});

const result = await que.signAsset({
  asset: {
    bucket: "que-assets-dev",
    key: "uploads/photo.jpg",
  },
  manifestJson: JSON.stringify({
    title: "Original Photo",
    assertions: [{
      label: "cawg.identity",
      data: {
        "@context": [
          "https://www.w3.org/ns/credentials/v2",
          "https://cawg.io/identity/1.1/ica/context/"
        ],
        "type": ["VerifiableCredential", "IdentityClaimsAggregationCredential"],
        "issuer": "did:web:trusted.idbroker.com",
        "validFrom": "2025-04-29T17:34:44Z",
        "verifiedIdentities": [{
          "type": "cawg.social_media",
          "username": "xyz",
          "uri": "https://www.instagram.com/xyz",
          "verifiedAt": "2024-10-08T18:04:08Z",
          "provider": { "id": "https://instagram.com", "name": "instagram" }
        }]
      }
    }]
  })
});

console.log(result.asset.s3Uri);
import os
import json
from que_media import Que

with Que(
    api_key_auth=os.getenv("QUE_API_KEY_AUTH", ""),
) as que:

    res = que.sign_asset(asset={
        "bucket": "que-assets-dev",
        "key": "uploads/photo.jpg"
    }, manifest_json=json.dumps({
        "title": "Original Photo",
        "assertions": [{
            "label": "cawg.identity",
            "data": {
                "@context": [
                    "https://www.w3.org/ns/credentials/v2",
                    "https://cawg.io/identity/1.1/ica/context/"
                ],
                "type": ["VerifiableCredential", "IdentityClaimsAggregationCredential"],
                "issuer": "did:web:trusted.idbroker.com",
                "validFrom": "2025-04-29T17:34:44Z",
                "verifiedIdentities": [{
                    "type": "cawg.social_media",
                    "username": "xyz",
                    "uri": "https://www.instagram.com/xyz",
                    "verifiedAt": "2024-10-08T18:04:08Z",
                    "provider": { "id": "https://instagram.com", "name": "instagram" }
                }]
            }
        }]
    }))

    print(res.asset.s3_uri)
client := que.NewClient(os.Getenv("QUE_API_KEY"))

res, err := client.SignAsset(que.SignRequest{
    Asset: que.Asset{Bucket: "que-assets-dev", Key: "uploads/photo.jpg"},
    Mode: "server_measure",
    ManifestJson: `{"title":"Original Photo"}`,
    Cawg: &que.CawgIdentityDto{
        Signer: que.Signer{Type: "use_main_signer"},
        SigningAlg: "ed25519",
        ReferencedAssertions: []string{"c2pa.actions"},
    },
})
if err != nil { panic(err) }

fmt.Println(res.AssetS3Uri)
use que::{Client, SignRequest, Asset};
use std::env;

#[tokio::main]
async fn main() {
    let client = Client::new(env::var("QUE_API_KEY").unwrap());
    let res = client.sign_asset(SignRequest {
        asset: Asset {
            bucket: "que-assets-dev".into(),
            key: "uploads/photo.jpg".into(),
        },
        mode: "server_measure".into(),
        manifest_json: r#"{"title":"Original Photo"}"#.into(),
        cawg: Some(que::CawgIdentityDto {
            signer: que::Signer::UseMainSigner,
            signing_alg: "ed25519".into(),
            referenced_assertions: vec!["c2pa.actions".into()],
        }),
        ..Default::default()
    }).await.unwrap();

    println!("{}", res.asset_s3_uri.unwrap());
}
package hello.world;

import java.lang.Exception;
import org.openapis.openapi.Que;
import org.openapis.openapi.models.components.*;
import org.openapis.openapi.models.errors.ProblemResponseException;
import org.openapis.openapi.models.operations.SignAssetResponse;

public class CawgExample {

    public static void main(String[] args) throws ProblemResponseException, ProblemResponseException, ProblemResponseException, Exception {

        Que sdk = Que.builder()
                .apiKeyAuth(System.getenv().getOrDefault("API_KEY_AUTH", ""))
            .build();

        SignRequest req = SignRequest.builder()
                .asset(AssetRefDto.of(S3.builder()
                    .bucket("que-assets-dev")
                    .key("uploads/photo.jpg")
                    .build()))
                .manifestJson("{\"title\":\"Original Photo\",\"assertions\":[{\"label\":\"cawg.identity\",\"data\":{\"@context\":[\"https://www.w3.org/ns/credentials/v2\",\"https://cawg.io/identity/1.1/ica/context/\"],\"type\":[\"VerifiableCredential\",\"IdentityClaimsAggregationCredential\"],\"issuer\":\"did:web:trusted.idbroker.com\",\"validFrom\":\"2025-04-29T17:34:44Z\",\"verifiedIdentities\":[{\"type\":\"cawg.social_media\",\"username\":\"xyz\",\"uri\":\"https://www.instagram.com/xyz\",\"verifiedAt\":\"2024-10-08T18:04:08Z\",\"provider\":{\"id\":\"https://instagram.com\",\"name\":\"instagram\"}}]}}]}")
                .build();

        SignAssetResponse res = sdk.signAsset()
                .request(req)
                .call();

        if (res.signResponse().isPresent()) {
            System.out.println(res.signResponse().get().asset().s3Uri());
        }
    }
}
<?php
declare(strict_types=1);

require 'vendor/autoload.php';

use Que;
use Que\Models\Components;

$sdk = Que\Que::builder()
    ->setSecurity(getenv('QUE_API_KEY_AUTH') ?: '')
    ->build();

$signRequest = new Components\SignRequest(
    asset: new Components\S3(
        bucket: 'que-assets-dev',
        key: 'uploads/photo.jpg'
    ),
    manifestJson: json_encode([
        'title' => 'Original Photo',
        'assertions' => [[
            'label' => 'cawg.identity',
            'data' => [
                '@context' => [
                    'https://www.w3.org/ns/credentials/v2',
                    'https://cawg.io/identity/1.1/ica/context/'
                ],
                'type' => ['VerifiableCredential', 'IdentityClaimsAggregationCredential'],
                'issuer' => 'did:web:trusted.idbroker.com',
                'validFrom' => '2025-04-29T17:34:44Z',
                'verifiedIdentities' => [[
                    'type' => 'cawg.social_media',
                    'username' => 'xyz',
                    'uri' => 'https://www.instagram.com/xyz',
                    'verifiedAt' => '2024-10-08T18:04:08Z',
                    'provider' => [
                        'id' => 'https://instagram.com',
                        'name' => 'instagram'
                    ]
                ]]
            ]
        ]]
    ])
);

$response = $sdk->signAsset(
    request: $signRequest
);

if ($response->signResponse !== null) {
    echo $response->signResponse->asset->s3Uri;
}
?>

Identity Assertion Types

You can add CAWG identity information in two main ways:

1. X.509 Certificate Assertions

  • Prove identity using a cryptographic certificate.
  • Enterprise-friendly (e.g. newsrooms, publishers).
  • Can be validated and signed by Que.

2. Aggregated Identity Claims

  • Collect identity signals from trusted providers (websites, social accounts, ID checks).
  • Good for individual creators.
  • Que can validate these claims. Signing not supported.

Example JSON Payloads

X.509 Certificate Assertion

"cawg": {
  "signer": { "type": "use_main_signer" },
  "signing_alg": "ed25519",
  "referenced_assertions": ["c2pa.actions"],
  "timestamper": "digicert"
}

Identity Claim Aggregator

"assertions": [
  {
    "label": "cawg.identity",
    "data": {
      "@context": [
        "https://www.w3.org/ns/credentials/v2",
        "https://cawg.io/identity/1.1/ica/context/"
      ],
      "type": ["VerifiableCredential", "IdentityClaimsAggregationCredential"],
      "issuer": "did:web:trusted.idbroker.com",
      "validFrom": "2025-04-29T17:34:44Z",
      "verifiedIdentities": [
        {
          "type": "cawg.social_media",
          "username": "xyz",
          "uri": "https://www.instagram.com/xyz",
          "verifiedAt": "2024-10-08T18:04:08Z",
          "provider": { "id": "https://instagram.com", "name": "instagram" }
        }
      ]
    }
  }
]

Verified Identity Types

The verifiedIdentities[].type can be one of:

ValueMeaning
cawg.document_verificationVerified with government-issued documents
cawg.web_siteOwnership of a website or domain
cawg.affiliationProof of organizational membership or employment
cawg.social_mediaVerified control of a social account
cawg.crypto_walletVerified control of a crypto wallet or blockchain account

Next Steps