agent_os_kernel 3.1.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.
Files changed (337) hide show
  1. agent_control_plane/__init__.py +662 -0
  2. agent_control_plane/a2a_adapter.py +543 -0
  3. agent_control_plane/adapter.py +417 -0
  4. agent_control_plane/agent_hibernation.py +394 -0
  5. agent_control_plane/agent_kernel.py +470 -0
  6. agent_control_plane/compliance.py +720 -0
  7. agent_control_plane/constraint_graphs.py +478 -0
  8. agent_control_plane/control_plane.py +854 -0
  9. agent_control_plane/example_executors.py +195 -0
  10. agent_control_plane/execution_engine.py +231 -0
  11. agent_control_plane/flight_recorder.py +846 -0
  12. agent_control_plane/governance_layer.py +435 -0
  13. agent_control_plane/hf_utils.py +563 -0
  14. agent_control_plane/interfaces/__init__.py +55 -0
  15. agent_control_plane/interfaces/kernel_interface.py +361 -0
  16. agent_control_plane/interfaces/plugin_interface.py +497 -0
  17. agent_control_plane/interfaces/protocol_interfaces.py +387 -0
  18. agent_control_plane/kernel_space.py +1009 -0
  19. agent_control_plane/langchain_adapter.py +424 -0
  20. agent_control_plane/lifecycle.py +3113 -0
  21. agent_control_plane/mcp_adapter.py +653 -0
  22. agent_control_plane/ml_safety.py +563 -0
  23. agent_control_plane/multimodal.py +727 -0
  24. agent_control_plane/mute_agent.py +422 -0
  25. agent_control_plane/observability.py +787 -0
  26. agent_control_plane/orchestrator.py +482 -0
  27. agent_control_plane/plugin_registry.py +750 -0
  28. agent_control_plane/policy_engine.py +954 -0
  29. agent_control_plane/process_isolation.py +777 -0
  30. agent_control_plane/shadow_mode.py +310 -0
  31. agent_control_plane/signals.py +493 -0
  32. agent_control_plane/supervisor_agents.py +430 -0
  33. agent_control_plane/time_travel_debugger.py +557 -0
  34. agent_control_plane/tool_registry.py +452 -0
  35. agent_control_plane/vfs.py +697 -0
  36. agent_kernel/__init__.py +69 -0
  37. agent_kernel/analyzer.py +435 -0
  38. agent_kernel/auditor.py +36 -0
  39. agent_kernel/completeness_auditor.py +237 -0
  40. agent_kernel/detector.py +203 -0
  41. agent_kernel/kernel.py +744 -0
  42. agent_kernel/memory_manager.py +85 -0
  43. agent_kernel/models.py +374 -0
  44. agent_kernel/nudge_mechanism.py +263 -0
  45. agent_kernel/outcome_analyzer.py +338 -0
  46. agent_kernel/patcher.py +582 -0
  47. agent_kernel/semantic_analyzer.py +316 -0
  48. agent_kernel/semantic_purge.py +349 -0
  49. agent_kernel/simulator.py +449 -0
  50. agent_kernel/teacher.py +85 -0
  51. agent_kernel/triage.py +152 -0
  52. agent_os/__init__.py +409 -0
  53. agent_os/_adversarial_impl.py +200 -0
  54. agent_os/_circuit_breaker_impl.py +232 -0
  55. agent_os/_mcp_metrics.py +193 -0
  56. agent_os/adversarial.py +20 -0
  57. agent_os/agents_compat.py +490 -0
  58. agent_os/audit_logger.py +135 -0
  59. agent_os/base_agent.py +651 -0
  60. agent_os/circuit_breaker.py +34 -0
  61. agent_os/cli/__init__.py +659 -0
  62. agent_os/cli/cmd_audit.py +128 -0
  63. agent_os/cli/cmd_init.py +152 -0
  64. agent_os/cli/cmd_policy.py +41 -0
  65. agent_os/cli/cmd_policy_gen.py +180 -0
  66. agent_os/cli/cmd_validate.py +258 -0
  67. agent_os/cli/mcp_scan.py +265 -0
  68. agent_os/cli/output.py +192 -0
  69. agent_os/cli/policy_checker.py +330 -0
  70. agent_os/compat.py +74 -0
  71. agent_os/constraint_graph.py +234 -0
  72. agent_os/content_governance.py +140 -0
  73. agent_os/context_budget.py +305 -0
  74. agent_os/credential_redactor.py +224 -0
  75. agent_os/diff_policy.py +89 -0
  76. agent_os/egress_policy.py +159 -0
  77. agent_os/escalation.py +276 -0
  78. agent_os/event_bus.py +124 -0
  79. agent_os/exceptions.py +180 -0
  80. agent_os/execution_context_policy.py +141 -0
  81. agent_os/github_enterprise.py +96 -0
  82. agent_os/health.py +20 -0
  83. agent_os/integrations/__init__.py +279 -0
  84. agent_os/integrations/a2a_adapter.py +279 -0
  85. agent_os/integrations/agent_lightning/__init__.py +30 -0
  86. agent_os/integrations/anthropic_adapter.py +420 -0
  87. agent_os/integrations/autogen_adapter.py +620 -0
  88. agent_os/integrations/base.py +1137 -0
  89. agent_os/integrations/compat.py +229 -0
  90. agent_os/integrations/config.py +98 -0
  91. agent_os/integrations/conversation_guardian.py +957 -0
  92. agent_os/integrations/crewai_adapter.py +467 -0
  93. agent_os/integrations/drift_detector.py +425 -0
  94. agent_os/integrations/dry_run.py +124 -0
  95. agent_os/integrations/escalation.py +582 -0
  96. agent_os/integrations/gemini_adapter.py +364 -0
  97. agent_os/integrations/google_adk_adapter.py +633 -0
  98. agent_os/integrations/guardrails_adapter.py +394 -0
  99. agent_os/integrations/health.py +197 -0
  100. agent_os/integrations/langchain_adapter.py +654 -0
  101. agent_os/integrations/llamafirewall.py +343 -0
  102. agent_os/integrations/llamaindex_adapter.py +188 -0
  103. agent_os/integrations/logging.py +191 -0
  104. agent_os/integrations/maf_adapter.py +631 -0
  105. agent_os/integrations/mistral_adapter.py +365 -0
  106. agent_os/integrations/openai_adapter.py +816 -0
  107. agent_os/integrations/openai_agents_sdk.py +406 -0
  108. agent_os/integrations/policy_compose.py +171 -0
  109. agent_os/integrations/profiling.py +144 -0
  110. agent_os/integrations/pydantic_ai_adapter.py +420 -0
  111. agent_os/integrations/rate_limiter.py +130 -0
  112. agent_os/integrations/rbac.py +143 -0
  113. agent_os/integrations/registry.py +113 -0
  114. agent_os/integrations/scope_guard.py +303 -0
  115. agent_os/integrations/semantic_kernel_adapter.py +769 -0
  116. agent_os/integrations/smolagents_adapter.py +629 -0
  117. agent_os/integrations/templates.py +178 -0
  118. agent_os/integrations/token_budget.py +134 -0
  119. agent_os/integrations/tool_aliases.py +190 -0
  120. agent_os/integrations/webhooks.py +177 -0
  121. agent_os/lite.py +208 -0
  122. agent_os/mcp_gateway.py +385 -0
  123. agent_os/mcp_message_signer.py +273 -0
  124. agent_os/mcp_protocols.py +161 -0
  125. agent_os/mcp_response_scanner.py +232 -0
  126. agent_os/mcp_security.py +924 -0
  127. agent_os/mcp_session_auth.py +231 -0
  128. agent_os/mcp_sliding_rate_limiter.py +184 -0
  129. agent_os/memory_guard.py +409 -0
  130. agent_os/metrics.py +134 -0
  131. agent_os/mute.py +428 -0
  132. agent_os/mute_agent.py +209 -0
  133. agent_os/policies/__init__.py +77 -0
  134. agent_os/policies/async_evaluator.py +275 -0
  135. agent_os/policies/backends.py +670 -0
  136. agent_os/policies/bridge.py +169 -0
  137. agent_os/policies/budget.py +85 -0
  138. agent_os/policies/cli.py +294 -0
  139. agent_os/policies/conflict_resolution.py +270 -0
  140. agent_os/policies/data_classification.py +252 -0
  141. agent_os/policies/evaluator.py +239 -0
  142. agent_os/policies/policy_schema.json +228 -0
  143. agent_os/policies/rate_limiting.py +145 -0
  144. agent_os/policies/schema.py +115 -0
  145. agent_os/policies/shared.py +331 -0
  146. agent_os/prompt_injection.py +694 -0
  147. agent_os/providers.py +182 -0
  148. agent_os/py.typed +0 -0
  149. agent_os/retry.py +81 -0
  150. agent_os/reversibility.py +251 -0
  151. agent_os/sandbox.py +432 -0
  152. agent_os/sandbox_provider.py +140 -0
  153. agent_os/secure_codegen.py +525 -0
  154. agent_os/security_skills.py +538 -0
  155. agent_os/semantic_policy.py +422 -0
  156. agent_os/server/__init__.py +15 -0
  157. agent_os/server/__main__.py +25 -0
  158. agent_os/server/app.py +277 -0
  159. agent_os/server/models.py +104 -0
  160. agent_os/shift_left_metrics.py +130 -0
  161. agent_os/stateless.py +742 -0
  162. agent_os/supervisor.py +148 -0
  163. agent_os/task_outcome.py +148 -0
  164. agent_os/transparency.py +181 -0
  165. agent_os/trust_root.py +128 -0
  166. agent_os_kernel-3.1.0.dist-info/METADATA +1269 -0
  167. agent_os_kernel-3.1.0.dist-info/RECORD +337 -0
  168. agent_os_kernel-3.1.0.dist-info/WHEEL +4 -0
  169. agent_os_kernel-3.1.0.dist-info/entry_points.txt +2 -0
  170. agent_os_kernel-3.1.0.dist-info/licenses/LICENSE +21 -0
  171. agent_os_observability/__init__.py +27 -0
  172. agent_os_observability/dashboards.py +898 -0
  173. agent_os_observability/metrics.py +398 -0
  174. agent_os_observability/server.py +223 -0
  175. agent_os_observability/tracer.py +232 -0
  176. agent_primitives/__init__.py +24 -0
  177. agent_primitives/failures.py +84 -0
  178. agent_primitives/py.typed +0 -0
  179. amb_core/__init__.py +177 -0
  180. amb_core/adapters/__init__.py +57 -0
  181. amb_core/adapters/aws_sqs_broker.py +376 -0
  182. amb_core/adapters/azure_servicebus_broker.py +340 -0
  183. amb_core/adapters/kafka_broker.py +260 -0
  184. amb_core/adapters/nats_broker.py +285 -0
  185. amb_core/adapters/rabbitmq_broker.py +235 -0
  186. amb_core/adapters/redis_broker.py +262 -0
  187. amb_core/broker.py +145 -0
  188. amb_core/bus.py +481 -0
  189. amb_core/cloudevents.py +509 -0
  190. amb_core/dlq.py +345 -0
  191. amb_core/hf_utils.py +536 -0
  192. amb_core/memory_broker.py +410 -0
  193. amb_core/models.py +141 -0
  194. amb_core/persistence.py +529 -0
  195. amb_core/schema.py +294 -0
  196. amb_core/tracing.py +358 -0
  197. atr/__init__.py +640 -0
  198. atr/access.py +348 -0
  199. atr/composition.py +645 -0
  200. atr/decorator.py +357 -0
  201. atr/executor.py +384 -0
  202. atr/health.py +557 -0
  203. atr/hf_utils.py +449 -0
  204. atr/injection.py +422 -0
  205. atr/metrics.py +440 -0
  206. atr/policies.py +403 -0
  207. atr/py.typed +2 -0
  208. atr/registry.py +452 -0
  209. atr/schema.py +480 -0
  210. atr/tools/safe/__init__.py +75 -0
  211. atr/tools/safe/calculator.py +467 -0
  212. atr/tools/safe/datetime_tool.py +443 -0
  213. atr/tools/safe/file_reader.py +402 -0
  214. atr/tools/safe/http_client.py +316 -0
  215. atr/tools/safe/json_parser.py +374 -0
  216. atr/tools/safe/text_tool.py +537 -0
  217. atr/tools/safe/toolkit.py +175 -0
  218. caas/__init__.py +162 -0
  219. caas/api/__init__.py +7 -0
  220. caas/api/server.py +1328 -0
  221. caas/caching.py +834 -0
  222. caas/cli.py +210 -0
  223. caas/conversation.py +223 -0
  224. caas/decay.py +72 -0
  225. caas/detection/__init__.py +9 -0
  226. caas/detection/detector.py +238 -0
  227. caas/enrichment.py +130 -0
  228. caas/gateway/__init__.py +27 -0
  229. caas/gateway/trust_gateway.py +474 -0
  230. caas/hf_utils.py +479 -0
  231. caas/ingestion/__init__.py +23 -0
  232. caas/ingestion/processors.py +253 -0
  233. caas/ingestion/structure_parser.py +188 -0
  234. caas/models.py +356 -0
  235. caas/pragmatic_truth.py +444 -0
  236. caas/routing/__init__.py +10 -0
  237. caas/routing/heuristic_router.py +58 -0
  238. caas/storage/__init__.py +9 -0
  239. caas/storage/store.py +389 -0
  240. caas/triad.py +213 -0
  241. caas/tuning/__init__.py +9 -0
  242. caas/tuning/tuner.py +329 -0
  243. caas/vfs/__init__.py +14 -0
  244. caas/vfs/filesystem.py +452 -0
  245. cmvk/__init__.py +218 -0
  246. cmvk/audit.py +402 -0
  247. cmvk/benchmarks.py +478 -0
  248. cmvk/constitutional.py +904 -0
  249. cmvk/hf_utils.py +301 -0
  250. cmvk/metrics.py +473 -0
  251. cmvk/profiles.py +300 -0
  252. cmvk/py.typed +0 -0
  253. cmvk/types.py +12 -0
  254. cmvk/verification.py +956 -0
  255. emk/__init__.py +89 -0
  256. emk/causal.py +352 -0
  257. emk/hf_utils.py +421 -0
  258. emk/indexer.py +83 -0
  259. emk/py.typed +0 -0
  260. emk/schema.py +204 -0
  261. emk/sleep_cycle.py +347 -0
  262. emk/store.py +281 -0
  263. iatp/__init__.py +166 -0
  264. iatp/attestation.py +461 -0
  265. iatp/cli.py +317 -0
  266. iatp/hf_utils.py +472 -0
  267. iatp/ipc_pipes.py +580 -0
  268. iatp/main.py +412 -0
  269. iatp/models/__init__.py +447 -0
  270. iatp/policy_engine.py +337 -0
  271. iatp/py.typed +2 -0
  272. iatp/recovery.py +321 -0
  273. iatp/security/__init__.py +270 -0
  274. iatp/sidecar/__init__.py +519 -0
  275. iatp/telemetry/__init__.py +164 -0
  276. iatp/tests/__init__.py +1 -0
  277. iatp/tests/test_attestation.py +370 -0
  278. iatp/tests/test_cli.py +131 -0
  279. iatp/tests/test_ed25519_attestation.py +211 -0
  280. iatp/tests/test_models.py +130 -0
  281. iatp/tests/test_policy_engine.py +347 -0
  282. iatp/tests/test_recovery.py +281 -0
  283. iatp/tests/test_security.py +222 -0
  284. iatp/tests/test_sidecar.py +167 -0
  285. iatp/tests/test_telemetry.py +175 -0
  286. mcp_kernel_server/__init__.py +28 -0
  287. mcp_kernel_server/cli.py +274 -0
  288. mcp_kernel_server/resources.py +217 -0
  289. mcp_kernel_server/server.py +564 -0
  290. mcp_kernel_server/tools.py +1174 -0
  291. mute_agent/__init__.py +68 -0
  292. mute_agent/core/__init__.py +1 -0
  293. mute_agent/core/execution_agent.py +166 -0
  294. mute_agent/core/handshake_protocol.py +201 -0
  295. mute_agent/core/reasoning_agent.py +238 -0
  296. mute_agent/knowledge_graph/__init__.py +1 -0
  297. mute_agent/knowledge_graph/graph_elements.py +65 -0
  298. mute_agent/knowledge_graph/multidimensional_graph.py +170 -0
  299. mute_agent/knowledge_graph/subgraph.py +224 -0
  300. mute_agent/listener/__init__.py +43 -0
  301. mute_agent/listener/adapters/__init__.py +31 -0
  302. mute_agent/listener/adapters/base_adapter.py +189 -0
  303. mute_agent/listener/adapters/caas_adapter.py +344 -0
  304. mute_agent/listener/adapters/control_plane_adapter.py +436 -0
  305. mute_agent/listener/adapters/iatp_adapter.py +332 -0
  306. mute_agent/listener/adapters/scak_adapter.py +251 -0
  307. mute_agent/listener/listener.py +610 -0
  308. mute_agent/listener/state_observer.py +436 -0
  309. mute_agent/listener/threshold_config.py +313 -0
  310. mute_agent/super_system/__init__.py +1 -0
  311. mute_agent/super_system/router.py +204 -0
  312. mute_agent/visualization/__init__.py +10 -0
  313. mute_agent/visualization/graph_debugger.py +502 -0
  314. nexus/README.md +60 -0
  315. nexus/__init__.py +51 -0
  316. nexus/arbiter.py +359 -0
  317. nexus/client.py +466 -0
  318. nexus/dmz.py +444 -0
  319. nexus/escrow.py +430 -0
  320. nexus/exceptions.py +286 -0
  321. nexus/pyproject.toml +36 -0
  322. nexus/registry.py +393 -0
  323. nexus/reputation.py +425 -0
  324. nexus/schemas/__init__.py +51 -0
  325. nexus/schemas/compliance.py +276 -0
  326. nexus/schemas/escrow.py +251 -0
  327. nexus/schemas/manifest.py +225 -0
  328. nexus/schemas/receipt.py +208 -0
  329. nexus/tests/__init__.py +0 -0
  330. nexus/tests/conftest.py +146 -0
  331. nexus/tests/test_arbiter.py +192 -0
  332. nexus/tests/test_dmz.py +194 -0
  333. nexus/tests/test_escrow.py +276 -0
  334. nexus/tests/test_exceptions.py +225 -0
  335. nexus/tests/test_registry.py +232 -0
  336. nexus/tests/test_reputation.py +328 -0
  337. nexus/tests/test_schemas.py +295 -0
