Native library reference. Extended CLI examples use
jacs-compat. This source reference can include unreleased changes; see the package guide for installation and MCP profiles for available tools.
Exchange Signed Artifacts
Sign artifacts with cryptographic provenance and verify artifacts from other agents. Node.js snippets run inside an async function. For multi-agent examples, create separate clients/configurations and independently authenticate each signer's public evidence and configure the verifier's key resolver before verification. Native artifact verification uses a trust-store enrollment for v2 artifacts signed by the exact enrolled agent_id:version; otherwise it uses its local public-key cache or opt-in registry or DNS/HTTPS key discovery. See cross-agent setup.
Sign and Verify
from jacs.client import JacsClient
client = JacsClient.quickstart(name="my-agent", domain="my-agent.example.com")
# Sign an artifact
signed = client.sign_artifact({"action": "classify", "input": "data"}, "artifact")
# Verify it (with trust assessment)
a2a = client.get_a2a()
result = a2a.verify_wrapped_artifact(signed, assess_trust=True)
print(f"Valid: {result['valid']}, Allowed: {result['trust']['allowed']}")
Chain of Custody
When multiple agents process data in sequence, link artifacts into a verifiable chain:
# Agent A signs step 1
step1 = client_a.sign_artifact({"step": 1, "data": "raw"}, "artifact")
# Agent B signs step 2, referencing step 1 as parent
step2 = client_b.sign_artifact(
{"step": 2, "data": "processed"},
"artifact",
parent_signatures=[step1],
)
# Verify the full chain
result = a2a.verify_wrapped_artifact(step2)
assert result["valid"]
assert result["parent_signatures_valid"]
Build an Audit Trail
chain = a2a.create_chain_of_custody([step1, step2])
# Metadata only: chainOfCustody, created, totalArtifacts.
# This helper does not verify signatures, ordering or validity.
Sign and Verify
const { JacsClient } = require('@hai.ai/jacs/client');
const client = await JacsClient.quickstart({
name: 'my-agent',
domain: 'my-agent.example.com',
});
// Sign an artifact
const signed = await client.signArtifact({ action: 'classify', input: 'data' }, 'task');
// Verify it
const a2a = client.getA2A();
const result = a2a.verifyWrappedArtifact(signed);
console.log(`Valid: ${result.valid}`);
Chain of Custody
// Agent A signs step 1
const step1 = await clientA.signArtifact({ step: 1, data: 'raw' }, 'message');
// Agent B signs step 2, referencing step 1
const step2 = await clientB.signArtifact(
{ step: 2, data: 'processed' }, 'message', [step1],
);
// Verify the full chain
const result = a2a.verifyWrappedArtifact(step2);
console.log(`Chain valid: ${result.valid}`);
console.log(`Parents valid: ${result.parentSignaturesValid}`);
Artifact Types
The artifact_type parameter labels the payload for downstream processing:
| Type | Use Case |
|---|---|
task | Task assignments, work requests |
message | Inter-agent messages |
result | Task results, responses |
You can use any string -- these are conventions, not enforced types.
What Gets Signed
Every signed artifact includes:
| Field | Description |
|---|---|
jacsId | Unique document ID |
jacsSignature | Signer ID, algorithm, timestamp, and base64 signature |
jacsSha256 | Content hash for integrity verification |
jacsType | a2a- followed by the caller's artifact type label |
jacsParentSignatures | Parent artifacts for chain of custody (if any) |
a2aArtifact | The original artifact data |
Extract a2aArtifact only after the required signature and trust checks. Discarding the envelope also discards its provenance.
Next Steps
- Serve Your Agent Card -- Make your agent discoverable
- Discover & Trust Remote Agents -- Find and assess other agents
- A2A Interoperability Reference -- Full API reference
- Hero Demo (Python) -- 3-agent trust verification example