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"}, "task")
# 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"}, "message")
# Agent B signs step 2, referencing step 1 as parent
step2 = client_b.sign_artifact(
{"step": 2, "data": "processed"},
"message",
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