Supported library reference. Rust, Node.js, Python and Go remain supported in a separate workspace. This chapter can contain historical version or installation text; use the current package guide. Extended CLI examples use
jacs-compatin 0.15. See the current MCP guide for actual runtime profiles and the release inventory for published versions.
Exchange Signed Artifacts
Sign artifacts with cryptographic provenance and verify artifacts from other agents.
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])
# chain contains: steps (ordered), signers, timestamps, 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 | The artifact type label |
jacsParentSignatures | Parent artifacts for chain of custody (if any) |
payload | The original artifact data |
Non-JACS receivers can safely ignore the jacs* fields and extract payload directly.
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