1+ #!/usr/bin/env python3
2+ """
3+ DecisionAssure -> TRACE v0.1 Adapter
4+ Outputs a signed JWT (Ed25519) that conforms to TRACE spec at Level 0.
5+
6+ Usage:
7+ python da_to_trace.py decisionassure_trace.json > claim.jwt
8+ """
9+
10+ import json
11+ import sys
12+ import os
13+ import time
14+ import hashlib
15+ import base64
16+ from pathlib import Path
17+
18+ import jwt
19+ from cryptography .hazmat .primitives import serialization
20+ from cryptography .hazmat .primitives .asymmetric .ed25519 import Ed25519PrivateKey
21+
22+
23+ def load_or_generate_key () -> Ed25519PrivateKey :
24+ pem = os .environ .get ("TRACE_PRIVATE_KEY_PEM" )
25+ if pem :
26+ return serialization .load_pem_private_key (pem .encode (), password = None )
27+ # Generate a new key for each run (deterministic for demo)
28+ return Ed25519PrivateKey .generate ()
29+
30+
31+ def private_key_to_jwk (key : Ed25519PrivateKey ) -> dict :
32+ pub = key .public_key ()
33+ raw = pub .public_bytes (encoding = serialization .Encoding .Raw , format = serialization .PublicFormat .Raw )
34+ x = base64 .urlsafe_b64encode (raw ).decode ().rstrip ("=" )
35+ return {"kty" : "OKP" , "crv" : "Ed25519" , "x" : x }
36+
37+
38+ def map_decisionassure_to_trace (da_trace : dict ) -> dict :
39+ trace_id = da_trace .get ("trace_id" , "unknown" )
40+ final_decision = da_trace .get ("final_decision" , "DENY" )
41+ appraisal_status = "affirming" if final_decision == "ALLOW" else "denying"
42+ iat = int (time .time ())
43+ bundle_input = f"{ trace_id } :{ final_decision } " .encode ()
44+ bundle_hash = f"sha256:{ hashlib .sha256 (bundle_input ).hexdigest ()} "
45+
46+ return {
47+ "eat_profile" : "tag:agentrust.io,2026:trace-v0.1" ,
48+ "iat" : iat ,
49+ "subject" : f"spiffe://decisionassure.io/agent/{ trace_id } " ,
50+ "model" : {
51+ "provider" : "decisionassure" ,
52+ "model_id" : "runtime-governance-engine" ,
53+ "version" : "1.2" ,
54+ "weights_digest" : "sha256:placeholder-no-model"
55+ },
56+ "runtime" : {
57+ "platform" : "software-simulated" ,
58+ "measurement" : "sha384:0000000000000000000000000000000000000000000000000000000000000000" ,
59+ "rim_uri" : "https://github.com/a1k7/DecisionAssure-Runtime-Governance"
60+ },
61+ "policy" : {
62+ "bundle_hash" : bundle_hash ,
63+ "enforcement_mode" : "enforce" ,
64+ "version" : "1.0"
65+ },
66+ "data_class" : "governance-trace" ,
67+ "tool_transcript" : {
68+ "hash" : trace_id ,
69+ "call_count" : len (da_trace .get ("steps" , []))
70+ },
71+ "build_provenance" : {
72+ "slsa_level" : 0 ,
73+ "builder" : "https://github.com/a1k7/DecisionAssure-Runtime-Governance" ,
74+ "digest" : "sha256:placeholder"
75+ },
76+ "appraisal" : {
77+ "status" : appraisal_status ,
78+ "verifier" : "https://github.com/a1k7/DecisionAssure-Runtime-Governance" ,
79+ "policy_ref" : "decisionassure-v1.2"
80+ },
81+ "transparency" : ""
82+ }
83+
84+
85+ def main ():
86+ if len (sys .argv ) < 2 :
87+ print ("Usage: da_to_trace.py <decisionassure_trace.json>" , file = sys .stderr )
88+ sys .exit (1 )
89+
90+ with open (sys .argv [1 ]) as f :
91+ da_trace = json .load (f )
92+
93+ payload = map_decisionassure_to_trace (da_trace )
94+ key = load_or_generate_key ()
95+ jwk = private_key_to_jwk (key )
96+ payload ["cnf" ] = {"jwk" : jwk }
97+
98+ token = jwt .encode (payload , key , algorithm = "EdDSA" , headers = {"alg" : "EdDSA" , "typ" : "JWT" })
99+
100+ # Write the JWT to a file
101+ with open ("claim.jwt" , "w" ) as f :
102+ f .write (token )
103+ # Also print to stdout so user can redirect
104+ print (token )
105+
106+
107+ if __name__ == "__main__" :
108+ main ()
0 commit comments