traceguard-core 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- traceguard_core-0.1.0/LICENSE +1 -0
- traceguard_core-0.1.0/PKG-INFO +40 -0
- traceguard_core-0.1.0/README.md +21 -0
- traceguard_core-0.1.0/pyproject.toml +34 -0
- traceguard_core-0.1.0/setup.cfg +4 -0
- traceguard_core-0.1.0/src/traceguard/__init__.py +15 -0
- traceguard_core-0.1.0/src/traceguard/asyncledger.py +67 -0
- traceguard_core-0.1.0/src/traceguard/aximos.py +14 -0
- traceguard_core-0.1.0/src/traceguard/cli.py +107 -0
- traceguard_core-0.1.0/src/traceguard/compliance_audit.py +31 -0
- traceguard_core-0.1.0/src/traceguard/compliance_report.py +97 -0
- traceguard_core-0.1.0/src/traceguard/dashboard_stream.py +24 -0
- traceguard_core-0.1.0/src/traceguard/enterprise.py +17 -0
- traceguard_core-0.1.0/src/traceguard/evidence.py +44 -0
- traceguard_core-0.1.0/src/traceguard/matrix.py +15 -0
- traceguard_core-0.1.0/src/traceguard/middleware.py +48 -0
- traceguard_core-0.1.0/src/traceguard/pdf_generator.py +84 -0
- traceguard_core-0.1.0/src/traceguard/traceguard.py +15 -0
- traceguard_core-0.1.0/src/traceguard_core.egg-info/PKG-INFO +40 -0
- traceguard_core-0.1.0/src/traceguard_core.egg-info/SOURCES.txt +26 -0
- traceguard_core-0.1.0/src/traceguard_core.egg-info/dependency_links.txt +1 -0
- traceguard_core-0.1.0/src/traceguard_core.egg-info/requires.txt +2 -0
- traceguard_core-0.1.0/src/traceguard_core.egg-info/top_level.txt +1 -0
- traceguard_core-0.1.0/tests/test_async_ledger.py +35 -0
- traceguard_core-0.1.0/tests/test_compliance_audit.py +21 -0
- traceguard_core-0.1.0/tests/test_engine.py +32 -0
- traceguard_core-0.1.0/tests/test_evidence.py +20 -0
- traceguard_core-0.1.0/tests/test_middleware.py +25 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
MIT License
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: traceguard-core
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Deterministic zero-trust runtime and evidence demonstrator for autonomous AI agent pipelines.
|
|
5
|
+
Author-email: Sigilith Labs <sigilith@proton.me>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Sigilith/traceguard-core
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Python: >=3.11
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: pytest>=8.0.0
|
|
17
|
+
Requires-Dist: pytest-asyncio>=0.23.0
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# TraceGuard
|
|
21
|
+
|
|
22
|
+
TraceGuard is a zero-trust governance and audit framework providing:
|
|
23
|
+
- Action verification
|
|
24
|
+
- Ledger integrity
|
|
25
|
+
- AXIOMOS risk scoring
|
|
26
|
+
- Compliance reporting
|
|
27
|
+
- CLI demo
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
pip install traceguard
|
|
31
|
+
|
|
32
|
+
## Examples
|
|
33
|
+
See the `examples/` directory.
|
|
34
|
+
|
|
35
|
+
## Documentation
|
|
36
|
+
See the `docs/` directory.
|
|
37
|
+
|
|
38
|
+
## CLI
|
|
39
|
+
traceguard demo
|
|
40
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# TraceGuard
|
|
2
|
+
|
|
3
|
+
TraceGuard is a zero-trust governance and audit framework providing:
|
|
4
|
+
- Action verification
|
|
5
|
+
- Ledger integrity
|
|
6
|
+
- AXIOMOS risk scoring
|
|
7
|
+
- Compliance reporting
|
|
8
|
+
- CLI demo
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
pip install traceguard
|
|
12
|
+
|
|
13
|
+
## Examples
|
|
14
|
+
See the `examples/` directory.
|
|
15
|
+
|
|
16
|
+
## Documentation
|
|
17
|
+
See the `docs/` directory.
|
|
18
|
+
|
|
19
|
+
## CLI
|
|
20
|
+
traceguard demo
|
|
21
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "traceguard-core"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Deterministic zero-trust runtime and evidence demonstrator for autonomous AI agent pipelines."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
authors = [
|
|
11
|
+
{ name = "Sigilith Labs", email = "sigilith@proton.me" }
|
|
12
|
+
]
|
|
13
|
+
license = { text = "MIT" }
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3.11",
|
|
16
|
+
"Programming Language :: Python :: 3.12",
|
|
17
|
+
"Programming Language :: Python :: 3.13",
|
|
18
|
+
"License :: OSI Approved :: MIT License",
|
|
19
|
+
"Operating System :: OS Independent",
|
|
20
|
+
]
|
|
21
|
+
requires-python = ">=3.11"
|
|
22
|
+
dependencies = [
|
|
23
|
+
"pytest>=8.0.0",
|
|
24
|
+
"pytest-asyncio>=0.23.0",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
Homepage = "https://github.com/Sigilith/traceguard-core"
|
|
29
|
+
|
|
30
|
+
[tool.setuptools]
|
|
31
|
+
package-dir = {"" = "src"}
|
|
32
|
+
|
|
33
|
+
[tool.setuptools.packages.find]
|
|
34
|
+
where = ["src"]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from traceguard.traceguard import TraceGuard
|
|
2
|
+
from traceguard.asyncledger import AsyncEvidenceLedger
|
|
3
|
+
from traceguard.aximos import AXIOMOSEvaluator
|
|
4
|
+
from traceguard.middleware import TraceGuardMiddleware
|
|
5
|
+
from traceguard.compliance_audit import ComplianceAuditGenerator
|
|
6
|
+
from traceguard.enterprise import EnterpriseComplianceSync
|
|
7
|
+
|
|
8
|
+
__all__ = [
|
|
9
|
+
"TraceGuard",
|
|
10
|
+
"AsyncEvidenceLedger",
|
|
11
|
+
"AXIOMOSEvaluator",
|
|
12
|
+
"TraceGuardMiddleware",
|
|
13
|
+
"ComplianceAuditGenerator",
|
|
14
|
+
"EnterpriseComplianceSync",
|
|
15
|
+
]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import json
|
|
3
|
+
import hashlib
|
|
4
|
+
from datetime import datetime, timezone
|
|
5
|
+
|
|
6
|
+
class AsyncEvidenceLedger:
|
|
7
|
+
"""Enterprise non-blocking tamper-evident hash-chain ledger for asynchronous AI agent pipelines."""
|
|
8
|
+
|
|
9
|
+
def __init__(self):
|
|
10
|
+
self.chain = []
|
|
11
|
+
self.last_hash = "0" * 64
|
|
12
|
+
self._lock = asyncio.Lock()
|
|
13
|
+
|
|
14
|
+
async def _compute_hash(self, entry_str: str) -> str:
|
|
15
|
+
"""Offloads SHA-256 computation to a background thread to prevent event loop blocking."""
|
|
16
|
+
return await asyncio.to_thread(
|
|
17
|
+
lambda: hashlib.sha256(entry_str.encode('utf-8')).hexdigest()
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
async def append_entry(self, payload: dict) -> dict:
|
|
21
|
+
"""Appends a cryptographically chained governance record asynchronously."""
|
|
22
|
+
async with self._lock:
|
|
23
|
+
timestamp = datetime.now(timezone.utc).isoformat()
|
|
24
|
+
entry = {
|
|
25
|
+
"timestamp": timestamp,
|
|
26
|
+
"payload": payload,
|
|
27
|
+
"prev_hash": self.last_hash
|
|
28
|
+
}
|
|
29
|
+
sorted_entry = dict(sorted(entry.items()))
|
|
30
|
+
entry_json = json.dumps(sorted_entry)
|
|
31
|
+
current_hash = await self._compute_hash(entry_json)
|
|
32
|
+
|
|
33
|
+
entry["current_hash"] = current_hash
|
|
34
|
+
self.chain.append(entry)
|
|
35
|
+
self.last_hash = current_hash
|
|
36
|
+
return entry
|
|
37
|
+
|
|
38
|
+
async def verify_integrity(self) -> bool:
|
|
39
|
+
"""Verifies immutable chain integrity by recomputing hashes sequentially from genesis."""
|
|
40
|
+
async with self._lock:
|
|
41
|
+
if not self.chain:
|
|
42
|
+
return True
|
|
43
|
+
|
|
44
|
+
expected_prev_hash = "0" * 64
|
|
45
|
+
|
|
46
|
+
for curr in self.chain:
|
|
47
|
+
# 1. Validate previous hash linkage
|
|
48
|
+
if curr["prev_hash"] != expected_prev_hash:
|
|
49
|
+
return False
|
|
50
|
+
|
|
51
|
+
# 2. Recompute current block hash from its source data
|
|
52
|
+
recheck_entry = {
|
|
53
|
+
"timestamp": curr["timestamp"],
|
|
54
|
+
"payload": curr["payload"],
|
|
55
|
+
"prev_hash": curr["prev_hash"]
|
|
56
|
+
}
|
|
57
|
+
sorted_recheck = dict(sorted(recheck_entry.items()))
|
|
58
|
+
recheck_json = json.dumps(sorted_recheck)
|
|
59
|
+
recheck_hash = hashlib.sha256(recheck_json.encode('utf-8')).hexdigest()
|
|
60
|
+
|
|
61
|
+
# 3. Validate stored hash matches recomputed hash
|
|
62
|
+
if recheck_hash != curr["current_hash"]:
|
|
63
|
+
return False
|
|
64
|
+
|
|
65
|
+
expected_prev_hash = recheck_hash
|
|
66
|
+
|
|
67
|
+
return True
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class AXIOMOSEvaluator:
|
|
2
|
+
def __init__(self, block_threshold: int = 2):
|
|
3
|
+
self.block_threshold = block_threshold
|
|
4
|
+
|
|
5
|
+
def evaluate_logs(self, logs: list) -> str:
|
|
6
|
+
if not logs:
|
|
7
|
+
return "UNRESOLVED"
|
|
8
|
+
|
|
9
|
+
block_count = sum(1 for log in logs if log.get("decision") == "BLOCK")
|
|
10
|
+
if block_count >= self.block_threshold:
|
|
11
|
+
return "HIGH_RISK"
|
|
12
|
+
elif block_count > 0:
|
|
13
|
+
return "MEDIUM_RISK"
|
|
14
|
+
return "LOW_RISK"
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from traceguard.traceguard import TraceGuard
|
|
5
|
+
from traceguard.aximos import AXIOMOSEvaluator
|
|
6
|
+
from traceguard.evidence import EvidenceLedger
|
|
7
|
+
from traceguard.compliance_report import ComplianceReportGenerator
|
|
8
|
+
from traceguard.pdf_generator import generate_compliance_pdf
|
|
9
|
+
|
|
10
|
+
def print_help():
|
|
11
|
+
print("TRACEGUARD CLI // Autonomous Agent Governance SDK")
|
|
12
|
+
print("\nUsage:")
|
|
13
|
+
print(" traceguard <command> [options]")
|
|
14
|
+
print("\nAvailable Commands:")
|
|
15
|
+
print(" demo Run the full interactive zero-trust pipeline demo")
|
|
16
|
+
print(" verify Perform independent cryptographic ledger verification")
|
|
17
|
+
print(" audit Execute a live policy check and generate audit metadata")
|
|
18
|
+
print(" drift Analyze operational log files for behavioral risk drift")
|
|
19
|
+
print(" pdf Compile and export the enterprise compliance PDF artifact")
|
|
20
|
+
print(" --help Show this command reference guide")
|
|
21
|
+
|
|
22
|
+
def main():
|
|
23
|
+
if len(sys.argv) < 2 or sys.argv[1] in ["--help", "-h"]:
|
|
24
|
+
print_help()
|
|
25
|
+
sys.exit(0)
|
|
26
|
+
|
|
27
|
+
command = sys.argv[1].lower()
|
|
28
|
+
|
|
29
|
+
if command == "demo":
|
|
30
|
+
run_demo()
|
|
31
|
+
elif command == "verify":
|
|
32
|
+
run_verification()
|
|
33
|
+
elif command == "audit":
|
|
34
|
+
run_audit()
|
|
35
|
+
elif command == "drift":
|
|
36
|
+
run_drift()
|
|
37
|
+
elif command == "pdf":
|
|
38
|
+
run_pdf()
|
|
39
|
+
else:
|
|
40
|
+
print(f"Unknown command: '{command}'. Run 'traceguard --help' for available commands.")
|
|
41
|
+
sys.exit(1)
|
|
42
|
+
|
|
43
|
+
def run_demo():
|
|
44
|
+
print("=== TRACEGUARD ZERO-TRUST DEMO ===")
|
|
45
|
+
tg = TraceGuard(allowed_actions=["read_logs", "safe_query"])
|
|
46
|
+
ledger = EvidenceLedger()
|
|
47
|
+
|
|
48
|
+
res1 = tg.evaluate_action("read_logs")
|
|
49
|
+
ledger.append_entry({"action": "read_logs", "decision": res1})
|
|
50
|
+
print(f"[1] Legitimate action {res1}")
|
|
51
|
+
|
|
52
|
+
res2 = tg.evaluate_action("delete_system_root")
|
|
53
|
+
ledger.append_entry({"action": "delete_system_root", "decision": res2})
|
|
54
|
+
print(f"[2] Unauthorized action {res2}")
|
|
55
|
+
|
|
56
|
+
print(f"[3] Evidence recorded ✓ (Ledger Index: {len(ledger.chain)-1})")
|
|
57
|
+
|
|
58
|
+
is_valid = ledger.verify_integrity()
|
|
59
|
+
print(f"[4] Hash chain verified {'✓' if is_valid else '✗'}")
|
|
60
|
+
|
|
61
|
+
ledger.tamper_with_entry(0, {"action": "tampered", "decision": "BYPASS"})
|
|
62
|
+
tamper_detected = not ledger.verify_integrity()
|
|
63
|
+
print(f"[5] Tamper attempt {'DETECTED' if tamper_detected else 'MISSED'}")
|
|
64
|
+
|
|
65
|
+
ax = AXIOMOSEvaluator(block_threshold=1)
|
|
66
|
+
risk = ax.evaluate_logs(tg.get_logs())
|
|
67
|
+
print(f"[6] AXIOMOS assessment {risk}")
|
|
68
|
+
print("\nAUDIT STATUS: VERIFIED" if is_valid else "AUDIT STATUS: COMPROMISED")
|
|
69
|
+
|
|
70
|
+
def run_verification():
|
|
71
|
+
print("=== TRACEGUARD INDEPENDENT EVIDENCE VERIFICATION ===")
|
|
72
|
+
ledger = EvidenceLedger()
|
|
73
|
+
ledger.append_entry({"action": "safe_query", "decision": "ALLOW"})
|
|
74
|
+
ledger.append_entry({"action": "unauthorized", "decision": "BLOCK"})
|
|
75
|
+
|
|
76
|
+
integrity = ledger.verify_integrity()
|
|
77
|
+
print(f"Chain Length: {len(ledger.chain)}")
|
|
78
|
+
print(f"Cryptographic Integrity Check: {'PASSED ✓' if integrity else 'FAILED ✗'}")
|
|
79
|
+
print(f"Current Head Hash: {ledger.chain[-1]['current_hash'][:16]}...")
|
|
80
|
+
|
|
81
|
+
def run_audit():
|
|
82
|
+
print("=== TRACEGUARD COMPLIANCE AUDIT PACKET ===")
|
|
83
|
+
reporter = ComplianceReportGenerator()
|
|
84
|
+
packet = reporter.generate_packet(consequence=3, autonomy=3, oversight=False, violations_detected=1)
|
|
85
|
+
print(packet["risk_classification"])
|
|
86
|
+
|
|
87
|
+
def run_drift():
|
|
88
|
+
print("=== AXIOMOS BEHAVIORAL DRIFT ANALYSIS ===")
|
|
89
|
+
ax = AXIOMOS(block_threshold=2)
|
|
90
|
+
sample_logs = [
|
|
91
|
+
{"action": "read_data", "decision": "ALLOW"},
|
|
92
|
+
{"action": "unauthorized_drop", "decision": "BLOCK"},
|
|
93
|
+
{"action": "unauthorized_modify", "decision": "BLOCK"}
|
|
94
|
+
]
|
|
95
|
+
risk = ax.evaluate_logs(sample_logs)
|
|
96
|
+
print(f"Evaluated Log Entries: {len(sample_logs)}")
|
|
97
|
+
print(f"Behavioral Risk Status: {risk}")
|
|
98
|
+
|
|
99
|
+
def run_pdf():
|
|
100
|
+
print("=== ENTERPRISE PDF EXPORT ===")
|
|
101
|
+
reporter = ComplianceReportGenerator()
|
|
102
|
+
packet = reporter.generate_packet(consequence=3, autonomy=3, oversight=False, violations_detected=1)
|
|
103
|
+
filename = generate_compliance_pdf(packet, "traceguard_compliance_audit.pdf")
|
|
104
|
+
print(f"PDF successfully compiled and saved to '{filename}'.")
|
|
105
|
+
|
|
106
|
+
if __name__ == "__main__":
|
|
107
|
+
main()
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from datetime import datetime, timezone
|
|
3
|
+
from traceguard.asyncledger import AsyncEvidenceLedger
|
|
4
|
+
from traceguard.aximos import AXIOMOSEvaluator
|
|
5
|
+
|
|
6
|
+
class ComplianceAuditGenerator:
|
|
7
|
+
"""Generates structured compliance audit packets from cryptographic ledger entries."""
|
|
8
|
+
|
|
9
|
+
def __init__(self, ledger: AsyncEvidenceLedger, evaluator: AXIOMOSEvaluator):
|
|
10
|
+
self.ledger = ledger
|
|
11
|
+
self.evaluator = evaluator
|
|
12
|
+
|
|
13
|
+
async def generate_audit_packet(self, framework_name: str = "Ofgem High-Impact AI Assurance") -> str:
|
|
14
|
+
is_valid = await self.ledger.verify_integrity()
|
|
15
|
+
risk_status = self.evaluator.evaluate_logs(self.ledger.chain)
|
|
16
|
+
|
|
17
|
+
packet = {
|
|
18
|
+
"audit_timestamp": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
|
|
19
|
+
"regulatory_framework": framework_name,
|
|
20
|
+
"ledger_metrics": {
|
|
21
|
+
"total_records": len(self.ledger.chain),
|
|
22
|
+
"hash_chain_integrity_verified": is_valid,
|
|
23
|
+
"head_hash": self.ledger.chain[-1]["current_hash"] if self.ledger.chain else None
|
|
24
|
+
},
|
|
25
|
+
"governance_evaluation": {
|
|
26
|
+
"axiomos_risk_tier": risk_status,
|
|
27
|
+
"boundary_enforcement_active": True,
|
|
28
|
+
"mandatory_controls_met": is_valid and risk_status != "CRITICAL_BREACH"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return json.dumps(packet, indent=2)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import uuid
|
|
3
|
+
from datetime import datetime, timezone
|
|
4
|
+
|
|
5
|
+
class ComplianceReportGenerator:
|
|
6
|
+
def __init__(self, system_name: str = "TraceGuard Autonomous Engine"):
|
|
7
|
+
self.system_name = system_name
|
|
8
|
+
|
|
9
|
+
def generate_packet(self, consequence: int, autonomy: int, oversight: bool, violations_detected: int) -> dict:
|
|
10
|
+
audit_id = str(uuid.uuid4())
|
|
11
|
+
timestamp = datetime.now(timezone.utc).isoformat()
|
|
12
|
+
|
|
13
|
+
# Assurance Matrix calculation
|
|
14
|
+
score = consequence + autonomy - (2 if oversight else 0)
|
|
15
|
+
if score >= 4:
|
|
16
|
+
tier = "Tier 3 — High Impact (Critical Infrastructure / Autonomous Execution)"
|
|
17
|
+
regulatory_focus = ["Ofgem High-Impact AI Assurance", "EU AI Act High-Risk Mandate"]
|
|
18
|
+
controls = [
|
|
19
|
+
"Deterministic runtime boundary enforcement (TraceGuard)",
|
|
20
|
+
"Continuous behavioral drift monitoring & AXIOMOS risk evaluation",
|
|
21
|
+
"Technical human-in-the-loop approval gates",
|
|
22
|
+
"Immutable append-only audit logging & incident reconstruction"
|
|
23
|
+
]
|
|
24
|
+
elif score >= 2:
|
|
25
|
+
tier = "Tier 2 — Moderate Impact (Operational Support)"
|
|
26
|
+
regulatory_focus = ["Ofgem Moderate Impact", "EU AI Act Transparency Requirements"]
|
|
27
|
+
controls = [
|
|
28
|
+
"Runtime monitoring and schema validation",
|
|
29
|
+
"Periodic behavioral drift checks",
|
|
30
|
+
"Defined human responsibility boundaries"
|
|
31
|
+
]
|
|
32
|
+
else:
|
|
33
|
+
tier = "Tier 1 — Low Impact (Informational / Internal)"
|
|
34
|
+
regulatory_focus = ["Standard Internal Governance"]
|
|
35
|
+
controls = [
|
|
36
|
+
"Basic schema logging and execution checks"
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
packet = {
|
|
40
|
+
"artifact_metadata": {
|
|
41
|
+
"audit_uuid": audit_id,
|
|
42
|
+
"timestamp_utc": timestamp,
|
|
43
|
+
"system_name": self.system_name,
|
|
44
|
+
"generator": "traceguard-core compliance engine"
|
|
45
|
+
},
|
|
46
|
+
"risk_classification": {
|
|
47
|
+
"consequence_level": consequence,
|
|
48
|
+
"autonomy_level": autonomy,
|
|
49
|
+
"human_oversight_enforced": oversight,
|
|
50
|
+
"composite_score": score,
|
|
51
|
+
"assigned_tier": tier
|
|
52
|
+
},
|
|
53
|
+
"regulatory_mapping": regulatory_focus,
|
|
54
|
+
"mandatory_controls": controls,
|
|
55
|
+
"runtime_boundary_blueprint": {
|
|
56
|
+
"traceguard_enforcement": "ACTIVE",
|
|
57
|
+
"aximos_drift_status": "HIGH_RISK" if violations_detected > 0 else "LOW_RISK",
|
|
58
|
+
"allowed_action_schema": ["read_logs", "safe_query"] if oversight else ["safe_query"]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return packet
|
|
62
|
+
|
|
63
|
+
def export_as_markdown(self, packet: dict) -> str:
|
|
64
|
+
meta = packet["artifact_metadata"]
|
|
65
|
+
risk = packet["risk_classification"]
|
|
66
|
+
blueprint = packet["runtime_boundary_blueprint"]
|
|
67
|
+
|
|
68
|
+
md = f"""# ENTERPRISE COMPLIANCE & ASSURANCE AUDIT PACKET
|
|
69
|
+
**System Name:** {meta['system_name']}
|
|
70
|
+
**Audit UUID:** `{meta['audit_uuid']}`
|
|
71
|
+
**Timestamp (UTC):** {meta['timestamp_utc']}
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## 1. Executive Tier Classification
|
|
76
|
+
* **Assigned Tier:** {risk['assigned_tier']}
|
|
77
|
+
* **Composite Risk Score:** {risk['composite_score']} (Consequence: {risk['consequence_level']} | Autonomy: {risk['autonomy_level']} | Oversight: {risk['human_oversight_enforced']})
|
|
78
|
+
|
|
79
|
+
## 2. Regulatory Alignment
|
|
80
|
+
* **Frameworks Mapped:** {', '.join(packet['regulatory_mapping'])}
|
|
81
|
+
* **Core Principle:** Designed to satisfy rigorous operational governance, aligning with tiered assurance frameworks for critical infrastructure and autonomous systems[span_0](start_span)[span_0](end_span).
|
|
82
|
+
|
|
83
|
+
## 3. Mandatory Governance Controls
|
|
84
|
+
"""
|
|
85
|
+
for control in packet["mandatory_controls"]:
|
|
86
|
+
md += f"- [x] {control}\n"
|
|
87
|
+
|
|
88
|
+
md += f"""
|
|
89
|
+
## 4. Runtime Boundary Blueprint
|
|
90
|
+
* **TraceGuard Status:** `{blueprint['traceguard_enforcement']}`
|
|
91
|
+
* **AXIOMOS Drift Evaluation:** `{blueprint['aximos_drift_status']}`
|
|
92
|
+
* **Permitted Action Schema:** `{json.dumps(blueprint['allowed_action_schema'])}`
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
*Generated autonomously by TraceGuard-Core Assurance Engine. Immutable record verified via UUID token.*
|
|
96
|
+
"""
|
|
97
|
+
return md
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from traceguard.aximos import AXIOMOSEvaluator
|
|
3
|
+
from traceguard.asyncledger import AsyncEvidenceLedger
|
|
4
|
+
|
|
5
|
+
class DashboardStreamer:
|
|
6
|
+
"""Streams live AXIOMOS risk telemetry and ledger hash chain states for enterprise dashboards."""
|
|
7
|
+
|
|
8
|
+
def __init__(self, block_threshold: int = 2):
|
|
9
|
+
self.evaluator = AXIOMOSEvaluator(block_threshold=block_threshold)
|
|
10
|
+
self.ledger = AsyncEvidenceLedger()
|
|
11
|
+
|
|
12
|
+
async def stream_telemetry(self):
|
|
13
|
+
"""Asynchronous generator yielding real-time risk indicators and cryptographic proofs."""
|
|
14
|
+
while True:
|
|
15
|
+
risk_status = self.evaluator.evaluate_logs(self.ledger.chain)
|
|
16
|
+
head_hash = self.ledger.chain[-1]["current_hash"] if self.ledger.chain else "0" * 64
|
|
17
|
+
|
|
18
|
+
yield {
|
|
19
|
+
"status": "SECURE_PERIMETER_ACTIVE",
|
|
20
|
+
"chain_length": len(self.ledger.chain),
|
|
21
|
+
"axiomos_risk": risk_status,
|
|
22
|
+
"head_hash": head_hash
|
|
23
|
+
}
|
|
24
|
+
await asyncio.sleep(1.0)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class EnterpriseComplianceSync:
|
|
2
|
+
"""Enterprise-tier synchronization for automated multi-node ledger backups and regulatory reporting."""
|
|
3
|
+
|
|
4
|
+
def __init__(self, license_key: str):
|
|
5
|
+
self.license_key = license_key
|
|
6
|
+
self._validate_license()
|
|
7
|
+
|
|
8
|
+
def _validate_license(self):
|
|
9
|
+
if not self.license_key or not self.license_key.startswith("TG-ENT-"):
|
|
10
|
+
raise PermissionError("Valid commercial TraceGuard Enterprise license required for cloud synchronization.")
|
|
11
|
+
|
|
12
|
+
async def push_audit_telemetry(self, compliance_packet: str) -> dict:
|
|
13
|
+
return {
|
|
14
|
+
"status": "SYNCED",
|
|
15
|
+
"secure_cloud_node": "regulated-enclave-uk-south",
|
|
16
|
+
"encryption": "AES-256-GCM"
|
|
17
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
class EvidenceLedger:
|
|
5
|
+
def __init__(self):
|
|
6
|
+
self.chain = []
|
|
7
|
+
self.genesis_hash = "0" * 64
|
|
8
|
+
|
|
9
|
+
def append_entry(self, data: dict) -> dict:
|
|
10
|
+
previous_hash = self.chain[-1]["current_hash"] if self.chain else self.genesis_hash
|
|
11
|
+
|
|
12
|
+
entry = {
|
|
13
|
+
"index": len(self.chain),
|
|
14
|
+
"data": data,
|
|
15
|
+
"previous_hash": previous_hash
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
encoded_payload = json.dumps(entry, sort_keys=True).encode()
|
|
19
|
+
current_hash = hashlib.sha256(encoded_payload).hexdigest()
|
|
20
|
+
|
|
21
|
+
entry["current_hash"] = current_hash
|
|
22
|
+
self.chain.append(entry)
|
|
23
|
+
return entry
|
|
24
|
+
|
|
25
|
+
def verify_integrity(self) -> bool:
|
|
26
|
+
if not self.chain:
|
|
27
|
+
return True
|
|
28
|
+
|
|
29
|
+
for i, entry in enumerate(self.chain):
|
|
30
|
+
expected_prev = self.chain[i - 1]["current_hash"] if i > 0 else self.genesis_hash
|
|
31
|
+
if entry["previous_hash"] != expected_prev:
|
|
32
|
+
return False
|
|
33
|
+
|
|
34
|
+
recheck_entry = entry.copy()
|
|
35
|
+
current_hash = recheck_entry.pop("current_hash")
|
|
36
|
+
encoded_payload = json.dumps(recheck_entry, sort_keys=True).encode()
|
|
37
|
+
if hashlib.sha256(encoded_payload).hexdigest() != current_hash:
|
|
38
|
+
return False
|
|
39
|
+
|
|
40
|
+
return True
|
|
41
|
+
|
|
42
|
+
def tamper_with_entry(self, index: int, malicious_data: dict):
|
|
43
|
+
if 0 <= index < len(self.chain):
|
|
44
|
+
self.chain[index]["data"] = malicious_data
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class AssuranceMatrix:
|
|
2
|
+
def calculate_tier(self, consequence: int, autonomy: int, oversight: bool) -> dict:
|
|
3
|
+
score = consequence + autonomy - (2 if oversight else 0)
|
|
4
|
+
if score >= 4:
|
|
5
|
+
tier = "Tier 3 — High Impact"
|
|
6
|
+
elif score >= 2:
|
|
7
|
+
tier = "Tier 2 — Moderate Impact"
|
|
8
|
+
else:
|
|
9
|
+
tier = "Tier 1 — Low Impact"
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
"score": score,
|
|
13
|
+
"tier": tier,
|
|
14
|
+
"oversight_enforced": oversight
|
|
15
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from typing import Callable, Any, Dict
|
|
3
|
+
from traceguard.traceguard import TraceGuard
|
|
4
|
+
from traceguard.asyncledger import AsyncEvidenceLedger
|
|
5
|
+
from traceguard.aximos import AXIOMOSEvaluator
|
|
6
|
+
|
|
7
|
+
class TraceGuardMiddleware:
|
|
8
|
+
"""Intercepts agent action executions, evaluates zero-trust boundaries, and logs cryptographic evidence."""
|
|
9
|
+
|
|
10
|
+
def __init__(self, allowed_actions: list[str]):
|
|
11
|
+
self.guard = TraceGuard(allowed_actions=allowed_actions)
|
|
12
|
+
self.ledger = AsyncEvidenceLedger()
|
|
13
|
+
self.evaluator = AXIOMOSEvaluator(block_threshold=2)
|
|
14
|
+
|
|
15
|
+
async def execute_protected_action(self, agent_id: str, action: str, tool_callable: Callable[..., Any], *args, **kwargs) -> Dict[str, Any]:
|
|
16
|
+
decision = self.guard.evaluate_action(action)
|
|
17
|
+
|
|
18
|
+
entry = await self.ledger.append_entry({
|
|
19
|
+
"agent": agent_id,
|
|
20
|
+
"action": action,
|
|
21
|
+
"decision": decision
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
risk_status = self.evaluator.evaluate_logs(self.ledger.chain)
|
|
25
|
+
|
|
26
|
+
if decision == "BLOCK":
|
|
27
|
+
return {
|
|
28
|
+
"status": "CONTAINED",
|
|
29
|
+
"reason": f"Action '{action}' blocked by boundary policy.",
|
|
30
|
+
"risk_tier": risk_status,
|
|
31
|
+
"provenance_hash": entry["current_hash"]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
try:
|
|
35
|
+
result = tool_callable(*args, **kwargs)
|
|
36
|
+
return {
|
|
37
|
+
"status": "EXECUTED",
|
|
38
|
+
"result": result,
|
|
39
|
+
"risk_tier": risk_status,
|
|
40
|
+
"provenance_hash": entry["current_hash"]
|
|
41
|
+
}
|
|
42
|
+
except Exception as e:
|
|
43
|
+
return {
|
|
44
|
+
"status": "ERROR",
|
|
45
|
+
"error": str(e),
|
|
46
|
+
"risk_tier": risk_status,
|
|
47
|
+
"provenance_hash": entry["current_hash"]
|
|
48
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from fpdf import FPDF
|
|
2
|
+
import json
|
|
3
|
+
|
|
4
|
+
def clean_text(text: str) -> str:
|
|
5
|
+
if not isinstance(text, str):
|
|
6
|
+
return text
|
|
7
|
+
return text.replace('—', '-').replace('–', '-').replace('“', '"').replace('”', '"').replace('‘', "'").replace('’', "'")
|
|
8
|
+
|
|
9
|
+
class EnterprisePDFExporter(FPDF):
|
|
10
|
+
def header(self):
|
|
11
|
+
self.set_font('helvetica', 'B', 10)
|
|
12
|
+
self.set_text_color(88, 166, 255)
|
|
13
|
+
self.cell(0, 10, 'TRACEGUARD-CORE // ENTERPRISE COMPLIANCE DIVISION', 0, 1, 'L')
|
|
14
|
+
self.set_draw_color(48, 54, 61)
|
|
15
|
+
self.line(10, 18, 200, 18)
|
|
16
|
+
self.ln(5)
|
|
17
|
+
|
|
18
|
+
def footer(self):
|
|
19
|
+
self.set_y(-15)
|
|
20
|
+
self.set_font('helvetica', 'I', 8)
|
|
21
|
+
self.set_text_color(139, 148, 158)
|
|
22
|
+
self.cell(0, 10, clean_text(f'Page {self.page_no()} | Immutable Audit Record — Confidential'), 0, 0, 'C')
|
|
23
|
+
|
|
24
|
+
def generate_compliance_pdf(packet: dict, filename: str = "compliance_audit_packet.pdf"):
|
|
25
|
+
pdf = EnterprisePDFExporter()
|
|
26
|
+
pdf.add_page()
|
|
27
|
+
pdf.set_auto_page_break(auto=True, margin=15)
|
|
28
|
+
|
|
29
|
+
# Title Section
|
|
30
|
+
pdf.set_font('helvetica', 'B', 15)
|
|
31
|
+
pdf.set_text_color(33, 33, 33)
|
|
32
|
+
pdf.cell(0, 10, clean_text('ENTERPRISE COMPLIANCE & ASSURANCE AUDIT PACKET'), 0, 1, 'L')
|
|
33
|
+
|
|
34
|
+
# Metadata Block
|
|
35
|
+
pdf.set_font('helvetica', '', 9)
|
|
36
|
+
pdf.set_text_color(100, 100, 100)
|
|
37
|
+
meta = packet['artifact_metadata']
|
|
38
|
+
pdf.cell(0, 6, clean_text(f"System Name: {meta['system_name']}"), 0, 1, 'L')
|
|
39
|
+
pdf.cell(0, 6, clean_text(f"Audit UUID: {meta['audit_uuid']}"), 0, 1, 'L')
|
|
40
|
+
pdf.cell(0, 6, clean_text(f"Timestamp (UTC): {meta['timestamp_utc']}"), 0, 1, 'L')
|
|
41
|
+
pdf.ln(4)
|
|
42
|
+
|
|
43
|
+
# Section 1: Tier Classification
|
|
44
|
+
pdf.set_font('helvetica', 'B', 12)
|
|
45
|
+
pdf.set_text_color(24, 100, 175)
|
|
46
|
+
pdf.cell(0, 8, clean_text('1. Executive Tier Classification'), 0, 1, 'L')
|
|
47
|
+
|
|
48
|
+
pdf.set_font('helvetica', '', 10)
|
|
49
|
+
pdf.set_text_color(50, 50, 50)
|
|
50
|
+
risk = packet['risk_classification']
|
|
51
|
+
pdf.cell(0, 6, clean_text(f"Assigned Tier: {risk['assigned_tier']}"), 0, 1, 'L')
|
|
52
|
+
pdf.cell(0, 6, clean_text(f"Composite Risk Score: {risk['composite_score']} (Consequence: {risk['consequence_level']} | Autonomy: {risk['autonomy_level']} | Oversight: {risk['human_oversight_enforced']})"), 0, 1, 'L')
|
|
53
|
+
pdf.ln(4)
|
|
54
|
+
|
|
55
|
+
# Section 2: Regulatory Alignment
|
|
56
|
+
pdf.set_font('helvetica', 'B', 12)
|
|
57
|
+
pdf.set_text_color(24, 100, 175)
|
|
58
|
+
pdf.cell(0, 8, clean_text('2. Regulatory Alignment'), 0, 1, 'L')
|
|
59
|
+
pdf.set_font('helvetica', '', 10)
|
|
60
|
+
reg_str = ", ".join(packet['regulatory_mapping'])
|
|
61
|
+
pdf.multi_cell(0, 6, clean_text(f"Frameworks Mapped: {reg_str}"))
|
|
62
|
+
pdf.ln(4)
|
|
63
|
+
|
|
64
|
+
# Section 3: Mandatory Governance Controls
|
|
65
|
+
pdf.set_font('helvetica', 'B', 12)
|
|
66
|
+
pdf.set_text_color(24, 100, 175)
|
|
67
|
+
pdf.cell(0, 8, clean_text('3. Mandatory Governance Controls'), 0, 1, 'L')
|
|
68
|
+
pdf.set_font('helvetica', '', 10)
|
|
69
|
+
for control in packet['mandatory_controls']:
|
|
70
|
+
pdf.cell(0, 6, clean_text(f"[X] {control}"), 0, 1, 'L')
|
|
71
|
+
pdf.ln(4)
|
|
72
|
+
|
|
73
|
+
# Section 4: Runtime Boundary Blueprint
|
|
74
|
+
pdf.set_font('helvetica', 'B', 12)
|
|
75
|
+
pdf.set_text_color(24, 100, 175)
|
|
76
|
+
pdf.cell(0, 8, clean_text('4. Runtime Boundary Blueprint'), 0, 1, 'L')
|
|
77
|
+
pdf.set_font('helvetica', '', 10)
|
|
78
|
+
bp = packet['runtime_boundary_blueprint']
|
|
79
|
+
pdf.cell(0, 6, clean_text(f"TraceGuard Enforcement: {bp['traceguard_enforcement']}"), 0, 1, 'L')
|
|
80
|
+
pdf.cell(0, 6, clean_text(f"AXIOMOS Drift Status: {bp['aximos_drift_status']}"), 0, 1, 'L')
|
|
81
|
+
pdf.multi_cell(0, 6, clean_text(f"Permitted Action Schema: {json.dumps(bp['allowed_action_schema'])}"))
|
|
82
|
+
|
|
83
|
+
pdf.output(filename)
|
|
84
|
+
return filename
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class TraceGuard:
|
|
2
|
+
"""Zero-trust runtime boundary enforcement engine for autonomous AI agents."""
|
|
3
|
+
|
|
4
|
+
def __init__(self, allowed_actions: list[str]):
|
|
5
|
+
self.allowed_actions = set(allowed_actions)
|
|
6
|
+
self.breaches = []
|
|
7
|
+
|
|
8
|
+
def evaluate_action(self, action: str) -> str:
|
|
9
|
+
if not action or action not in self.allowed_actions:
|
|
10
|
+
self.breaches.append(action)
|
|
11
|
+
return "BLOCK"
|
|
12
|
+
return "ALLOW"
|
|
13
|
+
|
|
14
|
+
def get_breach_count(self) -> int:
|
|
15
|
+
return len(self.breaches)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: traceguard-core
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Deterministic zero-trust runtime and evidence demonstrator for autonomous AI agent pipelines.
|
|
5
|
+
Author-email: Sigilith Labs <sigilith@proton.me>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Sigilith/traceguard-core
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Python: >=3.11
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: pytest>=8.0.0
|
|
17
|
+
Requires-Dist: pytest-asyncio>=0.23.0
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# TraceGuard
|
|
21
|
+
|
|
22
|
+
TraceGuard is a zero-trust governance and audit framework providing:
|
|
23
|
+
- Action verification
|
|
24
|
+
- Ledger integrity
|
|
25
|
+
- AXIOMOS risk scoring
|
|
26
|
+
- Compliance reporting
|
|
27
|
+
- CLI demo
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
pip install traceguard
|
|
31
|
+
|
|
32
|
+
## Examples
|
|
33
|
+
See the `examples/` directory.
|
|
34
|
+
|
|
35
|
+
## Documentation
|
|
36
|
+
See the `docs/` directory.
|
|
37
|
+
|
|
38
|
+
## CLI
|
|
39
|
+
traceguard demo
|
|
40
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/traceguard/__init__.py
|
|
5
|
+
src/traceguard/asyncledger.py
|
|
6
|
+
src/traceguard/aximos.py
|
|
7
|
+
src/traceguard/cli.py
|
|
8
|
+
src/traceguard/compliance_audit.py
|
|
9
|
+
src/traceguard/compliance_report.py
|
|
10
|
+
src/traceguard/dashboard_stream.py
|
|
11
|
+
src/traceguard/enterprise.py
|
|
12
|
+
src/traceguard/evidence.py
|
|
13
|
+
src/traceguard/matrix.py
|
|
14
|
+
src/traceguard/middleware.py
|
|
15
|
+
src/traceguard/pdf_generator.py
|
|
16
|
+
src/traceguard/traceguard.py
|
|
17
|
+
src/traceguard_core.egg-info/PKG-INFO
|
|
18
|
+
src/traceguard_core.egg-info/SOURCES.txt
|
|
19
|
+
src/traceguard_core.egg-info/dependency_links.txt
|
|
20
|
+
src/traceguard_core.egg-info/requires.txt
|
|
21
|
+
src/traceguard_core.egg-info/top_level.txt
|
|
22
|
+
tests/test_async_ledger.py
|
|
23
|
+
tests/test_compliance_audit.py
|
|
24
|
+
tests/test_engine.py
|
|
25
|
+
tests/test_evidence.py
|
|
26
|
+
tests/test_middleware.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
traceguard
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
import asyncio
|
|
3
|
+
from traceguard.asyncledger import AsyncEvidenceLedger
|
|
4
|
+
|
|
5
|
+
@pytest.mark.asyncio
|
|
6
|
+
async def test_async_ledger_basic():
|
|
7
|
+
ledger = AsyncEvidenceLedger()
|
|
8
|
+
entry1 = await ledger.append_entry({"action": "test_1", "decision": "ALLOW"})
|
|
9
|
+
entry2 = await ledger.append_entry({"action": "test_2", "decision": "BLOCK"})
|
|
10
|
+
|
|
11
|
+
assert len(ledger.chain) == 2
|
|
12
|
+
assert entry2["prev_hash"] == entry1["current_hash"]
|
|
13
|
+
assert await ledger.verify_integrity() is True
|
|
14
|
+
|
|
15
|
+
@pytest.mark.asyncio
|
|
16
|
+
async def test_async_concurrency():
|
|
17
|
+
ledger = AsyncEvidenceLedger()
|
|
18
|
+
|
|
19
|
+
async def simulate_agent_action(i):
|
|
20
|
+
return await ledger.append_entry({"action": f"action_{i}", "decision": "ALLOW"})
|
|
21
|
+
|
|
22
|
+
await asyncio.gather(*(simulate_agent_action(i) for i in range(25)))
|
|
23
|
+
assert len(ledger.chain) == 25
|
|
24
|
+
assert await ledger.verify_integrity() is True
|
|
25
|
+
|
|
26
|
+
@pytest.mark.asyncio
|
|
27
|
+
async def test_tamper_detection():
|
|
28
|
+
ledger = AsyncEvidenceLedger()
|
|
29
|
+
await ledger.append_entry({"action": "safe", "decision": "ALLOW"})
|
|
30
|
+
await ledger.append_entry({"action": "unsafe", "decision": "BLOCK"})
|
|
31
|
+
|
|
32
|
+
# Corrupt a past record manually
|
|
33
|
+
ledger.chain[0]["payload"]["action"] = "tampered_action"
|
|
34
|
+
|
|
35
|
+
assert await ledger.verify_integrity() is False
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
import asyncio
|
|
3
|
+
import json
|
|
4
|
+
from traceguard.asyncledger import AsyncEvidenceLedger
|
|
5
|
+
from traceguard.aximos import AXIOMOSEvaluator
|
|
6
|
+
from traceguard.compliance_audit import ComplianceAuditGenerator
|
|
7
|
+
|
|
8
|
+
@pytest.mark.asyncio
|
|
9
|
+
async def test_compliance_packet_generation():
|
|
10
|
+
ledger = AsyncEvidenceLedger()
|
|
11
|
+
await ledger.append_entry({"test": "audit_entry"})
|
|
12
|
+
evaluator = AXIOMOSEvaluator()
|
|
13
|
+
|
|
14
|
+
generator = ComplianceAuditGenerator(ledger, evaluator)
|
|
15
|
+
packet_json = await generator.generate_audit_packet("Ofgem High-Impact AI Assurance")
|
|
16
|
+
|
|
17
|
+
data = json.loads(packet_json)
|
|
18
|
+
assert data["regulatory_framework"] == "Ofgem High-Impact AI Assurance"
|
|
19
|
+
assert data["ledger_metrics"]["total_records"] == 1
|
|
20
|
+
assert data["ledger_metrics"]["hash_chain_integrity_verified"] is True
|
|
21
|
+
assert data["governance_evaluation"]["mandatory_controls_met"] is True
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from traceguard import TraceGuard, AXIOMOSEvaluator
|
|
3
|
+
|
|
4
|
+
def test_traceguard_allowed_action():
|
|
5
|
+
guard = TraceGuard(allowed_actions=["read_logs"])
|
|
6
|
+
assert guard.evaluate_action("read_logs") == "ALLOW"
|
|
7
|
+
|
|
8
|
+
def test_traceguard_unauthorized_block():
|
|
9
|
+
guard = TraceGuard(allowed_actions=["read_logs"])
|
|
10
|
+
assert guard.evaluate_action("drop_tables") == "BLOCK"
|
|
11
|
+
|
|
12
|
+
def test_traceguard_malformed_request():
|
|
13
|
+
guard = TraceGuard(allowed_actions=["read_logs"])
|
|
14
|
+
assert guard.evaluate_action("") == "BLOCK"
|
|
15
|
+
|
|
16
|
+
def test_traceguard_repeated_breach_persistence():
|
|
17
|
+
guard = TraceGuard(allowed_actions=["read_logs"])
|
|
18
|
+
guard.evaluate_action("unauthorized_1")
|
|
19
|
+
guard.evaluate_action("unauthorized_2")
|
|
20
|
+
assert guard.get_breach_count() == 2
|
|
21
|
+
|
|
22
|
+
def test_aximos_risk_fixtures():
|
|
23
|
+
evaluator = AXIOMOSEvaluator()
|
|
24
|
+
dummy_chain = [{"payload": {"decision": "BLOCK"}}, {"payload": {"decision": "BLOCK"}}]
|
|
25
|
+
tier = evaluator.evaluate_logs(dummy_chain)
|
|
26
|
+
assert tier in ["LOW_RISK", "NOMINAL", "ELEVATED_THREAT", "HIGH_RISK_CONTAINMENT"]
|
|
27
|
+
|
|
28
|
+
def test_assurance_matrix():
|
|
29
|
+
evaluator = AXIOMOSEvaluator(block_threshold=1)
|
|
30
|
+
dummy_chain = [{"payload": {"decision": "BLOCK"}}]
|
|
31
|
+
tier = evaluator.evaluate_logs(dummy_chain)
|
|
32
|
+
assert tier in ["LOW_RISK", "HIGH_RISK_CONTAINMENT"]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
import asyncio
|
|
3
|
+
from traceguard import AsyncEvidenceLedger
|
|
4
|
+
|
|
5
|
+
@pytest.mark.asyncio
|
|
6
|
+
async def test_ledger_integrity_valid():
|
|
7
|
+
ledger = AsyncEvidenceLedger()
|
|
8
|
+
await ledger.append_entry({"action": "test_1"})
|
|
9
|
+
await ledger.append_entry({"action": "test_2"})
|
|
10
|
+
assert await ledger.verify_integrity() is True
|
|
11
|
+
|
|
12
|
+
@pytest.mark.asyncio
|
|
13
|
+
async def test_ledger_tamper_detection():
|
|
14
|
+
ledger = AsyncEvidenceLedger()
|
|
15
|
+
await ledger.append_entry({"action": "test_1"})
|
|
16
|
+
await ledger.append_entry({"action": "test_2"})
|
|
17
|
+
|
|
18
|
+
# Tamper with historical payload
|
|
19
|
+
ledger.chain[0]["payload"]["action"] = "tampered"
|
|
20
|
+
assert await ledger.verify_integrity() is False
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
import asyncio
|
|
3
|
+
from traceguard.middleware import TraceGuardMiddleware
|
|
4
|
+
|
|
5
|
+
@pytest.mark.asyncio
|
|
6
|
+
async def test_middleware_allowed_action():
|
|
7
|
+
middleware = TraceGuardMiddleware(allowed_actions=["safe_query"])
|
|
8
|
+
def mock_tool():
|
|
9
|
+
return "success_data"
|
|
10
|
+
|
|
11
|
+
res = await middleware.execute_protected_action("agent_1", "safe_query", mock_tool)
|
|
12
|
+
assert res["status"] == "EXECUTED"
|
|
13
|
+
assert res["result"] == "success_data"
|
|
14
|
+
assert "provenance_hash" in res
|
|
15
|
+
|
|
16
|
+
@pytest.mark.asyncio
|
|
17
|
+
async def test_middleware_blocked_action():
|
|
18
|
+
middleware = TraceGuardMiddleware(allowed_actions=["safe_query"])
|
|
19
|
+
def mock_tool():
|
|
20
|
+
return "should_not_run"
|
|
21
|
+
|
|
22
|
+
res = await middleware.execute_protected_action("agent_1", "unauthorized_drop", mock_tool)
|
|
23
|
+
assert res["status"] == "CONTAINED"
|
|
24
|
+
assert res["risk_tier"] is not None
|
|
25
|
+
assert "provenance_hash" in res
|