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:
Value | Meaning |
---|---|
cawg.document_verification | Verified with government-issued documents |
cawg.web_site | Ownership of a website or domain |
cawg.affiliation | Proof of organizational membership or employment |
cawg.social_media | Verified control of a social account |
cawg.crypto_wallet | Verified control of a crypto wallet or blockchain account |
Next Steps
- Learn how to Sign Assets with Que
- See how to Verify and Validate Identity Assertions