Skip to content

Commit 3c601f7

Browse files
committed
┌──────┬─────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Task │ What │ ├──────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ 013 │ Created trust-layers.md — canonical three-layer model, terminology glossary, decision flow │ ├──────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ 014 │ Created a2a-attestation-composition.md — composition guide with Python/Node examples │ ├──────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ 015 │ Updated README.md — replaced inline boundary text with link to trust-layers │ ├──────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ 016 │ Updated a2a.md — added "A2A vs. Attestation" section │ ├──────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ 017 │ Updated attestation.md — added "Attestation vs. A2A Trust Policy" section │ ├──────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ 018 │ Updated sign-vs-attest.md — added cross-agent exchange branch (#5) + table row │ ├──────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ 019 │ Updated decision-tree.md — added A2A+Attestation row + Stage 3 note │ ├──────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ 020 │ Updated SUMMARY.md — added both new pages │ ├──────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ 036 │ Added jacs_attest_export_dsse MCP tool — params struct, schema, handler │ ├──────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ 037 │ Added jacs attest export-dsse CLI subcommand — reads file, outputs DSSE envelope │ ├──────┼─────────────────────────────────────────────────────────────────────────────────────────────────────┤ │ 038 │ Fixed all example digests — Python, Node, shell, tutorial (replaced placeholders with real SHA-256) │ └──────┴─────────────────────────────────────────────────────────────────────────────────────────────────────┘
1 parent f625e01 commit 3c601f7

File tree

104 files changed

+661
-118
lines changed

Some content is hidden

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

104 files changed

+661
-118
lines changed

README.md

Lines changed: 1 addition & 3 deletions

docs/jacsbook.pdf

48 KB
Binary file not shown.

examples/attestation_hello_world.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
*/
1313

1414
const { JacsClient } = require('@hai.ai/jacs/client');
15+
const { createHash } = require('crypto');
1516

1617
async function main() {
1718
// 1. Create an ephemeral agent (in-memory keys, no files)
@@ -22,11 +23,12 @@ async function main() {
2223
console.log(`Signed document: ${signed.documentId}`);
2324

2425
// 3. Attest WHY this document is trustworthy
26+
const contentHash = createHash('sha256').update(signed.raw).digest('hex');
2527
const attestation = await client.createAttestation({
2628
subject: {
2729
type: 'artifact',
2830
id: signed.documentId,
29-
digests: { sha256: 'from-signed-doc' },
31+
digests: { sha256: contentHash },
3032
},
3133
claims: [{ name: 'reviewed_by', value: 'human', confidence: 0.95 }],
3234
});

examples/attestation_hello_world.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
python examples/attestation_hello_world.py
1111
"""
1212

13+
import hashlib
1314
import json
1415
from jacs.client import JacsClient
1516

@@ -21,11 +22,12 @@
2122
print(f"Signed document: {signed.document_id}")
2223

2324
# 3. Attest WHY this document is trustworthy
25+
content_hash = hashlib.sha256(signed.raw_json.encode()).hexdigest()
2426
attestation = client.create_attestation(
2527
subject={
2628
"type": "artifact",
2729
"id": signed.document_id,
28-
"digests": {"sha256": "from-signed-doc"},
30+
"digests": {"sha256": content_hash},
2931
},
3032
claims=[{"name": "reviewed_by", "value": "human", "confidence": 0.95}],
3133
)

examples/attestation_hello_world.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,11 @@ echo "Document signed."
3838

3939
echo ""
4040
echo "=== 4. Create an attestation ==="
41+
DOC_HASH=$(sha256sum mydata.json | awk '{print $1}')
4142
jacs attest create \
4243
--subject-type artifact \
4344
--subject-id "mydata-001" \
44-
--subject-digest "sha256:from-signed-doc" \
45+
--subject-digest "sha256:${DOC_HASH}" \
4546
--claims '[{"name": "reviewed_by", "value": "human", "confidence": 0.95}]'
4647
echo "Attestation created."
4748

jacs-mcp/src/jacs_tools.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,14 @@ pub struct AttestVerifyParams {
13091309
pub full: bool,
13101310
}
13111311

1312+
/// Parameters for exporting an attestation as a DSSE envelope.
1313+
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
1314+
pub struct AttestExportDsseParams {
1315+
/// The signed attestation document JSON string.
1316+
#[schemars(description = "JSON string of the signed attestation document to export as DSSE")]
1317+
pub attestation_json: String,
1318+
}
1319+
13121320
/// Parameters for lifting a signed document to an attestation.
13131321
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
13141322
pub struct AttestLiftParams {
@@ -1594,6 +1602,13 @@ impl JacsMcpServer {
15941602
feature.",
15951603
Self::jacs_attest_lift_schema(),
15961604
),
1605+
Tool::new(
1606+
"jacs_attest_export_dsse",
1607+
"Export an attestation as a DSSE envelope for in-toto/SLSA compatibility. \
1608+
Provide the signed attestation document JSON. Returns a DSSE envelope with \
1609+
payloadType, payload, and signatures. Requires the attestation feature.",
1610+
Self::jacs_attest_export_dsse_schema(),
1611+
),
15971612
]
15981613
}
15991614

@@ -1852,6 +1867,14 @@ impl JacsMcpServer {
18521867
_ => serde_json::Map::new(),
18531868
}
18541869
}
1870+
1871+
fn jacs_attest_export_dsse_schema() -> serde_json::Map<String, serde_json::Value> {
1872+
let schema = schemars::schema_for!(AttestExportDsseParams);
1873+
match serde_json::to_value(schema) {
1874+
Ok(serde_json::Value::Object(map)) => map,
1875+
_ => serde_json::Map::new(),
1876+
}
1877+
}
18551878
}
18561879

18571880
// Implement the tool router for the server
@@ -3981,6 +4004,39 @@ impl JacsMcpServer {
39814004
}).to_string()
39824005
}
39834006
}
4007+
/// Export a signed attestation as a DSSE (Dead Simple Signing Envelope) for
4008+
/// in-toto/SLSA compatibility.
4009+
#[tool(
4010+
name = "jacs_attest_export_dsse",
4011+
description = "Export an attestation as a DSSE envelope for in-toto/SLSA compatibility."
4012+
)]
4013+
pub async fn jacs_attest_export_dsse(
4014+
&self,
4015+
Parameters(params): Parameters<AttestExportDsseParams>,
4016+
) -> String {
4017+
#[cfg(feature = "attestation")]
4018+
{
4019+
match self.agent.export_attestation_dsse(&params.attestation_json) {
4020+
Ok(result) => result,
4021+
Err(e) => {
4022+
let error = serde_json::json!({
4023+
"error": true,
4024+
"message": format!("Failed to export DSSE envelope: {}", e),
4025+
});
4026+
serde_json::to_string_pretty(&error)
4027+
.unwrap_or_else(|e| format!("Error: {}", e))
4028+
}
4029+
}
4030+
}
4031+
#[cfg(not(feature = "attestation"))]
4032+
{
4033+
let _ = params;
4034+
serde_json::json!({
4035+
"error": true,
4036+
"message": "Attestation feature not available. Rebuild with --features attestation."
4037+
}).to_string()
4038+
}
4039+
}
39844040
}
39854041

39864042
// Implement the tool handler for the server
@@ -4035,7 +4091,8 @@ impl ServerHandler for JacsMcpServer {
40354091
\
40364092
Attestation: jacs_attest_create (create signed attestation with claims), \
40374093
jacs_attest_verify (verify attestation, optionally with evidence checks), \
4038-
jacs_attest_lift (lift signed document into attestation). \
4094+
jacs_attest_lift (lift signed document into attestation), \
4095+
jacs_attest_export_dsse (export attestation as DSSE envelope). \
40394096
\
40404097
Security: jacs_audit (read-only security audit and health checks)."
40414098
.to_string(),
@@ -4090,6 +4147,7 @@ mod tests {
40904147
assert!(names.contains(&"jacs_attest_create"));
40914148
assert!(names.contains(&"jacs_attest_verify"));
40924149
assert!(names.contains(&"jacs_attest_lift"));
4150+
assert!(names.contains(&"jacs_attest_export_dsse"));
40934151
}
40944152

40954153
#[test]

jacs/docs/jacsbook/book/404.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

jacs/docs/jacsbook/book/advanced/algorithm-guide.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

jacs/docs/jacsbook/book/advanced/crypto.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

jacs/docs/jacsbook/book/advanced/custom-schemas.html

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)