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:

TypeUse Case
taskTask assignments, work requests
messageInter-agent messages
resultTask results, responses

You can use any string -- these are conventions, not enforced types.

What Gets Signed

Every signed artifact includes:

FieldDescription
jacsIdUnique document ID
jacsSignatureSigner ID, algorithm, timestamp, and base64 signature
jacsSha256Content hash for integrity verification
jacsTypeThe artifact type label
jacsParentSignaturesParent artifacts for chain of custody (if any)
payloadThe original artifact data

Non-JACS receivers can safely ignore the jacs* fields and extract payload directly.

Next Steps