Identity
C2PA separates two questions a viewer can ask about a signed asset: who cryptographically signed this and who claims responsibility for the content. Limbo Integrity follows that split.
- The signing certificate is the organization-level X.509 chain that Limbo provisions and manages for you. It is attached to every signature automatically; the SDK does not configure the chain directly.
- The identity assertion is a per-asset statement describing who authored or published the content. It is attached as a CAWG (Creator Assertions Working Group) assertion alongside the signed claim.
This split matters because most publishers sign with a single corporate certificate across thousands of contributors. The certificate proves the organization signed; the CAWG assertion proves which party within the organization authorized the asset. A verifier can reach Trusted on the certificate chain (the configured trust list permits it) while still rendering a per-asset byline, so "M. Okafor, editorial desk" shows even though the chain identifies only "Newsroom Org".
To attach a verified identity (a byline, a brand, a responsible party) to a specific asset, pass an identity field on the manifest spec.
Shape
const { sidecar } = await sdk.sign(bytes, "...", {
origin: { sourceType: "digitalCapture" },
identity: {
roles: ["cawg.creator"],
identities: [
{
type: "cawg.social_media",
name: "Newsroom Desk",
username: "newsroom",
uri: "https://newsroom.example.com/cawg",
verifiedAt: "2026-01-15T00:00:00Z",
provider: { id: "https://newsroom.example.com", name: "Newsroom Org" },
},
],
},
}, { storage: { mode: "embedded" } });
identity is an IdentityOptions object: { roles, identities }. roles is an array of strings describing the actions those identities performed. identities is an array of CAWG VerifiedIdentity objects. Each entry requires type (e.g. cawg.social_media, cawg.email), verifiedAt (ISO-8601), and a provider ({ id, name }); name, username, and uri describe the party. The Signer validates the array and embeds it as a signed CAWG identity-aggregation assertion, so the shape above must be complete: omitting a required field (or using display_name instead of name) fails the signing request.
Reusing a default identity
Most pipelines define a default identity once and reuse it across calls.
import { type IdentityOptions } from "@limboai/verifox-sdk-issuer";
const DEFAULT_IDENTITY: IdentityOptions = {
roles: ["cawg.creator"],
identities: [
{
type: "cawg.social_media",
name: "Newsroom Desk",
username: "newsroom",
uri: "https://newsroom.example.com/cawg",
verifiedAt: "2026-01-15T00:00:00Z",
provider: { id: "https://newsroom.example.com", name: "Newsroom Org" },
},
],
};
await sdk.sign(bytes, "...", {
origin: { sourceType: "digitalCapture" },
identity: DEFAULT_IDENTITY,
}, { storage: { mode: "embedded" } });
For per-story bylines, construct the identity object inline at the call site.
Verifier-side trust
The identity assertion is only meaningful when the verifier trusts the signing certificate. See Trust anchors.
See also
- Assertions: the
{ label, data }assertion array - Sign an asset: the full
signcall - Trust anchors: verifier-side trust configuration