The normative definition of the Trulioo KYA trust block carried on an
A2A Agent Card. This URL is the extension identifier -
an A2A client that sees this uri resolves it here.
KYA attaches as an AgentExtension under
capabilities.extensions[] (never a top-level card field). The whole card is
signed in signatures[].
{
"capabilities": {
"extensions": [{
"uri": "https://identity.trulioo.com/a2a/kya/v1",
"description": "Trulioo KYA verified-identity attestation.",
"required": true,
"params": { /* KYA block - see schema.json */ }
}]
}
}
params)params has three members, two of them required.
attestation is the
authoritative compact JWS a verifier MUST check; display is a
non-authoritative mirror of the signed claims, for rendering only.
{
"attestation": "<compact JWS>", // typ=kya-attestation+jwt, alg=EdDSA - THE source of truth
"display": { // mirror of the JWS payload; do NOT trust independently
"verified": true,
"verified_as_of": "2026-07-02T00:00:00Z",
"allowed_scopes": ["purchase"], // signed mandate scope
"issuer": "https://identity.trulioo.com",
"fingerprint": "<sha256, binds to the card>"
}
}
The JWS payload (decode attestation) carries the header claims
iss, sub (=fingerprint), iat, exp plus the same
block fields flattened. display is exactly that payload minus the JWT envelope.
dap reference (optional, v3)A third, OPTIONAL member points at the agent's Digital Agent Profile. It is a reference, never an inlined credential.
{
"dap": {
"vct": "https://identity.trulioo.com/vct/agent-profile.1",
"suite": "ats-v2",
"issuer": "https://identity.trulioo.com", // PIN this JWKS
"verify_endpoint": "https://identity.trulioo.com/kya/dap/verify",
"presentation_endpoint": "https://agent.example.com/dap/present" // AGENT-hosted, optional
}
}
Why not embed the passport: an agent card is a long-lived, cacheable
document served to everyone, while a DAP is a ≤600s credential that only means
anything when presented with a Key-Binding JWT bound to one verifier's audience
and nonce. Inlining one would ship bytes past their exp, discard the
holder-of-key proof (any card reader could replay the credential as its own), and
destroy selective disclosure. presentation_endpoint is agent-hosted and is
never defaulted to an identity.trulioo.com URL: only the agent holds the
cnf private key, so the issuer cannot present on its behalf.
attestation JWS is authoritative. A verifier MUST verify it and MUST NOT
trust display on its own (display is a convenience copy).verified is a boolean - a minimized assertion. There is deliberately
no ordinal trust score (not audit-defensible). Screening is not a standing
boolean here: it is an optional, provenanced screening claim on the DAP,
present only when a screen ran (a hit/review drives revocation) - not carried on this block.allowed_scopes are the mandate's signed actions - signed + auditable, but
enforced by the relying party at the handshake, not by Trulioo.fingerprint MUST equal the recomputed card fingerprint AND the JWS
sub; a verifier MUST reject on mismatch. It excludes signatures[].kid from the issuer JWKS and use
that key's permitted algorithm - never the token's alg header. Reject alg:none.verified:false as a hard reject.Fetch the issuer keys, then verify the attestation offline; or look up
by fingerprint (public, no key):
# issuer signing keys curl -s "https://identity.trulioo.com/.well-known/jwks.json" # public look-up (independent re-check by fingerprint) curl -s "https://identity.trulioo.com/kya/attestation/<fingerprint>"
/v1 path segment;
new OPTIONAL members do not - agent_id/build_id (v2) and
dap (v3) were added this way, so "v2"/"v3" name the claim generation, not a
new URI. A v1-only verifier reading a v3 block sees only the members it knew and behaves
identically. Note the widening is one-way: params and display
are additionalProperties: false, so the schema must name a member before any
card emits it.
The namespace URI (https://identity.trulioo.com/a2a/kya/v1) is the contract -
a stable identifier string-matched by relying parties, served from the issuer host.
Source: commerce/halo/docs/kya-a2a-extension-spec.md.