atr/access.py ADDED
@@ -0,0 +1,348 @@
1
+ # Copyright (c) Microsoft Corporation.
2
+ # Licensed under the MIT License.
3
+ """
4
+ Access control for ATR tools.
5
+
6
+ Provides permission-based access control for tool execution.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import threading
12
+ from dataclasses import dataclass, field
13
+ from enum import Enum
14
+ from typing import Any, Callable, Dict, FrozenSet, List, Optional, Set
15
+
16
+
17
+ class Permission(str, Enum):
18
+ """Built-in permission types."""
19
+
20
+ READ = "read"
21
+ WRITE = "write"
22
+ EXECUTE = "execute"
23
+ ADMIN = "admin"
24
+ ALL = "*"
25
+
26
+
27
+ @dataclass(frozen=True)
28
+ class Principal:
29
+ """Represents an entity (user, agent, service) that can access tools.
30
+
31
+ Attributes:
32
+ id: Unique identifier for the principal.
33
+ type: Type of principal (e.g., "agent", "user", "service").
34
+ roles: Set of roles assigned to this principal.
35
+ attributes: Additional attributes for attribute-based access control.
36
+ """
37
+
38
+ id: str
39
+ type: str = "agent"
40
+ roles: FrozenSet[str] = field(default_factory=frozenset)
41
+ attributes: FrozenSet[tuple] = field(default_factory=frozenset)
42
+
43
+ def has_role(self, role: str) -> bool:
44
+ """Check if principal has a specific role."""
45
+ return role in self.roles or "admin" in self.roles
46
+
47
+ def get_attribute(self, key: str) -> Optional[Any]:
48
+ """Get an attribute value."""
49
+ for k, v in self.attributes:
50
+ if k == key:
51
+ return v
52
+ return None
53
+
54
+ @classmethod
55
+ def create(
56
+ cls,
57
+ id: str,
58
+ type: str = "agent",
59
+ roles: Optional[List[str]] = None,
60
+ attributes: Optional[Dict[str, Any]] = None,
61
+ ) -> "Principal":
62
+ """Create a principal with mutable inputs."""
63
+ return cls(
64
+ id=id,
65
+ type=type,
66
+ roles=frozenset(roles or []),
67
+ attributes=frozenset((attributes or {}).items()),
68
+ )
69
+
70
+
71
+ @dataclass
72
+ class AccessPolicy:
73
+ """Defines access requirements for a tool.
74
+
75
+ Attributes:
76
+ allowed_principals: Specific principal IDs that can access.
77
+ allowed_roles: Roles that can access.
78
+ allowed_types: Principal types that can access.
79
+ denied_principals: Principals explicitly denied.
80
+ required_attributes: Attributes that must match.
81
+ custom_check: Custom authorization function.
82
+ """
83
+
84
+ allowed_principals: Set[str] = field(default_factory=set)
85
+ allowed_roles: Set[str] = field(default_factory=set)
86
+ allowed_types: Set[str] = field(default_factory=set)
87
+ denied_principals: Set[str] = field(default_factory=set)
88
+ required_attributes: Dict[str, Any] = field(default_factory=dict)
89
+ custom_check: Optional[Callable[[Principal, str], bool]] = None
90
+
91
+ def allows(self, principal: Principal, tool_name: str) -> bool:
92
+ """Check if the policy allows access.
93
+
94
+ Args:
95
+ principal: The principal requesting access.
96
+ tool_name: Name of the tool being accessed.
97
+
98
+ Returns:
99
+ True if access is allowed, False otherwise.
100
+ """
101
+ # Explicit deny takes precedence
102
+ if principal.id in self.denied_principals:
103
+ return False
104
+
105
+ # Check custom authorization
106
+ if self.custom_check is not None:
107
+ return self.custom_check(principal, tool_name)
108
+
109
+ # Admin role bypasses all checks
110
+ if principal.has_role("admin"):
111
+ return True
112
+
113
+ # Check explicit principal allowlist
114
+ if self.allowed_principals and principal.id in self.allowed_principals:
115
+ return True
116
+
117
+ # Check role-based access
118
+ if self.allowed_roles and any(principal.has_role(role) for role in self.allowed_roles):
119
+ return True
120
+
121
+ # Check type-based access
122
+ if self.allowed_types and principal.type in self.allowed_types:
123
+ return True
124
+
125
+ # Check required attributes
126
+ if self.required_attributes:
127
+ for key, required_value in self.required_attributes.items():
128
+ actual_value = principal.get_attribute(key)
129
+ if actual_value != required_value:
130
+ return False
131
+ return True
132
+
133
+ # If no restrictions defined, allow by default
134
+ if (
135
+ not self.allowed_principals
136
+ and not self.allowed_roles
137
+ and not self.allowed_types
138
+ and not self.required_attributes
139
+ ):
140
+ return True
141
+
142
+ return False
143
+
144
+ @classmethod
145
+ def allow_all(cls) -> "AccessPolicy":
146
+ """Create a policy that allows all access."""
147
+ return cls()
148
+
149
+ @classmethod
150
+ def deny_all(cls) -> "AccessPolicy":
151
+ """Create a policy that denies all access."""
152
+ return cls(custom_check=lambda _p, _t: False)
153
+
154
+ @classmethod
155
+ def roles_only(cls, *roles: str) -> "AccessPolicy":
156
+ """Create a policy that only allows specific roles."""
157
+ return cls(allowed_roles=set(roles))
158
+
159
+ @classmethod
160
+ def principals_only(cls, *principals: str) -> "AccessPolicy":
161
+ """Create a policy that only allows specific principals."""
162
+ return cls(allowed_principals=set(principals))
163
+
164
+
165
+ class AccessDeniedError(Exception):
166
+ """Raised when access to a tool is denied."""
167
+
168
+ def __init__(self, principal: Principal, tool_name: str, reason: str = ""):
169
+ self.principal = principal
170
+ self.tool_name = tool_name
171
+ self.reason = reason
172
+ message = f"Access denied for '{principal.id}' to tool '{tool_name}'"
173
+ if reason:
174
+ message += f": {reason}"
175
+ super().__init__(message)
176
+
177
+
178
+ class AccessControlManager:
179
+ """Manages access control for tools.
180
+
181
+ Example:
182
+ >>> manager = AccessControlManager()
183
+ >>>
184
+ >>> # Set policy for a tool
185
+ >>> manager.set_policy("sensitive_tool", AccessPolicy.roles_only("admin", "security"))
186
+ >>>
187
+ >>> # Check access
188
+ >>> agent = Principal.create("agent-1", roles=["claims"])
189
+ >>> if manager.can_access(agent, "sensitive_tool"):
190
+ ... # Execute tool
191
+ ... pass
192
+ """
193
+
194
+ def __init__(self, default_policy: Optional[AccessPolicy] = None):
195
+ """Initialize access control manager.
196
+
197
+ Args:
198
+ default_policy: Policy to use when no specific policy is set.
199
+ """
200
+ self._policies: Dict[str, AccessPolicy] = {}
201
+ self._default_policy = default_policy or AccessPolicy.allow_all()
202
+ self._lock = threading.RLock()
203
+ self._audit_log: List[Dict[str, Any]] = []
204
+ self._audit_enabled = False
205
+
206
+ def set_policy(self, tool_name: str, policy: AccessPolicy) -> None:
207
+ """Set access policy for a tool.
208
+
209
+ Args:
210
+ tool_name: Name of the tool.
211
+ policy: The access policy to apply.
212
+ """
213
+ with self._lock:
214
+ self._policies[tool_name] = policy
215
+
216
+ def get_policy(self, tool_name: str) -> AccessPolicy:
217
+ """Get access policy for a tool.
218
+
219
+ Args:
220
+ tool_name: Name of the tool.
221
+
222
+ Returns:
223
+ The tool's policy or default policy.
224
+ """
225
+ with self._lock:
226
+ return self._policies.get(tool_name, self._default_policy)
227
+
228
+ def remove_policy(self, tool_name: str) -> bool:
229
+ """Remove a tool's specific policy.
230
+
231
+ Args:
232
+ tool_name: Name of the tool.
233
+
234
+ Returns:
235
+ True if policy was removed, False if didn't exist.
236
+ """
237
+ with self._lock:
238
+ if tool_name in self._policies:
239
+ del self._policies[tool_name]
240
+ return True
241
+ return False
242
+
243
+ def can_access(self, principal: Principal, tool_name: str) -> bool:
244
+ """Check if a principal can access a tool.
245
+
246
+ Args:
247
+ principal: The principal requesting access.
248
+ tool_name: Name of the tool.
249
+
250
+ Returns:
251
+ True if access is allowed.
252
+ """
253
+ policy = self.get_policy(tool_name)
254
+ allowed = policy.allows(principal, tool_name)
255
+
256
+ if self._audit_enabled:
257
+ self._log_access(principal, tool_name, allowed)
258
+
259
+ return allowed
260
+
261
+ def require_access(self, principal: Principal, tool_name: str) -> None:
262
+ """Require access or raise AccessDeniedError.
263
+
264
+ Args:
265
+ principal: The principal requesting access.
266
+ tool_name: Name of the tool.
267
+
268
+ Raises:
269
+ AccessDeniedError: If access is denied.
270
+ """
271
+ if not self.can_access(principal, tool_name):
272
+ raise AccessDeniedError(principal, tool_name)
273
+
274
+ def enable_audit(self, enabled: bool = True) -> None:
275
+ """Enable or disable audit logging.
276
+
277
+ Args:
278
+ enabled: Whether to enable audit logging.
279
+ """
280
+ self._audit_enabled = enabled
281
+
282
+ def get_audit_log(self) -> List[Dict[str, Any]]:
283
+ """Get the audit log.
284
+
285
+ Returns:
286
+ List of audit log entries.
287
+ """
288
+ with self._lock:
289
+ return list(self._audit_log)
290
+
291
+ def clear_audit_log(self) -> None:
292
+ """Clear the audit log."""
293
+ with self._lock:
294
+ self._audit_log.clear()
295
+
296
+ def _log_access(self, principal: Principal, tool_name: str, allowed: bool) -> None:
297
+ """Log an access attempt."""
298
+ from datetime import datetime
299
+
300
+ with self._lock:
301
+ self._audit_log.append(
302
+ {
303
+ "timestamp": datetime.now().isoformat(),
304
+ "principal_id": principal.id,
305
+ "principal_type": principal.type,
306
+ "tool_name": tool_name,
307
+ "allowed": allowed,
308
+ }
309
+ )
310
+
311
+ # Keep only last 10000 entries
312
+ if len(self._audit_log) > 10000:
313
+ self._audit_log = self._audit_log[-10000:]
314
+
315
+ def list_accessible_tools(self, principal: Principal, tool_names: List[str]) -> List[str]:
316
+ """Get list of tools a principal can access.
317
+
318
+ Args:
319
+ principal: The principal to check.
320
+ tool_names: List of tool names to check.
321
+
322
+ Returns:
323
+ List of accessible tool names.
324
+ """
325
+ return [name for name in tool_names if self.can_access(principal, name)]
326
+
327
+
328
+ # Global access control manager
329
+ _global_access_manager: AccessControlManager = AccessControlManager()
330
+
331
+
332
+ def get_access_manager() -> AccessControlManager:
333
+ """Get the global access control manager.
334
+
335
+ Returns:
336
+ The global AccessControlManager instance.
337
+ """
338
+ return _global_access_manager
339
+
340
+
341
+ def set_access_manager(manager: AccessControlManager) -> None:
342
+ """Set the global access control manager.
343
+
344
+ Args:
345
+ manager: The manager to use globally.
346
+ """
347
+ global _global_access_manager
348
+ _global_access_manager = manager