zexus 1.6.2
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.
- package/LICENSE +0 -0
- package/README.md +2513 -0
- package/bin/zexus +2 -0
- package/bin/zpics +2 -0
- package/bin/zpm +2 -0
- package/bin/zx +2 -0
- package/bin/zx-deploy +2 -0
- package/bin/zx-dev +2 -0
- package/bin/zx-run +2 -0
- package/package.json +66 -0
- package/scripts/README.md +24 -0
- package/scripts/postinstall.js +44 -0
- package/shared_config.json +24 -0
- package/src/README.md +1525 -0
- package/src/tests/run_zexus_tests.py +117 -0
- package/src/tests/test_all_phases.zx +346 -0
- package/src/tests/test_blockchain_features.zx +306 -0
- package/src/tests/test_complexity_features.zx +321 -0
- package/src/tests/test_core_integration.py +185 -0
- package/src/tests/test_phase10_ecosystem.zx +177 -0
- package/src/tests/test_phase1_modifiers.zx +87 -0
- package/src/tests/test_phase2_plugins.zx +80 -0
- package/src/tests/test_phase3_security.zx +97 -0
- package/src/tests/test_phase4_vfs.zx +116 -0
- package/src/tests/test_phase5_types.zx +117 -0
- package/src/tests/test_phase6_metaprogramming.zx +125 -0
- package/src/tests/test_phase7_optimization.zx +132 -0
- package/src/tests/test_phase9_advanced_types.zx +157 -0
- package/src/tests/test_security_features.py +419 -0
- package/src/tests/test_security_features.zx +276 -0
- package/src/tests/test_simple_zx.zx +1 -0
- package/src/tests/test_verification_simple.zx +69 -0
- package/src/zexus/__init__.py +28 -0
- package/src/zexus/__main__.py +5 -0
- package/src/zexus/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/advanced_types.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/builtin_modules.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/capability_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/complexity_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/concurrency_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/config.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/dependency_injection.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/ecosystem.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/environment.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/error_reporter.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/hybrid_orchestrator.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/lexer.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/metaprogramming.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/module_cache.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/object.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/optimization.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/plugin_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/policy_engine.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/security.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/stdlib_integration.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/strategy_recovery.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/syntax_validator.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/type_system.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/virtual_filesystem.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/zexus_ast.cpython-312.pyc +0 -0
- package/src/zexus/__pycache__/zexus_token.cpython-312.pyc +0 -0
- package/src/zexus/advanced_types.py +401 -0
- package/src/zexus/blockchain/__init__.py +40 -0
- package/src/zexus/blockchain/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/crypto.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/ledger.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/__pycache__/transaction.cpython-312.pyc +0 -0
- package/src/zexus/blockchain/crypto.py +463 -0
- package/src/zexus/blockchain/ledger.py +255 -0
- package/src/zexus/blockchain/transaction.py +267 -0
- package/src/zexus/builtin_modules.py +284 -0
- package/src/zexus/builtin_plugins.py +317 -0
- package/src/zexus/capability_system.py +372 -0
- package/src/zexus/cli/__init__.py +2 -0
- package/src/zexus/cli/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/cli/__pycache__/main.cpython-312.pyc +0 -0
- package/src/zexus/cli/main.py +707 -0
- package/src/zexus/cli/zpm.py +203 -0
- package/src/zexus/compare_interpreter_compiler.py +146 -0
- package/src/zexus/compiler/__init__.py +169 -0
- package/src/zexus/compiler/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/lexer.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/parser.cpython-312.pyc +0 -0
- package/src/zexus/compiler/__pycache__/zexus_ast.cpython-312.pyc +0 -0
- package/src/zexus/compiler/bytecode.py +266 -0
- package/src/zexus/compiler/compat_runtime.py +277 -0
- package/src/zexus/compiler/lexer.py +257 -0
- package/src/zexus/compiler/parser.py +779 -0
- package/src/zexus/compiler/semantic.py +118 -0
- package/src/zexus/compiler/zexus_ast.py +454 -0
- package/src/zexus/complexity_system.py +575 -0
- package/src/zexus/concurrency_system.py +493 -0
- package/src/zexus/config.py +201 -0
- package/src/zexus/crypto_bridge.py +19 -0
- package/src/zexus/dependency_injection.py +423 -0
- package/src/zexus/ecosystem.py +434 -0
- package/src/zexus/environment.py +101 -0
- package/src/zexus/environment_manager.py +119 -0
- package/src/zexus/error_reporter.py +314 -0
- package/src/zexus/evaluator/__init__.py +12 -0
- package/src/zexus/evaluator/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/bytecode_compiler.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/core.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/expressions.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/functions.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/integration.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/statements.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/__pycache__/utils.cpython-312.pyc +0 -0
- package/src/zexus/evaluator/bytecode_compiler.py +700 -0
- package/src/zexus/evaluator/core.py +891 -0
- package/src/zexus/evaluator/expressions.py +827 -0
- package/src/zexus/evaluator/functions.py +3989 -0
- package/src/zexus/evaluator/integration.py +396 -0
- package/src/zexus/evaluator/statements.py +4303 -0
- package/src/zexus/evaluator/utils.py +126 -0
- package/src/zexus/evaluator_original.py +2041 -0
- package/src/zexus/external_bridge.py +16 -0
- package/src/zexus/find_affected_imports.sh +155 -0
- package/src/zexus/hybrid_orchestrator.py +152 -0
- package/src/zexus/input_validation.py +259 -0
- package/src/zexus/lexer.py +571 -0
- package/src/zexus/logging.py +89 -0
- package/src/zexus/lsp/__init__.py +9 -0
- package/src/zexus/lsp/completion_provider.py +207 -0
- package/src/zexus/lsp/definition_provider.py +22 -0
- package/src/zexus/lsp/hover_provider.py +71 -0
- package/src/zexus/lsp/server.py +269 -0
- package/src/zexus/lsp/symbol_provider.py +31 -0
- package/src/zexus/metaprogramming.py +321 -0
- package/src/zexus/module_cache.py +89 -0
- package/src/zexus/module_manager.py +107 -0
- package/src/zexus/object.py +973 -0
- package/src/zexus/optimization.py +424 -0
- package/src/zexus/parser/__init__.py +31 -0
- package/src/zexus/parser/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/parser.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/strategy_context.cpython-312.pyc +0 -0
- package/src/zexus/parser/__pycache__/strategy_structural.cpython-312.pyc +0 -0
- package/src/zexus/parser/integration.py +86 -0
- package/src/zexus/parser/parser.py +3977 -0
- package/src/zexus/parser/strategy_context.py +7254 -0
- package/src/zexus/parser/strategy_structural.py +1033 -0
- package/src/zexus/persistence.py +391 -0
- package/src/zexus/plugin_system.py +290 -0
- package/src/zexus/policy_engine.py +365 -0
- package/src/zexus/profiler/__init__.py +5 -0
- package/src/zexus/profiler/profiler.py +233 -0
- package/src/zexus/purity_system.py +398 -0
- package/src/zexus/runtime/__init__.py +20 -0
- package/src/zexus/runtime/async_runtime.py +324 -0
- package/src/zexus/search_old_imports.sh +65 -0
- package/src/zexus/security.py +1407 -0
- package/src/zexus/stack_trace.py +233 -0
- package/src/zexus/stdlib/__init__.py +27 -0
- package/src/zexus/stdlib/blockchain.py +341 -0
- package/src/zexus/stdlib/compression.py +167 -0
- package/src/zexus/stdlib/crypto.py +124 -0
- package/src/zexus/stdlib/datetime.py +163 -0
- package/src/zexus/stdlib/db_mongo.py +199 -0
- package/src/zexus/stdlib/db_mysql.py +162 -0
- package/src/zexus/stdlib/db_postgres.py +163 -0
- package/src/zexus/stdlib/db_sqlite.py +133 -0
- package/src/zexus/stdlib/encoding.py +230 -0
- package/src/zexus/stdlib/fs.py +195 -0
- package/src/zexus/stdlib/http.py +219 -0
- package/src/zexus/stdlib/http_server.py +248 -0
- package/src/zexus/stdlib/json_module.py +61 -0
- package/src/zexus/stdlib/math.py +360 -0
- package/src/zexus/stdlib/os_module.py +265 -0
- package/src/zexus/stdlib/regex.py +148 -0
- package/src/zexus/stdlib/sockets.py +253 -0
- package/src/zexus/stdlib/test_framework.zx +208 -0
- package/src/zexus/stdlib/test_runner.zx +119 -0
- package/src/zexus/stdlib_integration.py +341 -0
- package/src/zexus/strategy_recovery.py +256 -0
- package/src/zexus/syntax_validator.py +356 -0
- package/src/zexus/testing/zpics.py +407 -0
- package/src/zexus/testing/zpics_runtime.py +369 -0
- package/src/zexus/type_system.py +374 -0
- package/src/zexus/validation_system.py +569 -0
- package/src/zexus/virtual_filesystem.py +355 -0
- package/src/zexus/vm/__init__.py +8 -0
- package/src/zexus/vm/__pycache__/__init__.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/async_optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/bytecode.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/cache.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/jit.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/memory_manager.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/memory_pool.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/parallel_vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/peephole_optimizer.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/profiler.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/register_allocator.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/register_vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/ssa_converter.cpython-312.pyc +0 -0
- package/src/zexus/vm/__pycache__/vm.cpython-312.pyc +0 -0
- package/src/zexus/vm/async_optimizer.py +420 -0
- package/src/zexus/vm/bytecode.py +428 -0
- package/src/zexus/vm/bytecode_converter.py +297 -0
- package/src/zexus/vm/cache.py +532 -0
- package/src/zexus/vm/jit.py +720 -0
- package/src/zexus/vm/memory_manager.py +520 -0
- package/src/zexus/vm/memory_pool.py +511 -0
- package/src/zexus/vm/optimizer.py +478 -0
- package/src/zexus/vm/parallel_vm.py +899 -0
- package/src/zexus/vm/peephole_optimizer.py +452 -0
- package/src/zexus/vm/profiler.py +527 -0
- package/src/zexus/vm/register_allocator.py +462 -0
- package/src/zexus/vm/register_vm.py +520 -0
- package/src/zexus/vm/ssa_converter.py +757 -0
- package/src/zexus/vm/vm.py +1392 -0
- package/src/zexus/zexus_ast.py +1782 -0
- package/src/zexus/zexus_token.py +253 -0
- package/src/zexus/zpm/__init__.py +15 -0
- package/src/zexus/zpm/installer.py +116 -0
- package/src/zexus/zpm/package_manager.py +208 -0
- package/src/zexus/zpm/publisher.py +98 -0
- package/src/zexus/zpm/registry.py +110 -0
- package/src/zexus.egg-info/PKG-INFO +2235 -0
- package/src/zexus.egg-info/SOURCES.txt +876 -0
- package/src/zexus.egg-info/dependency_links.txt +1 -0
- package/src/zexus.egg-info/entry_points.txt +3 -0
- package/src/zexus.egg-info/not-zip-safe +1 -0
- package/src/zexus.egg-info/requires.txt +14 -0
- package/src/zexus.egg-info/top_level.txt +2 -0
- package/zexus.json +14 -0
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Capability-based security system for Zexus.
|
|
3
|
+
|
|
4
|
+
Implements fine-grained access control through capability tokens.
|
|
5
|
+
Plugins declare required capabilities, and the evaluator enforces access.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Set, Dict, List, Callable, Optional, Tuple
|
|
9
|
+
from dataclasses import dataclass, field
|
|
10
|
+
from enum import Enum
|
|
11
|
+
import time
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class CapabilityLevel(Enum):
|
|
15
|
+
"""Capability access levels."""
|
|
16
|
+
DENY = 0
|
|
17
|
+
RESTRICTED = 1
|
|
18
|
+
ALLOWED = 2
|
|
19
|
+
UNRESTRICTED = 3
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass
|
|
23
|
+
class Capability:
|
|
24
|
+
"""A capability token representing an action or resource access."""
|
|
25
|
+
name: str
|
|
26
|
+
level: CapabilityLevel = CapabilityLevel.ALLOWED
|
|
27
|
+
reason: str = "" # Why this capability is granted/denied
|
|
28
|
+
timestamp: float = field(default_factory=time.time)
|
|
29
|
+
source: str = "" # Which plugin/policy granted this
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass
|
|
33
|
+
class CapabilityRequest:
|
|
34
|
+
"""Request for capability access."""
|
|
35
|
+
capability: str
|
|
36
|
+
requester: str # Plugin or code requesting access
|
|
37
|
+
context: Dict = field(default_factory=dict) # Request context
|
|
38
|
+
timestamp: float = field(default_factory=time.time)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class CapabilityPolicy:
|
|
42
|
+
"""Base class for capability policies."""
|
|
43
|
+
|
|
44
|
+
def __init__(self, name: str):
|
|
45
|
+
self.name = name
|
|
46
|
+
self.grants: Dict[str, CapabilityLevel] = {}
|
|
47
|
+
self.denials: Set[str] = set()
|
|
48
|
+
|
|
49
|
+
def grant(self, capability: str, level: CapabilityLevel = CapabilityLevel.ALLOWED):
|
|
50
|
+
"""Grant a capability at specified level."""
|
|
51
|
+
self.grants[capability] = level
|
|
52
|
+
|
|
53
|
+
def deny(self, capability: str):
|
|
54
|
+
"""Deny a capability."""
|
|
55
|
+
self.denials.add(capability)
|
|
56
|
+
if capability in self.grants:
|
|
57
|
+
del self.grants[capability]
|
|
58
|
+
|
|
59
|
+
def check(self, capability: str) -> CapabilityLevel:
|
|
60
|
+
"""Check capability status."""
|
|
61
|
+
if capability in self.denials:
|
|
62
|
+
return CapabilityLevel.DENY
|
|
63
|
+
return self.grants.get(capability, CapabilityLevel.DENY)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class AllowAllPolicy(CapabilityPolicy):
|
|
67
|
+
"""Allow all capabilities (development mode)."""
|
|
68
|
+
|
|
69
|
+
def __init__(self):
|
|
70
|
+
super().__init__("allow_all")
|
|
71
|
+
|
|
72
|
+
def check(self, capability: str) -> CapabilityLevel:
|
|
73
|
+
"""All capabilities allowed."""
|
|
74
|
+
return CapabilityLevel.ALLOWED
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class DenyAllPolicy(CapabilityPolicy):
|
|
78
|
+
"""Deny all capabilities (secure sandbox)."""
|
|
79
|
+
|
|
80
|
+
def __init__(self):
|
|
81
|
+
super().__init__("deny_all")
|
|
82
|
+
|
|
83
|
+
def check(self, capability: str) -> CapabilityLevel:
|
|
84
|
+
"""All capabilities denied."""
|
|
85
|
+
return CapabilityLevel.DENY
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class SelectivePolicy(CapabilityPolicy):
|
|
89
|
+
"""Allow only specific capabilities."""
|
|
90
|
+
|
|
91
|
+
def __init__(self, allowed_capabilities: List[str]):
|
|
92
|
+
super().__init__("selective")
|
|
93
|
+
for cap in allowed_capabilities:
|
|
94
|
+
self.grant(cap, CapabilityLevel.ALLOWED)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class CapabilityAuditLog:
|
|
98
|
+
"""Log capability access for audit purposes."""
|
|
99
|
+
|
|
100
|
+
def __init__(self):
|
|
101
|
+
self.entries: List[Dict] = []
|
|
102
|
+
self.statistics: Dict[str, int] = {}
|
|
103
|
+
|
|
104
|
+
def log_request(self, request: CapabilityRequest, granted: bool, reason: str = ""):
|
|
105
|
+
"""Log a capability request."""
|
|
106
|
+
entry = {
|
|
107
|
+
"timestamp": request.timestamp,
|
|
108
|
+
"capability": request.capability,
|
|
109
|
+
"requester": request.requester,
|
|
110
|
+
"granted": granted,
|
|
111
|
+
"reason": reason,
|
|
112
|
+
"context": request.context
|
|
113
|
+
}
|
|
114
|
+
self.entries.append(entry)
|
|
115
|
+
|
|
116
|
+
# Update statistics
|
|
117
|
+
key = f"{request.capability}:{'granted' if granted else 'denied'}"
|
|
118
|
+
self.statistics[key] = self.statistics.get(key, 0) + 1
|
|
119
|
+
|
|
120
|
+
def get_entries(self, capability: Optional[str] = None, requester: Optional[str] = None) -> List[Dict]:
|
|
121
|
+
"""Get audit log entries, optionally filtered."""
|
|
122
|
+
entries = self.entries
|
|
123
|
+
|
|
124
|
+
if capability:
|
|
125
|
+
entries = [e for e in entries if e["capability"] == capability]
|
|
126
|
+
if requester:
|
|
127
|
+
entries = [e for e in entries if e["requester"] == requester]
|
|
128
|
+
|
|
129
|
+
return entries
|
|
130
|
+
|
|
131
|
+
def get_statistics(self) -> Dict[str, int]:
|
|
132
|
+
"""Get access statistics."""
|
|
133
|
+
return self.statistics.copy()
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
class CapabilityManager:
|
|
137
|
+
"""
|
|
138
|
+
Manages capabilities, policies, and access control.
|
|
139
|
+
|
|
140
|
+
Enforces that code only accesses capabilities it has declared.
|
|
141
|
+
Supports both compile-time declarations and runtime checks.
|
|
142
|
+
"""
|
|
143
|
+
|
|
144
|
+
# Base capabilities always available
|
|
145
|
+
BASE_CAPABILITIES = {
|
|
146
|
+
"core.language", # Core language features
|
|
147
|
+
"core.control", # Control flow
|
|
148
|
+
"core.math", # Math operations
|
|
149
|
+
"core.strings", # String operations
|
|
150
|
+
"core.arrays", # Array operations
|
|
151
|
+
"core.objects", # Object operations
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
# Privileged capabilities
|
|
155
|
+
PRIVILEGED_CAPABILITIES = {
|
|
156
|
+
"io.read", # File reading
|
|
157
|
+
"io.write", # File writing
|
|
158
|
+
"io.delete", # File deletion
|
|
159
|
+
"network.tcp", # TCP connections
|
|
160
|
+
"network.http", # HTTP requests
|
|
161
|
+
"crypto.keygen", # Key generation
|
|
162
|
+
"crypto.sign", # Signing
|
|
163
|
+
"exec.shell", # Shell execution
|
|
164
|
+
"exec.spawn", # Process spawning
|
|
165
|
+
"sys.env", # Environment variables
|
|
166
|
+
"sys.time", # System time
|
|
167
|
+
"sys.exit", # Process exit
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
def __init__(self, default_policy: Optional[CapabilityPolicy] = None):
|
|
171
|
+
"""Initialize capability manager."""
|
|
172
|
+
self.policy = default_policy or AllowAllPolicy()
|
|
173
|
+
self.audit_log = CapabilityAuditLog()
|
|
174
|
+
self.granted_capabilities: Dict[str, Set[str]] = {} # requester -> capabilities
|
|
175
|
+
self.required_capabilities: Dict[str, Set[str]] = {} # requester -> required caps
|
|
176
|
+
|
|
177
|
+
# Initialize with base capabilities
|
|
178
|
+
for cap in self.BASE_CAPABILITIES:
|
|
179
|
+
self.policy.grant(cap, CapabilityLevel.ALLOWED)
|
|
180
|
+
|
|
181
|
+
def set_policy(self, policy: CapabilityPolicy):
|
|
182
|
+
"""Set the capability policy."""
|
|
183
|
+
self.policy = policy
|
|
184
|
+
|
|
185
|
+
def declare_required_capabilities(self, requester: str, capabilities: List[str]):
|
|
186
|
+
"""Declare that a module/plugin requires certain capabilities."""
|
|
187
|
+
self.required_capabilities[requester] = set(capabilities)
|
|
188
|
+
|
|
189
|
+
def grant_capability(self, requester: str, capability: str):
|
|
190
|
+
"""Grant a capability to a requester."""
|
|
191
|
+
if requester not in self.granted_capabilities:
|
|
192
|
+
self.granted_capabilities[requester] = set()
|
|
193
|
+
self.granted_capabilities[requester].add(capability)
|
|
194
|
+
|
|
195
|
+
def grant_capabilities(self, requester: str, capabilities: List[str]):
|
|
196
|
+
"""Grant multiple capabilities to a requester."""
|
|
197
|
+
for cap in capabilities:
|
|
198
|
+
self.grant_capability(requester, cap)
|
|
199
|
+
|
|
200
|
+
def check_capability(self, requester: str, capability: str,
|
|
201
|
+
context: Optional[Dict] = None) -> Tuple[bool, str]:
|
|
202
|
+
"""
|
|
203
|
+
Check if a requester can access a capability.
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
(allowed: bool, reason: str)
|
|
207
|
+
"""
|
|
208
|
+
request = CapabilityRequest(
|
|
209
|
+
capability=capability,
|
|
210
|
+
requester=requester,
|
|
211
|
+
context=context or {}
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
# 1. Check if policy allows all (AllowAllPolicy)
|
|
215
|
+
if isinstance(self.policy, AllowAllPolicy):
|
|
216
|
+
reason = f"Capability {capability} allowed by policy (allow-all)"
|
|
217
|
+
self.audit_log.log_request(request, True, reason)
|
|
218
|
+
return True, reason
|
|
219
|
+
|
|
220
|
+
# 2. Check if capability is base capability (always available)
|
|
221
|
+
if capability in self.BASE_CAPABILITIES:
|
|
222
|
+
reason = f"Base capability {capability} available"
|
|
223
|
+
self.audit_log.log_request(request, True, reason)
|
|
224
|
+
return True, reason
|
|
225
|
+
|
|
226
|
+
# 3. Check if requester has been explicitly granted this capability
|
|
227
|
+
if requester in self.granted_capabilities:
|
|
228
|
+
if capability in self.granted_capabilities[requester]:
|
|
229
|
+
reason = f"Capability {capability} granted to {requester}"
|
|
230
|
+
self.audit_log.log_request(request, True, reason)
|
|
231
|
+
return True, reason
|
|
232
|
+
|
|
233
|
+
# 4. Check if capability is allowed by policy
|
|
234
|
+
policy_level = self.policy.check(capability)
|
|
235
|
+
if policy_level == CapabilityLevel.ALLOWED:
|
|
236
|
+
reason = f"Capability {capability} allowed by policy"
|
|
237
|
+
self.audit_log.log_request(request, True, reason)
|
|
238
|
+
return True, reason
|
|
239
|
+
|
|
240
|
+
# Denied by default
|
|
241
|
+
reason = f"Capability {capability} not granted to {requester}"
|
|
242
|
+
self.audit_log.log_request(request, False, reason)
|
|
243
|
+
return False, reason
|
|
244
|
+
|
|
245
|
+
def require_capability(self, requester: str, capability: str,
|
|
246
|
+
context: Optional[Dict] = None) -> bool:
|
|
247
|
+
"""
|
|
248
|
+
Require a capability. Raises error if not available.
|
|
249
|
+
|
|
250
|
+
This is the hook that evaluator calls.
|
|
251
|
+
"""
|
|
252
|
+
allowed, reason = self.check_capability(requester, capability, context)
|
|
253
|
+
if not allowed:
|
|
254
|
+
raise PermissionError(f"{requester} cannot access {capability}: {reason}")
|
|
255
|
+
return True
|
|
256
|
+
|
|
257
|
+
def has_capability(self, requester: str, capability: str) -> bool:
|
|
258
|
+
"""Check if a requester has a capability (without error)."""
|
|
259
|
+
allowed, _ = self.check_capability(requester, capability)
|
|
260
|
+
return allowed
|
|
261
|
+
|
|
262
|
+
def get_granted_capabilities(self, requester: str) -> List[str]:
|
|
263
|
+
"""Get all capabilities granted to a requester."""
|
|
264
|
+
caps = list(self.BASE_CAPABILITIES)
|
|
265
|
+
if requester in self.granted_capabilities:
|
|
266
|
+
caps.extend(list(self.granted_capabilities[requester]))
|
|
267
|
+
return sorted(list(set(caps)))
|
|
268
|
+
|
|
269
|
+
def get_required_capabilities(self, requester: str) -> List[str]:
|
|
270
|
+
"""Get capabilities required by a requester."""
|
|
271
|
+
return sorted(list(self.required_capabilities.get(requester, set())))
|
|
272
|
+
|
|
273
|
+
def validate_requirements(self, requester: str) -> Tuple[bool, List[str]]:
|
|
274
|
+
"""
|
|
275
|
+
Validate that all required capabilities are granted.
|
|
276
|
+
|
|
277
|
+
Returns:
|
|
278
|
+
(valid: bool, missing_capabilities: [str])
|
|
279
|
+
"""
|
|
280
|
+
required = self.get_required_capabilities(requester)
|
|
281
|
+
granted = set(self.get_granted_capabilities(requester))
|
|
282
|
+
|
|
283
|
+
missing = [cap for cap in required if cap not in granted]
|
|
284
|
+
return len(missing) == 0, missing
|
|
285
|
+
|
|
286
|
+
def get_audit_log(self) -> List[Dict]:
|
|
287
|
+
"""Get audit log entries."""
|
|
288
|
+
return self.audit_log.get_entries()
|
|
289
|
+
|
|
290
|
+
def get_audit_statistics(self) -> Dict[str, int]:
|
|
291
|
+
"""Get audit statistics."""
|
|
292
|
+
return self.audit_log.get_statistics()
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
class CapabilityError(Exception):
|
|
296
|
+
"""Exception raised when capability check fails."""
|
|
297
|
+
pass
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
# Standard capability sets for common scenarios
|
|
301
|
+
|
|
302
|
+
CAPABILITY_SETS = {
|
|
303
|
+
"read_only": {
|
|
304
|
+
"capabilities": [
|
|
305
|
+
"io.read",
|
|
306
|
+
"sys.time"
|
|
307
|
+
],
|
|
308
|
+
"description": "Read-only access to files and time"
|
|
309
|
+
},
|
|
310
|
+
|
|
311
|
+
"io_full": {
|
|
312
|
+
"capabilities": [
|
|
313
|
+
"io.read",
|
|
314
|
+
"io.write",
|
|
315
|
+
"io.delete",
|
|
316
|
+
"sys.time"
|
|
317
|
+
],
|
|
318
|
+
"description": "Full file I/O access"
|
|
319
|
+
},
|
|
320
|
+
|
|
321
|
+
"network": {
|
|
322
|
+
"capabilities": [
|
|
323
|
+
"network.tcp",
|
|
324
|
+
"network.http",
|
|
325
|
+
"sys.time"
|
|
326
|
+
],
|
|
327
|
+
"description": "Network access (TCP and HTTP)"
|
|
328
|
+
},
|
|
329
|
+
|
|
330
|
+
"crypto": {
|
|
331
|
+
"capabilities": [
|
|
332
|
+
"crypto.keygen",
|
|
333
|
+
"crypto.sign",
|
|
334
|
+
"crypto.hash" # Assumed in crypto plugin
|
|
335
|
+
],
|
|
336
|
+
"description": "Cryptographic operations"
|
|
337
|
+
},
|
|
338
|
+
|
|
339
|
+
"untrusted": {
|
|
340
|
+
"capabilities": [],
|
|
341
|
+
"description": "Minimal capabilities for untrusted code"
|
|
342
|
+
},
|
|
343
|
+
|
|
344
|
+
"trusted": {
|
|
345
|
+
"capabilities": [
|
|
346
|
+
"io.read",
|
|
347
|
+
"io.write",
|
|
348
|
+
"network.http",
|
|
349
|
+
"crypto.hash",
|
|
350
|
+
"sys.time"
|
|
351
|
+
],
|
|
352
|
+
"description": "Standard trusted code capabilities"
|
|
353
|
+
},
|
|
354
|
+
|
|
355
|
+
"system": {
|
|
356
|
+
"capabilities": [
|
|
357
|
+
"io.read",
|
|
358
|
+
"io.write",
|
|
359
|
+
"io.delete",
|
|
360
|
+
"network.tcp",
|
|
361
|
+
"network.http",
|
|
362
|
+
"crypto.keygen",
|
|
363
|
+
"crypto.sign",
|
|
364
|
+
"exec.shell",
|
|
365
|
+
"exec.spawn",
|
|
366
|
+
"sys.env",
|
|
367
|
+
"sys.time",
|
|
368
|
+
"sys.exit"
|
|
369
|
+
],
|
|
370
|
+
"description": "Full system access (privileged code)"
|
|
371
|
+
}
|
|
372
|
+
}
|
|
Binary file
|
|
Binary file
|