Skip to content

Commit 87cfe79

Browse files
Hendlerclaude
andauthored
User/jhendler/0.3.6 (#31)
* CHANGELOG.md * dns * fix * fixing bootstrap * fix race condition * dilithium fix * agent fixure * dnssec not working * dns * dns agent verification from cli * clean up observability * change log * keystore mod * cleaned up key loading * fixes * fix tests * warning cleanup * changelog * starting embeded mcp and http * jacs mcp * CHANGELOG.md * doc * tests * jacsgp * fixes in jacgo to run tests * fix lint main issue * readme * a2a * a2a * bugfix * misc fixes w/ libs and a2a * changelog * refactor filestysem read write * cargo upgrade * add a new post quantum algorithm for signing * passing pq tests * permission * add jacsBranch * a2a updates * a2a updates * updating a2a, rust, cleanup errors * a2a updates * cleanup code * ignore * Security fixes: PBKDF2 KDF, panic handling, verification status, file permissions CRITICAL SECURITY FIXES: 1. [CRITICAL] Key derivation now uses PBKDF2-HMAC-SHA256 with 100,000 iterations instead of single SHA-256 hash. Previous approach was vulnerable to brute-force. - jacs/src/crypt/aes_encrypt.rs: Added derive_key_pbkdf2() with configurable iterations, salt generation, and proper key derivation - Added MAGIC_HEADER to distinguish new format from legacy encrypted keys - Backward compatible: auto-detects and reads legacy format 2. [CRITICAL] Crypto panic handling: Replaced .expect() with .map_err() in AES-GCM encrypt/decrypt. Crypto failures now return errors instead of panicking. - Prevents potential denial of service from malformed ciphertext 3. [HIGH] Foreign signature verification: verify_wrapped_artifact() now properly returns Unverified status for foreign agent signatures when public key is unavailable. Previously incorrectly indicated verified. - jacs/src/a2a/provenance.rs: Added VerificationStatus enum with Verified, SelfSigned, Unverified, Invalid states - Added is_verified(), is_invalid(), is_unverified() helper methods 4. [HIGH] Parent signature verification: verify_parent_signatures() now actually recursively verifies parent signatures instead of always returning true. MEDIUM SECURITY FIXES: 5. [MEDIUM] jacsnpm global singleton: Refactored from lazy_static! mutex to JacsAgent NAPI class pattern. Multiple agents can now be used concurrently in same Node.js process without shared mutable state. - jacsnpm/src/lib.rs: Added JacsAgent struct with instance methods - Legacy functions preserved with LEGACY_AGENT static for backward compat 6. [MEDIUM] Secure file permissions: Private keys now get 0600 permissions (owner read/write only) and key directories get 0700 (owner rwx only) on Unix systems. Prevents other users from reading private keys. - jacs/src/keystore/mod.rs: Added set_secure_permissions() with Unix/non-Unix conditional compilation OTHER CHANGES: - Added serial_test crate for test isolation (prevents env var conflicts) - Regenerated test encrypted key fixtures with correct passwords per config - Updated CHANGELOG.md with all security fixes under 0.3.6 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * - **[MEDIUM] Fixed jacspy global singleton**: Refactored from global `lazy_static!` mutex to `JacsAgent` PyO3 class pattern. Multiple agents can now be used concurrently in the same Python process. The `Arc<Mutex<Agent>>` pattern ensures thread-safety and works with Python's GIL as well as future free-threading (Python 3.13+). Legacy functions preserved for backwards compatibility. + * openclaw? * openclaw * jacsnpm security updates * fix test, doc * cli for fetch * moar openclaw * update gooooo * better test coverage * start updating book * update book * books update * update rust build versions * fix test * fix test * fix defaults * add test config for CI * test fix --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 6da8e00 commit 87cfe79

File tree

294 files changed

+79480
-6348
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

294 files changed

+79480
-6348
lines changed

.github/workflows/rust.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,12 @@ jobs:
2424
- name: Checkout code
2525
uses: actions/checkout@v4 # Use v4
2626

27+
- name: Install Rust toolchain
28+
uses: dtolnay/rust-toolchain@stable
29+
with:
30+
toolchain: '1.93'
31+
2732
- name: Run jacs tests
2833
# Specify the working directory for the test command
29-
working-directory: jacs
30-
run: cargo test --verbose
34+
working-directory: jacs
35+
run: cargo test --verbose --features cli

.github/workflows/static.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,16 @@ jobs:
3333
uses: actions/checkout@v4
3434
- name: Setup Pages
3535
uses: actions/configure-pages@v5
36+
- name: Install mdbook
37+
run: |
38+
curl -L https://github.com/rust-lang/mdBook/releases/download/v0.4.37/mdbook-v0.4.37-x86_64-unknown-linux-gnu.tar.gz | tar xz
39+
sudo mv mdbook /usr/local/bin/
40+
- name: Build book
41+
run: mdbook build jacs/docs/jacsbook
3642
- name: Upload artifact
3743
uses: actions/upload-pages-artifact@v3
3844
with:
39-
path: './docs/jacsbook/book/'
45+
path: './jacs/docs/jacsbook/book/'
4046
- name: Deploy to GitHub Pages
4147
id: deployment
4248
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
debug/
44
target/
55
.idea
6-
6+
jacs/documents/*
77
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
88
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
99
Cargo.lock
@@ -13,8 +13,9 @@ Cargo.lock
1313

1414
# MSVC Windows builds of rustc generate these, which store debugging information
1515
*.pdb
16-
16+
.cursor
1717
grant.md
1818
scratch.md
1919
jacs.config.json
20+
!jacs/jacs.config.json
2021
.DS_Store

A2A_QUICKSTART.md

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# JACS A2A Quick Start Guide
2+
3+
JACS extends Google's A2A (Agent-to-Agent) protocol with cryptographic document provenance.
4+
5+
## What JACS Adds to A2A
6+
7+
- **Document signatures** that persist with data (not just transport security)
8+
- **Post-quantum cryptography** for future-proof security
9+
- **Chain of custody** tracking for multi-agent workflows
10+
- **Self-verifying artifacts** that work offline
11+
12+
## Installation
13+
14+
```bash
15+
# Rust
16+
cargo add jacs
17+
18+
# Python
19+
pip install jacs
20+
21+
# Node.js
22+
npm install jacsnpm
23+
```
24+
25+
## Basic Usage
26+
27+
### 1. Export Agent to A2A Format
28+
29+
```python
30+
from jacs.a2a import JACSA2AIntegration
31+
32+
a2a = JACSA2AIntegration("jacs.config.json")
33+
agent_card = a2a.export_agent_card({
34+
"jacsId": "my-agent",
35+
"jacsName": "My Agent",
36+
"jacsServices": [{
37+
"name": "Process Data",
38+
"tools": [{
39+
"url": "/api/process",
40+
"function": {
41+
"name": "process",
42+
"description": "Process data"
43+
}
44+
}]
45+
}]
46+
})
47+
```
48+
49+
### 2. Wrap A2A Artifacts with Provenance
50+
51+
```javascript
52+
const { JACSA2AIntegration } = require('jacsnpm');
53+
const a2a = new JACSA2AIntegration();
54+
55+
// Wrap any A2A artifact
56+
const wrapped = a2a.wrapArtifactWithProvenance({
57+
taskId: 'task-123',
58+
operation: 'analyze',
59+
data: { /* ... */ }
60+
}, 'task');
61+
```
62+
63+
### 3. Verify Wrapped Artifacts
64+
65+
```rust
66+
use jacs::a2a::provenance::verify_wrapped_artifact;
67+
68+
let result = verify_wrapped_artifact(&agent, &wrapped_artifact)?;
69+
if result.valid {
70+
println!("Verified by: {}", result.signer_id);
71+
}
72+
```
73+
74+
### 4. Create Chain of Custody
75+
76+
```python
77+
# Track multi-step workflows
78+
step1 = a2a.wrap_artifact_with_provenance(data1, "step")
79+
step2 = a2a.wrap_artifact_with_provenance(data2, "step", [step1])
80+
step3 = a2a.wrap_artifact_with_provenance(data3, "step", [step2])
81+
82+
chain = a2a.create_chain_of_custody([step1, step2, step3])
83+
```
84+
85+
## Well-Known Endpoints
86+
87+
Serve these endpoints for A2A discovery:
88+
89+
- `/.well-known/agent.json` - A2A Agent Card (JWS signed)
90+
- `/.well-known/jacs-agent.json` - JACS agent descriptor
91+
- `/.well-known/jacs-pubkey.json` - JACS public key
92+
93+
## JACS Extension in Agent Cards
94+
95+
```json
96+
{
97+
"capabilities": {
98+
"extensions": [{
99+
"uri": "urn:hai.ai:jacs-provenance-v1",
100+
"description": "JACS cryptographic document signing",
101+
"params": {
102+
"supportedAlgorithms": ["dilithium", "rsa", "ecdsa"],
103+
"verificationEndpoint": "/jacs/verify"
104+
}
105+
}]
106+
}
107+
}
108+
```
109+
110+
## Examples
111+
112+
- **Rust**: [jacs/examples/a2a_complete_example.rs](./jacs/examples/a2a_complete_example.rs)
113+
- **Python**: [jacspy/examples/fastmcp/a2a_agent_server.py](./jacspy/examples/fastmcp/a2a_agent_server.py)
114+
- **Node.js**: [jacsnpm/examples/a2a-agent-example.js](./jacsnpm/examples/a2a-agent-example.js)
115+
116+
## Key Concepts
117+
118+
1. **Dual Keys**: JACS generates two key pairs:
119+
- Post-quantum (Dilithium) for document signatures
120+
- Traditional (RSA/ECDSA) for A2A compatibility
121+
122+
2. **Separation of Concerns**:
123+
- A2A handles discovery and transport
124+
- JACS handles document provenance
125+
126+
3. **Zero Trust**: Every artifact is self-verifying with complete audit trail
127+
128+
## Next Steps
129+
130+
1. Set up JACS configuration with keys
131+
2. Export your agent as A2A Agent Card
132+
3. Implement verification endpoints
133+
4. Register with A2A discovery services
134+
135+
See full documentation: [jacs/src/a2a/README.md](./jacs/src/a2a/README.md)

CHANGELOG.md

Lines changed: 79 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
. ai.pydantic.dev
1212
- secure storage of private key for shared server envs https://crates.io/crates/tss-esapi, https://docs.rs/cryptoki/latest/cryptoki/
1313
- qr code integration
14+
- https://github.com/sourcemeta/one
1415

1516
## 0.4.0
1617
- Domain integration
@@ -22,20 +23,49 @@
2223
- load document whatever storage config is
2324
- function test output metadata about current config and current agent
2425

26+
- [] add more feature flags for modular integrations
27+
- [] a2a integration
28+
- [] acp integration
29+
30+
2531
## jacs-mcp 0.1.0
2632

2733
- [] use rmcp
2834
- [] auth or all features
2935
- [] integration test with client
3036
- [] https://github.com/modelcontextprotocol/specification/discussions
3137

38+
### devrel
39+
- [] github actions builder for auto build/deploy of platform specific versions
40+
--------------------
3241

42+
- [] cli install for brew
43+
- [] cli install via shell script
44+
- [] open license
45+
- [] api for easier integratios data processing
46+
47+
- [] clickhous demo
48+
- [] test centralized logging output without file output
49+
3350
--------------------
3451

3552
## 0.3.7
3653

37-
### devrel
38-
- [] github actions builder for auto build/deploy of platform specific versions
54+
### internals
55+
56+
- [x] Updated A2A integration to protocol v0.4.0: rewrote AgentCard schema (protocolVersions array, supportedInterfaces, embedded JWS signatures, SecurityScheme enum, AgentSkill with id/tags), updated well-known path to agent-card.json, and aligned Rust, Python, and Node.js bindings with passing tests across all three.
57+
- [] remove in memory map if users don't request it. Refactor and DRY storage to prep for DB storage
58+
- [] test a2a across libraries
59+
- [] store in database
60+
- [] awareness of branch, merge, latest for documents.
61+
62+
### hai.ai
63+
64+
- integration with
65+
66+
1. register
67+
2.
68+
3969

4070
### jacsnpm
4171

@@ -59,11 +89,12 @@
5989
1. cli create agent
6090
2. config jacspy to load each agent
6191
- [] github actions builder for linux varieties
92+
- [] switch to uv from pip/etc
6293

6394
### JACS core
64-
- [] acp integration
95+
6596
- [] brew installer, review installation instrucitons, cli install instructions. a .sh command?
66-
- [] a2a integration
97+
- [] more a2a tests
6798
- [] ensure if a user wants standard logging they can use that
6899

69100

@@ -78,33 +109,7 @@
78109
### minor core
79110
- [] don't store "jacs_private_key_password": in config, don't display
80111
- [] minor feature - no_save = false should save document and still return json string instead of message on create document
81-
82-
--------------------
83-
84-
## 0.3.6
85-
86-
87-
### devex
88-
89-
- [] add more feature flags for modular integrations
90-
- [] a2a integration
91-
- [] acp integration
92-
- [] add updates to book
93-
- [] cli install for brew
94-
- [] cli install via shell script
95-
- [] open license
96-
- [] crew.ai
97-
- [] langchain
98-
99-
### jacs
100-
101-
- [] redesign api for easier bootstrapping
102-
- [] PKI choice (dkim, ke)
103-
- [] private key bootstrapping with vault, kerberos - filesystem
104-
- [] api for easier integratios data processing
105-
- [x] add observability to configuration
106-
107-
- [] test centralized logging output without file output
112+
- [] default to dnssec if domain is present - or WARN
108113

109114
### jacsmcp
110115

@@ -115,14 +120,56 @@
115120
- [] refactor api
116121
- [] publish to pipy
117122
- [] tracing and logging integration tests
118-
- [] switch to uv from pip/etc
123+
119124

120125
### jacsnpm
121126

122127
- [] publish to npm
123128
- [] tracing and logging integration tests
124129

125130

131+
====
132+
## 0.3.6
133+
134+
### Security
135+
136+
- **[CRITICAL] Fixed key derivation**: Changed from single SHA-256 hash to proper PBKDF2-HMAC-SHA256 with 100,000 iterations for deriving encryption keys from passwords. The previous single-hash approach was vulnerable to brute-force attacks.
137+
138+
- **[CRITICAL] Fixed crypto panic handling**: Replaced `.expect()` with proper `.map_err()` error handling in AES-GCM encryption/decryption. Crypto failures now return proper errors instead of panicking, which could cause denial of service.
139+
140+
- **[HIGH] Fixed foreign signature verification**: The `verify_wrapped_artifact` function now properly returns `Unverified` status for foreign agent signatures when the public key is not available, rather than incorrectly indicating signatures were verified. Added `VerificationStatus` enum to explicitly distinguish between `Verified`, `SelfSigned`, `Unverified`, and `Invalid` states.
141+
142+
- **[HIGH] Fixed parent signature verification**: The `verify_parent_signatures` function now actually verifies parent signatures recursively. Previously it always returned true regardless of verification status.
143+
144+
- Added `serial_test` for test isolation to prevent environment variable conflicts between tests.
145+
146+
- Added `regenerate_test_keys.rs` utility example for re-encrypting test fixtures with the new KDF.
147+
148+
- **[MEDIUM] Fixed jacsnpm global singleton**: Refactored from global `lazy_static!` mutex to `JacsAgent` NAPI class pattern. Multiple agents can now be used concurrently in the same Node.js process. Legacy functions preserved for backwards compatibility but marked deprecated.
149+
150+
- **[MEDIUM] Fixed jacspy global singleton**: Refactored from global `lazy_static!` mutex to `JacsAgent` PyO3 class pattern. Multiple agents can now be used concurrently in the same Python process. The `Arc<Mutex<Agent>>` pattern ensures thread-safety and works with Python's GIL as well as future free-threading (Python 3.13+). Legacy functions preserved for backwards compatibility.
151+
152+
- **[MEDIUM] Added secure file permissions**: Private keys now get 0600 permissions (owner read/write only) and key directories get 0700 (owner rwx only) on Unix systems. This prevents other users on shared systems from reading private keys.
153+
154+
### devex
155+
- [x] add updates to book
156+
- [x] add observability demo
157+
158+
### jacs
159+
- [x] a2a integration
160+
- [x] clean up observability
161+
- Observability: added feature-gated backends (`otlp-logs`, `otlp-metrics`, `otlp-tracing`) and optional `observability-convenience`. Default build is minimal (stderr/file logs only), no tokio/OpenTelemetry; clear runtime errors if a requested backend isn’t compiled. Docs now include a feature matrix and compile recipes. Tests updated and all pass with features.
162+
163+
- [x] dns verification of pubic key hash
164+
- DNS: implemented fingerprint-in-DNS (TXT under `_v1.agent.jacs.<domain>.`), CLI emitters for BIND/Route53/Azure/Cloudflare, DNSSEC validation with non-strict fallback, and config flags (`jacs_agent_domain`, `jacs_dns_validate`, `jacs_dns_strict`, `jacs_dns_required`). Added CLI flags `--require-dns`, `--require-strict-dns`, `--ignore-dns`, and `--no-dns` (alias preserved). Improved error messages, updated docs, and added policy/encoding tests.
165+
166+
167+
- [x] scaffold private key bootstrapping with vault, kerberos - filesystem
168+
169+
170+
171+
172+
126173
--------------------
127174

128175
## 0.3.5

Cargo.toml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
[workspace]
22
members = [
3-
"jacs",
4-
"jacsnpm",
5-
# "mcp-server",
6-
"jacspy"
3+
"jacs",
4+
"jacsnpm",
5+
"jacspy",
6+
"jacs-mcp",
7+
"jacsgo/lib"
78
]
89
resolver = "3"
9-
rust-version = "1.85"
10-
1110

11+
[workspace.package]
12+
rust-version = "1.93"
1213
readme = "README.md"
1314
authors = ["HAI.AI <engineering@hai.io>"]
1415
license-file = "LICENSE"
1516
homepage = "https://humanassisted.github.io/JACS"
1617
repository = "https://github.com/HumanAssisted/JACS"
1718
keywords = ["cryptography", "json", "ai", "data", "ml-ops"]
18-
categories = ["cryptography", "text-processing", "data-structures" ]
19-
build = "build.rs"
19+
categories = ["cryptography", "text-processing", "data-structures"]

0 commit comments

Comments
 (0)