xoras-agent-framework 2.0.0__py3-none-any.whl
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.
- build/lib/build/lib/examples/01_basic_agent.py +29 -0
- build/lib/build/lib/examples/02_secure_code_evaluator.py +31 -0
- build/lib/build/lib/tests/test_ast_security.py +47 -0
- build/lib/build/lib/tests/test_runtime.py +42 -0
- build/lib/build/lib/tests/test_signer.py +27 -0
- build/lib/build/lib/xoras/__init__.py +23 -0
- build/lib/build/lib/xoras/ast_security.py +141 -0
- build/lib/build/lib/xoras/cli.py +211 -0
- build/lib/build/lib/xoras/config.py +102 -0
- build/lib/build/lib/xoras/orchestrator.py +69 -0
- build/lib/build/lib/xoras/runtime.py +157 -0
- build/lib/build/lib/xoras/signer.py +64 -0
- build/lib/examples/01_basic_agent.py +29 -0
- build/lib/examples/02_secure_code_evaluator.py +31 -0
- build/lib/tests/test_ast_security.py +47 -0
- build/lib/tests/test_runtime.py +42 -0
- build/lib/tests/test_signer.py +27 -0
- build/lib/xoras/__init__.py +23 -0
- build/lib/xoras/ast_security.py +141 -0
- build/lib/xoras/cli.py +211 -0
- build/lib/xoras/config.py +102 -0
- build/lib/xoras/orchestrator.py +69 -0
- build/lib/xoras/runtime.py +157 -0
- build/lib/xoras/signer.py +64 -0
- examples/01_basic_agent.py +29 -0
- examples/02_secure_code_evaluator.py +31 -0
- tests/test_ast_security.py +47 -0
- tests/test_runtime.py +42 -0
- tests/test_signer.py +27 -0
- xoras/__init__.py +23 -0
- xoras/ast_security.py +141 -0
- xoras/cli.py +211 -0
- xoras/config.py +102 -0
- xoras/orchestrator.py +69 -0
- xoras/runtime.py +157 -0
- xoras/signer.py +64 -0
- xoras_agent_framework-2.0.0.dist-info/METADATA +130 -0
- xoras_agent_framework-2.0.0.dist-info/RECORD +42 -0
- xoras_agent_framework-2.0.0.dist-info/WHEEL +5 -0
- xoras_agent_framework-2.0.0.dist-info/entry_points.txt +2 -0
- xoras_agent_framework-2.0.0.dist-info/licenses/LICENSE +21 -0
- xoras_agent_framework-2.0.0.dist-info/top_level.txt +9 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
XORAS Agentic Framework — Basic Agent Example
|
|
4
|
+
Demonstrates environment initialization, tool execution, and signed trace receipts.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from xoras import XORASAgentEnvironment
|
|
8
|
+
|
|
9
|
+
def main():
|
|
10
|
+
print("=== XORAS Agent Framework — Basic Agent Example ===")
|
|
11
|
+
env = XORASAgentEnvironment(config_path="xoras.env.yaml")
|
|
12
|
+
|
|
13
|
+
# Execute a safe file write tool
|
|
14
|
+
result = env.execute_tool(
|
|
15
|
+
agent_name="Engineer",
|
|
16
|
+
tool_name="file_write",
|
|
17
|
+
args={
|
|
18
|
+
"path": "artifacts/basic_agent_output.json",
|
|
19
|
+
"content": '{"message": "Hello from XORAS Agent Framework v2.0", "status": "active"}'
|
|
20
|
+
}
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
print("\nExecution Result:")
|
|
24
|
+
print("Success:", result.get("success"))
|
|
25
|
+
print("Path:", result.get("path"))
|
|
26
|
+
print("Receipt Signature:", result.get("receipt_signature"))
|
|
27
|
+
|
|
28
|
+
if __name__ == "__main__":
|
|
29
|
+
main()
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
XORAS Agentic Framework — AST Code Security Evaluator
|
|
4
|
+
Demonstrates AST static analysis and rejection of unsafe dynamic code snippets.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from xoras import ASTSecurityEngine
|
|
8
|
+
|
|
9
|
+
def evaluate_snippets():
|
|
10
|
+
engine = ASTSecurityEngine()
|
|
11
|
+
|
|
12
|
+
snippets = [
|
|
13
|
+
("Safe Data Handler", "def process(x):\n return x.strip().lower()\n"),
|
|
14
|
+
("Dynamic Eval Snippet", "eval('import os; os.system(\"ls\")')\n"),
|
|
15
|
+
("Unsafe Subprocess", "import subprocess\nsubprocess.Popen('rm -rf /tmp', shell=True)\n"),
|
|
16
|
+
("Hardcoded API Key", "AWS_SECRET_ACCESS_KEY = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'\n")
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
print("=== XORAS AST Security Evaluator Demo ===")
|
|
20
|
+
for title, code in snippets:
|
|
21
|
+
res = engine.scan_code(code)
|
|
22
|
+
print(f"\n[Snippet]: {title}")
|
|
23
|
+
print(f"Status: {'SAFE [PASSED]' if res.is_safe else 'UNSAFE [REJECTED]'}")
|
|
24
|
+
print(f"Safety Score: {res.safety_score * 100:.1f}%")
|
|
25
|
+
if res.violations:
|
|
26
|
+
print("Violations:", res.violations)
|
|
27
|
+
if res.secrets_detected:
|
|
28
|
+
print("Secrets:", res.secrets_detected)
|
|
29
|
+
|
|
30
|
+
if __name__ == "__main__":
|
|
31
|
+
evaluate_snippets()
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for XORAS AST Security Engine.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
from xoras.ast_security import ASTSecurityEngine
|
|
7
|
+
|
|
8
|
+
def test_ast_safe_code():
|
|
9
|
+
engine = ASTSecurityEngine()
|
|
10
|
+
code = """
|
|
11
|
+
def calculate_sum(a, b):
|
|
12
|
+
return a + b
|
|
13
|
+
|
|
14
|
+
print(calculate_sum(10, 20))
|
|
15
|
+
"""
|
|
16
|
+
result = engine.scan_code(code)
|
|
17
|
+
assert result.is_safe is True
|
|
18
|
+
assert result.safety_score == 1.0
|
|
19
|
+
assert len(result.violations) == 0
|
|
20
|
+
|
|
21
|
+
def test_ast_forbidden_eval():
|
|
22
|
+
engine = ASTSecurityEngine()
|
|
23
|
+
code = """
|
|
24
|
+
x = 10
|
|
25
|
+
eval("print(x)")
|
|
26
|
+
"""
|
|
27
|
+
result = engine.scan_code(code)
|
|
28
|
+
assert result.is_safe is False
|
|
29
|
+
assert any("eval()" in v for v in result.violations)
|
|
30
|
+
|
|
31
|
+
def test_ast_forbidden_exec():
|
|
32
|
+
engine = ASTSecurityEngine()
|
|
33
|
+
code = """
|
|
34
|
+
exec("import os; os.system('ls')")
|
|
35
|
+
"""
|
|
36
|
+
result = engine.scan_code(code)
|
|
37
|
+
assert result.is_safe is False
|
|
38
|
+
assert any("exec()" in v for v in result.violations)
|
|
39
|
+
|
|
40
|
+
def test_ast_secret_leak_detection():
|
|
41
|
+
engine = ASTSecurityEngine()
|
|
42
|
+
code = """
|
|
43
|
+
AWS_SECRET_ACCESS_KEY = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
|
|
44
|
+
"""
|
|
45
|
+
result = engine.scan_code(code)
|
|
46
|
+
assert result.is_safe is False
|
|
47
|
+
assert len(result.secrets_detected) > 0
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for XORAS Agentic Runtime & Orchestrator.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from xoras.runtime import XORASAgentEnvironment
|
|
7
|
+
from xoras.orchestrator import SwarmOrchestrator
|
|
8
|
+
|
|
9
|
+
def test_runtime_file_write_and_read():
|
|
10
|
+
env = XORASAgentEnvironment(config_path="xoras.env.yaml")
|
|
11
|
+
write_res = env.execute_tool("Engineer", "file_write", {
|
|
12
|
+
"path": "artifacts/test_artifact.json",
|
|
13
|
+
"content": '{"version": "2.0.0", "status": "active"}'
|
|
14
|
+
})
|
|
15
|
+
assert write_res["success"] is True
|
|
16
|
+
assert "receipt_signature" in write_res
|
|
17
|
+
|
|
18
|
+
read_res = env.execute_tool("Engineer", "file_read", {
|
|
19
|
+
"path": "artifacts/test_artifact.json"
|
|
20
|
+
})
|
|
21
|
+
assert read_res["success"] is True
|
|
22
|
+
assert "active" in read_res["content"]
|
|
23
|
+
|
|
24
|
+
def test_runtime_ast_rejection():
|
|
25
|
+
env = XORASAgentEnvironment(config_path="xoras.env.yaml")
|
|
26
|
+
unsafe_res = env.execute_tool("Engineer", "file_write", {
|
|
27
|
+
"path": "artifacts/bad.py",
|
|
28
|
+
"content": 'eval("print(\'unsafe\')")'
|
|
29
|
+
})
|
|
30
|
+
assert unsafe_res["success"] is False
|
|
31
|
+
assert "blocked by XORAS AST security" in unsafe_res["error"]
|
|
32
|
+
|
|
33
|
+
def test_swarm_orchestrator_pipeline():
|
|
34
|
+
orch = SwarmOrchestrator()
|
|
35
|
+
res = orch.run_pipeline(
|
|
36
|
+
task_description="Deploy secure configuration manifest",
|
|
37
|
+
code_payload='{"config": "valid_json"}',
|
|
38
|
+
target_path="artifacts/swarm_output.json"
|
|
39
|
+
)
|
|
40
|
+
assert res["success"] is True
|
|
41
|
+
assert res["stage"] == "COMPLETED"
|
|
42
|
+
assert res["safety_score"] == 1.0
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Unit tests for XORAS Cryptographic Signer.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from xoras.signer import CryptographicSigner
|
|
6
|
+
|
|
7
|
+
def test_evidence_receipt_signing_and_verification():
|
|
8
|
+
signer = CryptographicSigner()
|
|
9
|
+
payload = {"path": "test.txt", "content": "hello world"}
|
|
10
|
+
receipt = signer.sign_receipt("Engineer", "file_write", payload, "SUCCESS")
|
|
11
|
+
|
|
12
|
+
assert receipt.version == "xoras.evidence.v1"
|
|
13
|
+
assert receipt.organization == "XORAS Systems LLC"
|
|
14
|
+
assert receipt.status == "SUCCESS"
|
|
15
|
+
assert receipt.signature is not None
|
|
16
|
+
|
|
17
|
+
# Verify signature mathematically
|
|
18
|
+
assert signer.verify_receipt(receipt) is True
|
|
19
|
+
|
|
20
|
+
def test_evidence_receipt_tamper_rejection():
|
|
21
|
+
signer = CryptographicSigner()
|
|
22
|
+
payload = {"path": "test.txt", "content": "hello world"}
|
|
23
|
+
receipt = signer.sign_receipt("Engineer", "file_write", payload, "SUCCESS")
|
|
24
|
+
|
|
25
|
+
# Tamper with status
|
|
26
|
+
receipt.status = "FAILED"
|
|
27
|
+
assert signer.verify_receipt(receipt) is False
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
XORAS Systems LLC — Agentic Environment & Governance Framework
|
|
3
|
+
Enterprise-grade multi-agent runtime, AST static security gating, and cryptographic provenance receipts.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
__version__ = "2.0.0"
|
|
7
|
+
__author__ = "XORAS Systems LLC"
|
|
8
|
+
|
|
9
|
+
from .config import XORASConfig
|
|
10
|
+
from .ast_security import ASTSecurityEngine, ASTScanResult
|
|
11
|
+
from .signer import CryptographicSigner, EvidenceReceipt
|
|
12
|
+
from .runtime import XORASAgentEnvironment
|
|
13
|
+
from .orchestrator import SwarmOrchestrator
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"XORASConfig",
|
|
17
|
+
"ASTSecurityEngine",
|
|
18
|
+
"ASTScanResult",
|
|
19
|
+
"CryptographicSigner",
|
|
20
|
+
"EvidenceReceipt",
|
|
21
|
+
"XORASAgentEnvironment",
|
|
22
|
+
"SwarmOrchestrator",
|
|
23
|
+
]
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"""
|
|
2
|
+
XORAS Systems LLC — AST Security Engine & Secret Scanner
|
|
3
|
+
Performs strict Abstract Syntax Tree (AST) static analysis and entropy secret detection.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import ast
|
|
7
|
+
import re
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
from typing import List, Dict, Any, Optional
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class ASTScanResult:
|
|
13
|
+
is_safe: bool
|
|
14
|
+
violations: List[str] = field(default_factory=list)
|
|
15
|
+
secrets_detected: List[str] = field(default_factory=list)
|
|
16
|
+
safety_score: float = 1.0
|
|
17
|
+
nodes_analyzed: int = 0
|
|
18
|
+
|
|
19
|
+
class ASTSecurityVisitor(ast.NodeVisitor):
|
|
20
|
+
def __init__(self):
|
|
21
|
+
self.violations: List[str] = []
|
|
22
|
+
self.nodes_analyzed: int = 0
|
|
23
|
+
|
|
24
|
+
# Unsafe call names
|
|
25
|
+
self.forbidden_calls = {
|
|
26
|
+
"eval": "Dynamic evaluation via eval() is strictly prohibited by XORAS AST Guardrails.",
|
|
27
|
+
"exec": "Dynamic execution via exec() is strictly prohibited by XORAS AST Guardrails.",
|
|
28
|
+
"compile": "Dynamic compilation via compile() is prohibited in agent runtime.",
|
|
29
|
+
"__import__": "Dynamic import via __import__ is prohibited.",
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
# Unsafe module imports
|
|
33
|
+
self.dangerous_modules = {
|
|
34
|
+
"ctypes": "Raw memory manipulation via ctypes is restricted.",
|
|
35
|
+
"pty": "Pseudo-terminal creation via pty is prohibited.",
|
|
36
|
+
"code": "Interactive interpreter via code module is restricted."
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
def visit(self, node):
|
|
40
|
+
self.nodes_analyzed += 1
|
|
41
|
+
super().visit(node)
|
|
42
|
+
|
|
43
|
+
def visit_Call(self, node):
|
|
44
|
+
# Inspect function call names
|
|
45
|
+
func_name = None
|
|
46
|
+
if isinstance(node.func, ast.Name):
|
|
47
|
+
func_name = node.func.id
|
|
48
|
+
elif isinstance(node.func, ast.Attribute):
|
|
49
|
+
func_name = node.func.attr
|
|
50
|
+
|
|
51
|
+
if func_name in self.forbidden_calls:
|
|
52
|
+
self.violations.append(f"Line {getattr(node, 'lineno', '?')}: {self.forbidden_calls[func_name]}")
|
|
53
|
+
|
|
54
|
+
# Check os.system / subprocess.Popen with unsafe args
|
|
55
|
+
if isinstance(node.func, ast.Attribute) and isinstance(node.func.value, ast.Name):
|
|
56
|
+
module_name = node.func.value.id
|
|
57
|
+
if module_name == "os" and func_name in ("system", "popen", "execv", "execl"):
|
|
58
|
+
# Inspect string argument if available
|
|
59
|
+
if node.args and isinstance(node.args[0], ast.Constant):
|
|
60
|
+
arg_val = str(node.args[0].value)
|
|
61
|
+
if "rm -rf" in arg_val or "sudo " in arg_val or "> /dev/" in arg_val:
|
|
62
|
+
self.violations.append(f"Line {getattr(node, 'lineno', '?')}: High-risk shell command in os.{func_name}: '{arg_val}'")
|
|
63
|
+
elif module_name == "subprocess" and func_name in ("Popen", "call", "run"):
|
|
64
|
+
# Check shell=True kwargs
|
|
65
|
+
for keyword in node.keywords:
|
|
66
|
+
if keyword.arg == "shell" and isinstance(keyword.value, ast.Constant) and keyword.value.value is True:
|
|
67
|
+
self.violations.append(f"Line {getattr(node, 'lineno', '?')}: Subprocess invocation with shell=True is restricted under XORAS AST policy.")
|
|
68
|
+
|
|
69
|
+
self.generic_visit(node)
|
|
70
|
+
|
|
71
|
+
def visit_Import(self, node):
|
|
72
|
+
for alias in node.names:
|
|
73
|
+
if alias.name in self.dangerous_modules:
|
|
74
|
+
self.violations.append(f"Line {getattr(node, 'lineno', '?')}: {self.dangerous_modules[alias.name]}")
|
|
75
|
+
self.generic_visit(node)
|
|
76
|
+
|
|
77
|
+
def visit_ImportFrom(self, node):
|
|
78
|
+
if node.module in self.dangerous_modules:
|
|
79
|
+
self.violations.append(f"Line {getattr(node, 'lineno', '?')}: {self.dangerous_modules[node.module]}")
|
|
80
|
+
self.generic_visit(node)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class ASTSecurityEngine:
|
|
84
|
+
SECRET_PATTERNS = [
|
|
85
|
+
(r'(?i)(?:aws_access_key_id|aws_secret_access_key|api_key|secret_key|private_key)\s*[:=]\s*["\']([^"\']{8,})["\']', "Hardcoded API / Secret Key"),
|
|
86
|
+
(r'AKIA[0-9A-Z]{16}', "AWS Access Key ID"),
|
|
87
|
+
(r'sk_live_[0-9a-zA-Z]{24,}', "Stripe Live API Key"),
|
|
88
|
+
(r'sk-(?:proj-)?[a-zA-Z0-9_-]{32,}', "OpenAI API Key"),
|
|
89
|
+
(r'sk-ant-[a-zA-Z0-9_-]{32,}', "Anthropic API Key"),
|
|
90
|
+
(r'AIzaSy[0-9a-zA-Z_-]{33}', "Google Gemini API Key"),
|
|
91
|
+
(r'xox[baprs]-[0-9a-zA-Z]{10,48}', "Slack OAuth / Bot Token"),
|
|
92
|
+
(r'ghp_[0-9a-zA-Z]{36}', "GitHub Personal Access Token"),
|
|
93
|
+
(r'-----BEGIN\s+(?:RSA|EC|OPENSSH|PRIVATE)\s+KEY-----', "Private Cryptographic Key Block"),
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
def __init__(self, strict_mode: bool = True):
|
|
97
|
+
self.strict_mode = strict_mode
|
|
98
|
+
|
|
99
|
+
def scan_code(self, code_snippet: str) -> ASTScanResult:
|
|
100
|
+
"""Parses python AST syntax tree and runs regex secret scanning."""
|
|
101
|
+
violations: List[str] = []
|
|
102
|
+
secrets_detected: List[str] = []
|
|
103
|
+
|
|
104
|
+
# 1. Secret scanning across raw code
|
|
105
|
+
for pattern, desc in self.SECRET_PATTERNS:
|
|
106
|
+
matches = re.findall(pattern, code_snippet)
|
|
107
|
+
if matches:
|
|
108
|
+
secrets_detected.append(f"Secret Leak Warning: Detected {desc} pattern in code payload.")
|
|
109
|
+
violations.append(f"Secret Scanner: High-entropy token matching '{desc}' found.")
|
|
110
|
+
|
|
111
|
+
# 2. Syntax validation & AST parsing
|
|
112
|
+
nodes_analyzed = 0
|
|
113
|
+
try:
|
|
114
|
+
tree = ast.parse(code_snippet)
|
|
115
|
+
visitor = ASTSecurityVisitor()
|
|
116
|
+
visitor.visit(tree)
|
|
117
|
+
violations.extend(visitor.violations)
|
|
118
|
+
nodes_analyzed = visitor.nodes_analyzed
|
|
119
|
+
except SyntaxError as e:
|
|
120
|
+
# If not python syntax (e.g. bash script), fallback to regex heuristic scanner
|
|
121
|
+
nodes_analyzed = len(code_snippet.splitlines())
|
|
122
|
+
forbidden_heuristics = [
|
|
123
|
+
(r'\beval\s*\(', "Dynamic eval() invocation"),
|
|
124
|
+
(r'\bexec\s*\(', "Dynamic exec() invocation"),
|
|
125
|
+
(r'rm\s+-rf\s+/', "Destructive root filesystem command 'rm -rf /'"),
|
|
126
|
+
(r':\(\)\{\s*:\|:&\s*\};:', "Fork bomb pattern"),
|
|
127
|
+
]
|
|
128
|
+
for pat, msg in forbidden_heuristics:
|
|
129
|
+
if re.search(pat, code_snippet):
|
|
130
|
+
violations.append(f"Heuristic AST Fallback Violation: Detected forbidden pattern '{msg}'")
|
|
131
|
+
|
|
132
|
+
is_safe = len(violations) == 0
|
|
133
|
+
safety_score = max(0.0, 1.0 - (len(violations) * 0.35))
|
|
134
|
+
|
|
135
|
+
return ASTScanResult(
|
|
136
|
+
is_safe=is_safe,
|
|
137
|
+
violations=violations,
|
|
138
|
+
secrets_detected=secrets_detected,
|
|
139
|
+
safety_score=round(safety_score, 4),
|
|
140
|
+
nodes_analyzed=nodes_analyzed
|
|
141
|
+
)
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"""
|
|
2
|
+
XORAS Systems LLC — CLI Tooling Entrypoint (xoras-cli)
|
|
3
|
+
Command line interface for initializing environments, running AST security scans, and serving web dashboards.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import argparse
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
import http.server
|
|
11
|
+
import socketserver
|
|
12
|
+
import webbrowser
|
|
13
|
+
from typing import List
|
|
14
|
+
|
|
15
|
+
from .config import XORASConfig
|
|
16
|
+
from .ast_security import ASTSecurityEngine
|
|
17
|
+
from .runtime import XORASAgentEnvironment
|
|
18
|
+
from .orchestrator import SwarmOrchestrator
|
|
19
|
+
|
|
20
|
+
DEFAULT_RULES = """# XORAS SYSTEMS LLC — AGENTIC ENVIRONMENT & GOVERNANCE SPECIFICATION
|
|
21
|
+
|
|
22
|
+
[AGENT_IDENTITY]
|
|
23
|
+
Entity: XORAS Autonomous Agent Node
|
|
24
|
+
Architecture: Multi-Agent Orchestrator (XORAS Swarm)
|
|
25
|
+
Governance Policy: Strict Execution Guardrails & AST Safety Verification
|
|
26
|
+
|
|
27
|
+
[OPERATIONAL_DIRECTIVES]
|
|
28
|
+
1. AUTONOMOUS_EXECUTION: Resolve intent via iterative state evaluation, tool invocation, and self-correction prior to human escalation.
|
|
29
|
+
2. AST_SECURITY_GATING: All dynamic code execution, subprocess calls, and external payloads must pass AST static analysis and secret scanning (`env-integrity-sentry`).
|
|
30
|
+
3. ZERO_DRIFT_BRANDING: Enforce XORAS Systems LLC branding across all client-facing artifacts, logs, and generated assets. Legacy naming is prohibited.
|
|
31
|
+
4. DETERMINISTIC_LOGGING: Every agent state transition, tool call, and FFI interaction must produce structured JSON-L traces.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
DEFAULT_ENV_YAML = """version: "2.0.0"
|
|
35
|
+
organization: "XORAS Systems LLC"
|
|
36
|
+
runtime:
|
|
37
|
+
environment_type: "agentic-sandbox"
|
|
38
|
+
concurrency_limit: 8
|
|
39
|
+
default_timeout_seconds: 120
|
|
40
|
+
memory_limit_mb: 4096
|
|
41
|
+
|
|
42
|
+
security:
|
|
43
|
+
ast_verification: true
|
|
44
|
+
allow_network_egress: true
|
|
45
|
+
allowed_domains:
|
|
46
|
+
- "github.com"
|
|
47
|
+
- "pypi.org"
|
|
48
|
+
secret_scanner: "env-integrity-sentry"
|
|
49
|
+
block_deprecated_branding: true
|
|
50
|
+
|
|
51
|
+
agent_swarm:
|
|
52
|
+
orchestrator:
|
|
53
|
+
model: "gemini-2.5-flash"
|
|
54
|
+
temperature: 0.1
|
|
55
|
+
max_tokens: 8192
|
|
56
|
+
agents:
|
|
57
|
+
- name: "Architect"
|
|
58
|
+
role: "System design, specification authoring, and state graph planning"
|
|
59
|
+
capabilities: ["file_read", "file_write", "diagram_gen"]
|
|
60
|
+
- name: "Engineer"
|
|
61
|
+
role: "Code generation, refactoring, and AST verification"
|
|
62
|
+
capabilities: ["file_read", "file_write", "bash_exec", "test_runner"]
|
|
63
|
+
- name: "Auditor"
|
|
64
|
+
role: "Security scanning, secret detection, and runtime compliance"
|
|
65
|
+
capabilities: ["ast_scan", "log_audit", "policy_check"]
|
|
66
|
+
|
|
67
|
+
paths:
|
|
68
|
+
workspace_root: "."
|
|
69
|
+
log_output: "./logs/xoras_agent_traces.jsonl"
|
|
70
|
+
artifact_store: "./artifacts"
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
def init_cmd():
|
|
74
|
+
print("[XORAS CLI] Initializing XORAS Agentic Governance Environment...")
|
|
75
|
+
if not os.path.exists(".xorasrules"):
|
|
76
|
+
with open(".xorasrules", "w", encoding="utf-8") as f:
|
|
77
|
+
f.write(DEFAULT_RULES)
|
|
78
|
+
print(" -> Created .xorasrules")
|
|
79
|
+
else:
|
|
80
|
+
print(" -> .xorasrules already exists.")
|
|
81
|
+
|
|
82
|
+
if not os.path.exists("xoras.env.yaml"):
|
|
83
|
+
with open("xoras.env.yaml", "w", encoding="utf-8") as f:
|
|
84
|
+
f.write(DEFAULT_ENV_YAML)
|
|
85
|
+
print(" -> Created xoras.env.yaml")
|
|
86
|
+
else:
|
|
87
|
+
print(" -> xoras.env.yaml already exists.")
|
|
88
|
+
|
|
89
|
+
os.makedirs("logs", exist_ok=True)
|
|
90
|
+
os.makedirs("artifacts", exist_ok=True)
|
|
91
|
+
print("[XORAS CLI] Initialization complete. Your workspace is secured with XORAS AST Guardrails.")
|
|
92
|
+
|
|
93
|
+
def scan_cmd(target_file: str):
|
|
94
|
+
print(f"[XORAS CLI] Running AST Security Scan on target: '{target_file}'")
|
|
95
|
+
if not os.path.exists(target_file):
|
|
96
|
+
print(f"Error: Target file or directory '{target_file}' not found.")
|
|
97
|
+
sys.exit(1)
|
|
98
|
+
|
|
99
|
+
files_to_scan: List[str] = []
|
|
100
|
+
if os.path.isdir(target_file):
|
|
101
|
+
for root, _, files in os.walk(target_file):
|
|
102
|
+
for file in files:
|
|
103
|
+
if file.endswith(".py"):
|
|
104
|
+
files_to_scan.append(os.path.join(root, file))
|
|
105
|
+
else:
|
|
106
|
+
files_to_scan.append(target_file)
|
|
107
|
+
|
|
108
|
+
engine = ASTSecurityEngine()
|
|
109
|
+
total_violations = 0
|
|
110
|
+
total_secrets = 0
|
|
111
|
+
any_failed = False
|
|
112
|
+
|
|
113
|
+
for file_path in files_to_scan:
|
|
114
|
+
with open(file_path, "r", encoding="utf-8") as f:
|
|
115
|
+
code = f.read()
|
|
116
|
+
|
|
117
|
+
result = engine.scan_code(code)
|
|
118
|
+
print(f"\n--- AST SCAN REPORT: {file_path} ---")
|
|
119
|
+
print(f"Status: {'PASSED [SAFE]' if result.is_safe else 'REJECTED [UNSAFE]'}")
|
|
120
|
+
print(f"Safety Score: {result.safety_score * 100:.1f}% | AST Nodes Analyzed: {result.nodes_analyzed}")
|
|
121
|
+
|
|
122
|
+
if result.violations:
|
|
123
|
+
total_violations += len(result.violations)
|
|
124
|
+
print("Violations Detected:")
|
|
125
|
+
for v in result.violations:
|
|
126
|
+
print(f" - {v}")
|
|
127
|
+
|
|
128
|
+
if result.secrets_detected:
|
|
129
|
+
total_secrets += len(result.secrets_detected)
|
|
130
|
+
print("Secret Leaks Detected:")
|
|
131
|
+
for s in result.secrets_detected:
|
|
132
|
+
print(f" - {s}")
|
|
133
|
+
|
|
134
|
+
if not result.is_safe:
|
|
135
|
+
any_failed = True
|
|
136
|
+
|
|
137
|
+
print(f"\n[XORAS CLI Summary] Scanned {len(files_to_scan)} file(s). Total Violations: {total_violations} | Total Secret Warnings: {total_secrets}")
|
|
138
|
+
if any_failed:
|
|
139
|
+
sys.exit(2)
|
|
140
|
+
|
|
141
|
+
def run_cmd(target_file: str):
|
|
142
|
+
print(f"[XORAS CLI] Executing script '{target_file}' under XORAS Sandboxed Runtime...")
|
|
143
|
+
if not os.path.exists(target_file):
|
|
144
|
+
print(f"Error: Target file '{target_file}' not found.")
|
|
145
|
+
sys.exit(1)
|
|
146
|
+
|
|
147
|
+
with open(target_file, "r", encoding="utf-8") as f:
|
|
148
|
+
code = f.read()
|
|
149
|
+
|
|
150
|
+
env = XORASAgentEnvironment()
|
|
151
|
+
res = env.execute_tool("Engineer", "bash_exec", {"command": f"{sys.executable} {target_file}"})
|
|
152
|
+
|
|
153
|
+
print("\n--- EXECUTION OUTPUT ---")
|
|
154
|
+
print(res.get("stdout", ""))
|
|
155
|
+
if res.get("stderr"):
|
|
156
|
+
print("STDERR:", res.get("stderr"))
|
|
157
|
+
print(f"Exit Code: {res.get('exit_code', -1)}")
|
|
158
|
+
print(f"Trace Receipt Signature: {res.get('receipt_signature', 'NONE')}")
|
|
159
|
+
|
|
160
|
+
def serve_cmd(port: int = 8080):
|
|
161
|
+
web_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "web")
|
|
162
|
+
if not os.path.exists(web_dir):
|
|
163
|
+
web_dir = os.path.join(os.getcwd(), "web")
|
|
164
|
+
|
|
165
|
+
if not os.path.exists(web_dir):
|
|
166
|
+
print(f"Error: Web dashboard directory '{web_dir}' not found.")
|
|
167
|
+
sys.exit(1)
|
|
168
|
+
|
|
169
|
+
os.chdir(web_dir)
|
|
170
|
+
Handler = http.server.SimpleHTTPRequestHandler
|
|
171
|
+
print(f"[XORAS CLI] Serving Web Product Page & Live Dashboard at http://localhost:{port}")
|
|
172
|
+
try:
|
|
173
|
+
with socketserver.TCPServer(("", port), Handler) as httpd:
|
|
174
|
+
print(f"[XORAS CLI] Server running. Press Ctrl+C to stop.")
|
|
175
|
+
httpd.serve_forever()
|
|
176
|
+
except KeyboardInterrupt:
|
|
177
|
+
print("\n[XORAS CLI] Server stopped.")
|
|
178
|
+
|
|
179
|
+
def main():
|
|
180
|
+
parser = argparse.ArgumentParser(description="XORAS Systems LLC — Agentic Framework CLI")
|
|
181
|
+
subparsers = parser.add_subparsers(dest="command")
|
|
182
|
+
|
|
183
|
+
# init command
|
|
184
|
+
init_p = subparsers.add_parser("init", help="Initialize .xorasrules and xoras.env.yaml in current workspace")
|
|
185
|
+
|
|
186
|
+
# scan command
|
|
187
|
+
scan_p = subparsers.add_parser("scan", help="Run AST security and secret scan on a script")
|
|
188
|
+
scan_p.add_argument("file", help="Python or shell script to scan")
|
|
189
|
+
|
|
190
|
+
# run command
|
|
191
|
+
run_p = subparsers.add_parser("run", help="Run a script through XORAS agentic runtime")
|
|
192
|
+
run_p.add_argument("file", help="Python script to run")
|
|
193
|
+
|
|
194
|
+
# serve command
|
|
195
|
+
serve_p = subparsers.add_parser("serve", help="Serve interactive product landing page and dashboard")
|
|
196
|
+
serve_p.add_argument("--port", type=int, default=8080, help="Port to serve on (default: 8080)")
|
|
197
|
+
|
|
198
|
+
args = parser.parse_args()
|
|
199
|
+
if args.command == "init":
|
|
200
|
+
init_cmd()
|
|
201
|
+
elif args.command == "scan":
|
|
202
|
+
scan_cmd(args.file)
|
|
203
|
+
elif args.command == "run":
|
|
204
|
+
run_cmd(args.file)
|
|
205
|
+
elif args.command == "serve":
|
|
206
|
+
serve_cmd(args.port)
|
|
207
|
+
else:
|
|
208
|
+
parser.print_help()
|
|
209
|
+
|
|
210
|
+
if __name__ == "__main__":
|
|
211
|
+
main()
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""
|
|
2
|
+
XORAS Systems LLC — Configuration Schema Parser & Validator
|
|
3
|
+
Loads and validates xoras.env.yaml runtime configurations.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import os
|
|
7
|
+
import yaml
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
from typing import Dict, Any, List, Optional
|
|
10
|
+
|
|
11
|
+
@dataclass
|
|
12
|
+
class RuntimeConfig:
|
|
13
|
+
environment_type: str = "agentic-sandbox"
|
|
14
|
+
concurrency_limit: int = 8
|
|
15
|
+
default_timeout_seconds: int = 120
|
|
16
|
+
memory_limit_mb: int = 4096
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class SecurityConfig:
|
|
20
|
+
ast_verification: bool = True
|
|
21
|
+
allow_network_egress: bool = True
|
|
22
|
+
allowed_domains: List[str] = field(default_factory=lambda: ["github.com", "pypi.org"])
|
|
23
|
+
secret_scanner: str = "env-integrity-sentry"
|
|
24
|
+
block_deprecated_branding: bool = True
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
class AgentSpec:
|
|
28
|
+
name: str
|
|
29
|
+
role: str
|
|
30
|
+
capabilities: List[str]
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class AgentSwarmConfig:
|
|
34
|
+
orchestrator_model: str = "gemini-2.5-flash"
|
|
35
|
+
temperature: float = 0.1
|
|
36
|
+
max_tokens: int = 8192
|
|
37
|
+
agents: List[AgentSpec] = field(default_factory=list)
|
|
38
|
+
|
|
39
|
+
@dataclass
|
|
40
|
+
class XORASConfig:
|
|
41
|
+
version: str
|
|
42
|
+
organization: str
|
|
43
|
+
runtime: RuntimeConfig
|
|
44
|
+
security: SecurityConfig
|
|
45
|
+
swarm: AgentSwarmConfig
|
|
46
|
+
workspace_root: str
|
|
47
|
+
log_output: str
|
|
48
|
+
artifact_store: str
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def load_from_yaml(cls, filepath: str = "xoras.env.yaml") -> "XORASConfig":
|
|
52
|
+
if not os.path.exists(filepath):
|
|
53
|
+
raise FileNotFoundError(f"XORAS environment configuration not found at '{filepath}'")
|
|
54
|
+
|
|
55
|
+
with open(filepath, "r", encoding="utf-8") as f:
|
|
56
|
+
raw = yaml.safe_load(f)
|
|
57
|
+
|
|
58
|
+
rt_data = raw.get("runtime", {})
|
|
59
|
+
runtime_cfg = RuntimeConfig(
|
|
60
|
+
environment_type=rt_data.get("environment_type", "agentic-sandbox"),
|
|
61
|
+
concurrency_limit=rt_data.get("concurrency_limit", 8),
|
|
62
|
+
default_timeout_seconds=rt_data.get("default_timeout_seconds", 120),
|
|
63
|
+
memory_limit_mb=rt_data.get("memory_limit_mb", 4096)
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
sec_data = raw.get("security", {})
|
|
67
|
+
security_cfg = SecurityConfig(
|
|
68
|
+
ast_verification=sec_data.get("ast_verification", True),
|
|
69
|
+
allow_network_egress=sec_data.get("allow_network_egress", True),
|
|
70
|
+
allowed_domains=sec_data.get("allowed_domains", ["github.com", "pypi.org"]),
|
|
71
|
+
secret_scanner=sec_data.get("secret_scanner", "env-integrity-sentry"),
|
|
72
|
+
block_deprecated_branding=sec_data.get("block_deprecated_branding", True)
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
swarm_raw = raw.get("agent_swarm", {})
|
|
76
|
+
orch_raw = swarm_raw.get("orchestrator", {})
|
|
77
|
+
agent_specs = []
|
|
78
|
+
for a in swarm_raw.get("agents", []):
|
|
79
|
+
agent_specs.append(AgentSpec(
|
|
80
|
+
name=a.get("name", "Agent"),
|
|
81
|
+
role=a.get("role", "Worker"),
|
|
82
|
+
capabilities=a.get("capabilities", [])
|
|
83
|
+
))
|
|
84
|
+
|
|
85
|
+
swarm_cfg = AgentSwarmConfig(
|
|
86
|
+
orchestrator_model=orch_raw.get("model", "gemini-2.5-flash"),
|
|
87
|
+
temperature=orch_raw.get("temperature", 0.1),
|
|
88
|
+
max_tokens=orch_raw.get("max_tokens", 8192),
|
|
89
|
+
agents=agent_specs
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
paths = raw.get("paths", {})
|
|
93
|
+
return cls(
|
|
94
|
+
version=raw.get("version", "2.0.0"),
|
|
95
|
+
organization=raw.get("organization", "XORAS Systems LLC"),
|
|
96
|
+
runtime=runtime_cfg,
|
|
97
|
+
security=security_cfg,
|
|
98
|
+
swarm=swarm_cfg,
|
|
99
|
+
workspace_root=paths.get("workspace_root", "."),
|
|
100
|
+
log_output=paths.get("log_output", "./logs/xoras_agent_traces.jsonl"),
|
|
101
|
+
artifact_store=paths.get("artifact_store", "./artifacts")
|
|
102
|
+
)
|