JACS - JSON AI Communication Standard: Cryptographic signing and verification for AI agents.
Project description
JACS Python Library
Python bindings for JACS (JSON Agent Communication Standard) -- an open data provenance toolkit for signing and verifying AI agent communications. JACS works standalone with no server required; optionally register with HAI.ai for cross-organization key discovery.
# Using uv (recommended)
uv pip install jacs
# Or with pip
pip install jacs
# With HAI.ai integration
uv pip install jacs[hai]
Packaging/build metadata is defined in pyproject.toml (maturin). setup.py is intentionally not used.
To check dependencies for known vulnerabilities when using optional extras, run pip audit (or safety check).
Quick Start (Simplified API)
The simplified API gets you signing in under 2 minutes:
import jacs.simple as jacs
# Load your agent
agent = jacs.load("./jacs.config.json")
# Sign a message (accepts dict, list, str, or any JSON-serializable data)
signed = jacs.sign_message({"action": "approve", "amount": 100})
print(f"Signed by: {signed.agent_id}")
# Verify it
result = jacs.verify(signed.raw)
print(f"Valid: {result.valid}")
# Sign a file
signed_file = jacs.sign_file("document.pdf", embed=True)
# Update agent metadata
agent_doc = json.loads(jacs.export_agent())
agent_doc["jacsAgentType"] = "updated-service"
updated = jacs.update_agent(agent_doc)
# Update a document
doc = json.loads(signed.raw)
doc["content"]["status"] = "approved"
updated_doc = jacs.update_document(signed.document_id, doc)
Core Operations
The simplified API provides these core operations:
| Operation | Description |
|---|---|
create() |
Create a new agent programmatically (non-interactive) |
load() |
Load an existing agent from config |
verify_self() |
Verify the loaded agent's integrity |
update_agent() |
Update the agent document with new data |
update_document() |
Update an existing document with new data |
sign_message() |
Sign a text message or JSON data |
sign_file() |
Sign a file with optional embedding |
verify() |
Verify any signed document (JSON string) |
verify_standalone() |
Verify without loading an agent (one-off) |
verify_by_id() |
Verify a document by its storage ID (uuid:version) |
get_dns_record() |
Get DNS TXT record line for the agent |
get_well_known_json() |
Get well-known JSON for /.well-known/jacs-pubkey.json |
reencrypt_key() |
Re-encrypt the private key with a new password |
trust_agent() |
Add an agent to the local trust store |
list_trusted_agents() |
List all trusted agent IDs |
untrust_agent() |
Remove an agent from the trust store |
is_trusted() |
Check if an agent is trusted |
get_trusted_agent() |
Get a trusted agent's JSON document |
audit() |
Run a read-only security audit (returns risks, health_checks, summary) |
generate_verify_link() |
Generate a shareable hai.ai verification URL for a signed document |
Programmatic Agent Creation
import jacs.simple as jacs
# Create an agent without interactive prompts
agent = jacs.create(
name="my-agent",
password="Str0ng-P@ssw0rd!", # or set JACS_PRIVATE_KEY_PASSWORD env var
algorithm="pq2025", # default; also: "ring-Ed25519", "RSA-PSS"
data_directory="./jacs_data",
key_directory="./jacs_keys",
)
print(f"Created agent: {agent.agent_id}")
Verify by Document ID
# If you have a document ID instead of the full JSON
result = jacs.verify_by_id("550e8400-e29b-41d4-a716-446655440000:1")
print(f"Valid: {result.valid}")
Re-encrypt Private Key
jacs.reencrypt_key("old-password-123!", "new-Str0ng-P@ss!")
Password Requirements
Passwords must be at least 8 characters and include uppercase, lowercase, a digit, and a special character.
Algorithm Deprecation Notice
The pq-dilithium algorithm is deprecated. Use pq2025 (ML-DSA-87, FIPS-204) instead. pq-dilithium still works but emits deprecation warnings.
Type Definitions
from jacs import AgentInfo, SignedDocument, VerificationResult
# All return types are dataclasses with clear fields
agent: AgentInfo = jacs.load()
signed: SignedDocument = jacs.sign_message({"data": "hello"})
result: VerificationResult = jacs.verify(signed.raw)
MCP Integration
For AI tool servers using the Model Context Protocol:
from fastmcp import FastMCP
import jacs.simple as jacs
mcp = FastMCP("My Server")
jacs.load("./jacs.config.json")
@mcp.tool()
def signed_hello(name: str) -> dict:
signed = jacs.sign_message({"greeting": f"Hello, {name}!"})
return {"response": signed.raw}
JacsAgent Class (Advanced)
For more control, use the JacsAgent class directly:
from jacs import JacsAgent
agent = JacsAgent()
agent.load("./jacs.config.json")
# Sign raw strings
signature = agent.sign_string("data to sign")
# Verify documents
is_valid = agent.verify_document(document_json)
# Create documents with schemas
doc = agent.create_document(json_string, schema=None)
A2A Protocol Support
JACS supports Google's Agent-to-Agent (A2A) protocol:
from jacs.a2a import JACSA2AIntegration
a2a = JACSA2AIntegration("jacs.config.json")
agent_card = a2a.export_agent_card(agent_data)
wrapped = a2a.wrap_artifact_with_provenance(artifact, "task")
HAI.ai Integration
HAI.ai is a platform for agent-to-agent agreements and conflict resolution, providing cryptographic attestation of agent capabilities.
Quick Registration
from jacs.hai import HaiClient
import jacs.simple as jacs
# Load your JACS agent
jacs.load("./jacs.config.json")
# Connect to HAI.ai
hai = HaiClient()
# Test connection
if hai.testconnection("https://hai.ai"):
# Register your agent
result = hai.register("https://hai.ai", api_key="your-api-key")
print(f"Registered: {result.agent_id}")
Prerequisites
- JACS agent created (see Quick Start)
- API key from HAI.ai (visit https://hai.ai/developers)
Available Methods
| Method | Description |
|---|---|
testconnection() |
Test HAI.ai connectivity |
register() |
Register agent with HAI.ai |
verify_agent() |
Verify another agent's trust level |
status() |
Check registration status |
benchmark() |
Run benchmark suite |
connect() |
Connect to SSE event stream |
Agent Verification Levels
JACS agents can be verified at three trust levels:
| Level | Badge | What it proves |
|---|---|---|
| 1 | Basic | Agent holds a valid private key (self-signed) |
| 2 | Domain | Agent owner controls a DNS domain |
| 3 | Attested | HAI.ai has verified and co-signed the agent |
from jacs.hai import verify_agent
# Verify another agent meets your trust requirements
result = verify_agent(sender_agent_doc, min_level=2)
if result.valid:
print(f"Verified: {result.agent_id} (Level {result.level}: {result.level_name})")
else:
print(f"Verification failed: {result.errors}")
Examples
examples/hai_quickstart.py- 5-minute quickstartexamples/register_with_hai.py- Complete registration example
Installation
# Basic installation
pip install jacs
# With MCP support
pip install jacs[mcp]
# With HAI.ai integration
pip install jacs[hai]
Examples
See the examples/ directory:
quickstart.py- Basic signing and verificationsign_file.py- File signing with embeddingsmcp_server.py- Authenticated MCP serverp2p_exchange.py- Peer-to-peer trust establishment
Development
Using uv (recommended):
# Quick start with Makefile
make setup # Install all dependencies
make dev # Build for development
make test # Run all tests
# Or manually:
uv venv && source .venv/bin/activate
uv pip install maturin pytest httpx httpx-sse
uv run maturin develop
uv run python -m pytest tests/ -v
Available Make Commands
| Command | Description |
|---|---|
make setup |
Install dev dependencies with uv |
make dev |
Build Rust extension for development |
make test |
Run all tests (Python + HAI) |
make test-hai |
Run HAI integration tests only |
make check-imports |
Verify all imports work |
Documentation
- JACS Book - Full documentation (published book)
- Quick Start
- API Reference - Python API docs
- Migration Guide - Upgrading from v0.4.x
- Source - GitHub repository
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file jacs-0.6.0.tar.gz.
File metadata
- Download URL: jacs-0.6.0.tar.gz
- Upload date:
- Size: 518.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
56b25cb129ab8231d8e8ea971fb5e13c477672538085cc3e28ad4bb72e222b35
|
|
| MD5 |
fa3497df83b8aa57d4a80142600a1c79
|
|
| BLAKE2b-256 |
136b51ee179499f705859ec9ee4718c13c510f009a24ac59181f9cb3769d383c
|
Provenance
The following attestation bundles were made for jacs-0.6.0.tar.gz:
Publisher:
release-pypi.yml on HumanAssisted/JACS
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jacs-0.6.0.tar.gz -
Subject digest:
56b25cb129ab8231d8e8ea971fb5e13c477672538085cc3e28ad4bb72e222b35 - Sigstore transparency entry: 929127720
- Sigstore integration time:
-
Permalink:
HumanAssisted/JACS@2c1d78366e7bc09491d3424f5ac2b8bc956c39ed -
Branch / Tag:
refs/tags/pypi/v0.6.0 - Owner: https://github.com/HumanAssisted
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@2c1d78366e7bc09491d3424f5ac2b8bc956c39ed -
Trigger Event:
push
-
Statement type:
File details
Details for the file jacs-0.6.0-cp310-abi3-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: jacs-0.6.0-cp310-abi3-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 6.2 MB
- Tags: CPython 3.10+, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7686971eaf45f125595c5e12cfa02ca5ca9820bfc43f8fefefa495c1cdd42783
|
|
| MD5 |
635fca7cea1fc1b358f520ccade38720
|
|
| BLAKE2b-256 |
69b08e2edb10bf512acc299b0e6014548c1a4bfb38fbf3319999fabcd5c042db
|
Provenance
The following attestation bundles were made for jacs-0.6.0-cp310-abi3-musllinux_1_2_x86_64.whl:
Publisher:
release-pypi.yml on HumanAssisted/JACS
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jacs-0.6.0-cp310-abi3-musllinux_1_2_x86_64.whl -
Subject digest:
7686971eaf45f125595c5e12cfa02ca5ca9820bfc43f8fefefa495c1cdd42783 - Sigstore transparency entry: 929127725
- Sigstore integration time:
-
Permalink:
HumanAssisted/JACS@2c1d78366e7bc09491d3424f5ac2b8bc956c39ed -
Branch / Tag:
refs/tags/pypi/v0.6.0 - Owner: https://github.com/HumanAssisted
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@2c1d78366e7bc09491d3424f5ac2b8bc956c39ed -
Trigger Event:
push
-
Statement type:
File details
Details for the file jacs-0.6.0-cp310-abi3-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: jacs-0.6.0-cp310-abi3-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 7.0 MB
- Tags: CPython 3.10+, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d8da8472bca004e4118051ff5c0b26397a598b7f0d9c3d24a3df611a1e0f3c23
|
|
| MD5 |
d673acf18c19ffafcf8e1de0b1e01ea6
|
|
| BLAKE2b-256 |
407b2384cf3e8e1c52c2164206961429a8c55a774848a27c1ad4ef075bc7d34d
|
Provenance
The following attestation bundles were made for jacs-0.6.0-cp310-abi3-manylinux_2_34_x86_64.whl:
Publisher:
release-pypi.yml on HumanAssisted/JACS
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jacs-0.6.0-cp310-abi3-manylinux_2_34_x86_64.whl -
Subject digest:
d8da8472bca004e4118051ff5c0b26397a598b7f0d9c3d24a3df611a1e0f3c23 - Sigstore transparency entry: 929127722
- Sigstore integration time:
-
Permalink:
HumanAssisted/JACS@2c1d78366e7bc09491d3424f5ac2b8bc956c39ed -
Branch / Tag:
refs/tags/pypi/v0.6.0 - Owner: https://github.com/HumanAssisted
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@2c1d78366e7bc09491d3424f5ac2b8bc956c39ed -
Trigger Event:
push
-
Statement type:
File details
Details for the file jacs-0.6.0-cp310-abi3-manylinux_2_34_aarch64.whl.
File metadata
- Download URL: jacs-0.6.0-cp310-abi3-manylinux_2_34_aarch64.whl
- Upload date:
- Size: 7.1 MB
- Tags: CPython 3.10+, manylinux: glibc 2.34+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c16742cad30a932e7cec851bd1235ec3a6ed7af715416be9bd86eac235c22aed
|
|
| MD5 |
25c9a990547cbc6b983af1fd74656dc2
|
|
| BLAKE2b-256 |
cb26fbc0b840d719f969d17cfee6f6c44ab2a4bb2874b9bf8bdd78bd0a395fca
|
Provenance
The following attestation bundles were made for jacs-0.6.0-cp310-abi3-manylinux_2_34_aarch64.whl:
Publisher:
release-pypi.yml on HumanAssisted/JACS
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jacs-0.6.0-cp310-abi3-manylinux_2_34_aarch64.whl -
Subject digest:
c16742cad30a932e7cec851bd1235ec3a6ed7af715416be9bd86eac235c22aed - Sigstore transparency entry: 929127721
- Sigstore integration time:
-
Permalink:
HumanAssisted/JACS@2c1d78366e7bc09491d3424f5ac2b8bc956c39ed -
Branch / Tag:
refs/tags/pypi/v0.6.0 - Owner: https://github.com/HumanAssisted
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@2c1d78366e7bc09491d3424f5ac2b8bc956c39ed -
Trigger Event:
push
-
Statement type:
File details
Details for the file jacs-0.6.0-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: jacs-0.6.0-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 6.4 MB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca6cc627ddbca07ed2a98c1efbd5c0f29cee347bbc5c8cb2083efb2cb00bcb37
|
|
| MD5 |
149b69e1ce5049ce06e83ff1d1e7c38e
|
|
| BLAKE2b-256 |
a706b9d940360d2079213c67ab6711ccb51471268ac365389eb1b5bb09544ac0
|
Provenance
The following attestation bundles were made for jacs-0.6.0-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
release-pypi.yml on HumanAssisted/JACS
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jacs-0.6.0-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
ca6cc627ddbca07ed2a98c1efbd5c0f29cee347bbc5c8cb2083efb2cb00bcb37 - Sigstore transparency entry: 929127723
- Sigstore integration time:
-
Permalink:
HumanAssisted/JACS@2c1d78366e7bc09491d3424f5ac2b8bc956c39ed -
Branch / Tag:
refs/tags/pypi/v0.6.0 - Owner: https://github.com/HumanAssisted
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@2c1d78366e7bc09491d3424f5ac2b8bc956c39ed -
Trigger Event:
push
-
Statement type:
File details
Details for the file jacs-0.6.0-cp310-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: jacs-0.6.0-cp310-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 6.6 MB
- Tags: CPython 3.10+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28005040068b82ef0704ad3e885d515460a224a7822d2ee2d100f1774d9d17f9
|
|
| MD5 |
3ed05f722ab1ef1f0e1175d87495a8fc
|
|
| BLAKE2b-256 |
72cc5c995037f56eb925a2106639af2bcc03b3f69eb287728c2ee02b8f3cdbf2
|
Provenance
The following attestation bundles were made for jacs-0.6.0-cp310-abi3-macosx_10_12_x86_64.whl:
Publisher:
release-pypi.yml on HumanAssisted/JACS
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
jacs-0.6.0-cp310-abi3-macosx_10_12_x86_64.whl -
Subject digest:
28005040068b82ef0704ad3e885d515460a224a7822d2ee2d100f1774d9d17f9 - Sigstore transparency entry: 929127727
- Sigstore integration time:
-
Permalink:
HumanAssisted/JACS@2c1d78366e7bc09491d3424f5ac2b8bc956c39ed -
Branch / Tag:
refs/tags/pypi/v0.6.0 - Owner: https://github.com/HumanAssisted
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release-pypi.yml@2c1d78366e7bc09491d3424f5ac2b8bc956c39ed -
Trigger Event:
push
-
Statement type: