adminA 0.14.2__tar.gz → 0.15.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.
Files changed (313) hide show
  1. {admina-0.14.2/admina.egg-info → admina-0.15.0}/PKG-INFO +142 -36
  2. {admina-0.14.2 → admina-0.15.0}/README.md +140 -34
  3. {admina-0.14.2 → admina-0.15.0}/admina/__init__.py +1 -1
  4. {admina-0.14.2 → admina-0.15.0}/admina/cli/main.py +28 -25
  5. {admina-0.14.2 → admina-0.15.0}/admina/cli/templates/docker-compose.yml.j2 +9 -0
  6. {admina-0.14.2 → admina-0.15.0}/admina/cli/templates/plugin.py.j2 +21 -0
  7. {admina-0.14.2 → admina-0.15.0}/admina/cli/templates/plugin_readme.md.j2 +5 -3
  8. {admina-0.14.2 → admina-0.15.0}/admina/core/config.py +199 -2
  9. {admina-0.14.2 → admina-0.15.0}/admina/core/config_schema.py +36 -0
  10. admina-0.15.0/admina/core/install_hint.py +32 -0
  11. admina-0.15.0/admina/core/types.py +317 -0
  12. {admina-0.14.2 → admina-0.15.0}/admina/dashboard/static/index.html +75 -8
  13. admina-0.15.0/admina/domains/agent_security/sandbox.py +542 -0
  14. {admina-0.14.2 → admina-0.15.0}/admina/domains/ai_infra/rag.py +6 -4
  15. {admina-0.14.2 → admina-0.15.0}/admina/domains/compliance/eu_ai_act.py +143 -19
  16. {admina-0.14.2 → admina-0.15.0}/admina/engines/__init__.py +2 -2
  17. {admina-0.14.2 → admina-0.15.0}/admina/engines/presidio.py +3 -2
  18. {admina-0.14.2 → admina-0.15.0}/admina/integrations/_engines.py +2 -2
  19. {admina-0.14.2 → admina-0.15.0}/admina/plugins/__init__.py +3 -1
  20. {admina-0.14.2 → admina-0.15.0}/admina/plugins/base.py +107 -2
  21. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/adapters/anthropic.py +3 -2
  22. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/adapters/bedrock.py +3 -2
  23. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/adapters/gemini.py +3 -2
  24. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/adapters/mistral.py +3 -2
  25. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/adapters/ollama.py +3 -2
  26. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/adapters/openai.py +3 -2
  27. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/adapters/vllm.py +2 -1
  28. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/connectors/chromadb.py +3 -2
  29. admina-0.15.0/admina/plugins/builtin/sandboxes/__init__.py +15 -0
  30. admina-0.15.0/admina/plugins/builtin/sandboxes/docker.py +612 -0
  31. {admina-0.14.2 → admina-0.15.0}/admina/plugins/registry.py +5 -2
  32. {admina-0.14.2 → admina-0.15.0}/admina/proxy/api/dashboard.py +36 -5
  33. {admina-0.14.2 → admina-0.15.0}/admina/proxy/env_check.py +1 -0
  34. {admina-0.14.2 → admina-0.15.0}/admina/proxy/forensic_backend.py +4 -1
  35. {admina-0.14.2 → admina-0.15.0}/admina/proxy/main.py +400 -113
  36. {admina-0.14.2 → admina-0.15.0}/admina/proxy/multi_upstream.py +41 -20
  37. admina-0.15.0/admina/proxy/sandbox_bridge.py +274 -0
  38. {admina-0.14.2 → admina-0.15.0}/admina/proxy/state.py +18 -2
  39. {admina-0.14.2 → admina-0.15.0}/admina/sdk/compliance_kit.py +14 -6
  40. admina-0.15.0/admina/sdk/sandbox.py +140 -0
  41. {admina-0.14.2 → admina-0.15.0/admina.egg-info}/PKG-INFO +142 -36
  42. {admina-0.14.2 → admina-0.15.0}/admina.egg-info/SOURCES.txt +15 -0
  43. {admina-0.14.2 → admina-0.15.0}/admina.egg-info/requires.txt +1 -1
  44. {admina-0.14.2 → admina-0.15.0}/pyproject.toml +3 -10
  45. {admina-0.14.2 → admina-0.15.0}/tests/test_benchmark_14us.py +8 -8
  46. admina-0.15.0/tests/test_compliance_gap_analysis_api.py +150 -0
  47. {admina-0.14.2 → admina-0.15.0}/tests/test_health_fields.py +2 -0
  48. admina-0.15.0/tests/test_install_hint.py +65 -0
  49. admina-0.15.0/tests/test_multi_upstream_tool_routing.py +233 -0
  50. admina-0.15.0/tests/test_sandbox_config.py +192 -0
  51. admina-0.15.0/tests/test_sandbox_core.py +449 -0
  52. admina-0.15.0/tests/test_sandbox_docker.py +298 -0
  53. admina-0.15.0/tests/test_sandbox_docker_unit.py +367 -0
  54. admina-0.15.0/tests/test_sandbox_mcp.py +390 -0
  55. admina-0.15.0/tests/test_sdk_sandbox.py +123 -0
  56. admina-0.14.2/admina/core/types.py +0 -154
  57. {admina-0.14.2 → admina-0.15.0}/LICENSE +0 -0
  58. {admina-0.14.2 → admina-0.15.0}/NOTICE +0 -0
  59. {admina-0.14.2 → admina-0.15.0}/admina/cli/__init__.py +0 -0
  60. {admina-0.14.2 → admina-0.15.0}/admina/cli/commands/__init__.py +0 -0
  61. {admina-0.14.2 → admina-0.15.0}/admina/cli/forensic.py +0 -0
  62. {admina-0.14.2 → admina-0.15.0}/admina/cli/redteam.py +0 -0
  63. {admina-0.14.2 → admina-0.15.0}/admina/cli/templates/admina.yaml.j2 +0 -0
  64. {admina-0.14.2 → admina-0.15.0}/admina/cli/templates/env.j2 +0 -0
  65. {admina-0.14.2 → admina-0.15.0}/admina/cli/templates/main.py.j2 +0 -0
  66. {admina-0.14.2 → admina-0.15.0}/admina/cli/templates/plugin_pyproject.toml.j2 +0 -0
  67. {admina-0.14.2 → admina-0.15.0}/admina/cli/templates/plugin_test.py.j2 +0 -0
  68. {admina-0.14.2 → admina-0.15.0}/admina/core/__init__.py +0 -0
  69. {admina-0.14.2 → admina-0.15.0}/admina/core/event_bus.py +0 -0
  70. {admina-0.14.2 → admina-0.15.0}/admina/core/exception_log.py +0 -0
  71. {admina-0.14.2 → admina-0.15.0}/admina/core/jcs.py +0 -0
  72. {admina-0.14.2 → admina-0.15.0}/admina/core/offline.py +0 -0
  73. {admina-0.14.2 → admina-0.15.0}/admina/core/secretfile.py +0 -0
  74. {admina-0.14.2 → admina-0.15.0}/admina/core/secrets.py +0 -0
  75. {admina-0.14.2 → admina-0.15.0}/admina/core/trace_context.py +0 -0
  76. {admina-0.14.2 → admina-0.15.0}/admina/dashboard/__init__.py +0 -0
  77. {admina-0.14.2 → admina-0.15.0}/admina/dashboard/static/heimdall.png +0 -0
  78. {admina-0.14.2 → admina-0.15.0}/admina/dashboard/static/vendor/alpinejs.min.js +0 -0
  79. {admina-0.14.2 → admina-0.15.0}/admina/domains/__init__.py +0 -0
  80. {admina-0.14.2 → admina-0.15.0}/admina/domains/agent_security/__init__.py +0 -0
  81. {admina-0.14.2 → admina-0.15.0}/admina/domains/agent_security/coordination.py +0 -0
  82. {admina-0.14.2 → admina-0.15.0}/admina/domains/agent_security/egress.py +0 -0
  83. {admina-0.14.2 → admina-0.15.0}/admina/domains/agent_security/fingerprint.py +0 -0
  84. {admina-0.14.2 → admina-0.15.0}/admina/domains/agent_security/firewall.py +0 -0
  85. {admina-0.14.2 → admina-0.15.0}/admina/domains/agent_security/loop_breaker.py +0 -0
  86. {admina-0.14.2 → admina-0.15.0}/admina/domains/agent_security/pattern_packs.py +0 -0
  87. {admina-0.14.2 → admina-0.15.0}/admina/domains/agent_security/pattern_timing.py +0 -0
  88. {admina-0.14.2 → admina-0.15.0}/admina/domains/agent_security/ruleset.py +0 -0
  89. {admina-0.14.2 → admina-0.15.0}/admina/domains/agent_security/scan_policy.py +0 -0
  90. {admina-0.14.2 → admina-0.15.0}/admina/domains/ai_infra/__init__.py +0 -0
  91. {admina-0.14.2 → admina-0.15.0}/admina/domains/ai_infra/llm_engine.py +0 -0
  92. {admina-0.14.2 → admina-0.15.0}/admina/domains/ai_infra/webui.py +0 -0
  93. {admina-0.14.2 → admina-0.15.0}/admina/domains/compliance/__init__.py +0 -0
  94. {admina-0.14.2 → admina-0.15.0}/admina/domains/compliance/ai_act_terms.py +0 -0
  95. {admina-0.14.2 → admina-0.15.0}/admina/domains/compliance/cross_regulation.py +0 -0
  96. {admina-0.14.2 → admina-0.15.0}/admina/domains/compliance/forensic.py +0 -0
  97. {admina-0.14.2 → admina-0.15.0}/admina/domains/compliance/forensic_files.py +0 -0
  98. {admina-0.14.2 → admina-0.15.0}/admina/domains/compliance/forensic_integrity.py +0 -0
  99. {admina-0.14.2 → admina-0.15.0}/admina/domains/compliance/gdpr.py +0 -0
  100. {admina-0.14.2 → admina-0.15.0}/admina/domains/compliance/nis2.py +0 -0
  101. {admina-0.14.2 → admina-0.15.0}/admina/domains/compliance/oisg.py +0 -0
  102. {admina-0.14.2 → admina-0.15.0}/admina/domains/compliance/oisg_evidence.py +0 -0
  103. {admina-0.14.2 → admina-0.15.0}/admina/domains/compliance/otel.py +0 -0
  104. {admina-0.14.2 → admina-0.15.0}/admina/domains/compliance/schemas/oisg-evidence.schema.json +0 -0
  105. {admina-0.14.2 → admina-0.15.0}/admina/domains/data_sovereignty/__init__.py +0 -0
  106. {admina-0.14.2 → admina-0.15.0}/admina/domains/data_sovereignty/classification.py +0 -0
  107. {admina-0.14.2 → admina-0.15.0}/admina/domains/data_sovereignty/email_matching.py +0 -0
  108. {admina-0.14.2 → admina-0.15.0}/admina/domains/data_sovereignty/iban.py +0 -0
  109. {admina-0.14.2 → admina-0.15.0}/admina/domains/data_sovereignty/masking.py +0 -0
  110. {admina-0.14.2 → admina-0.15.0}/admina/domains/data_sovereignty/names.py +0 -0
  111. {admina-0.14.2 → admina-0.15.0}/admina/domains/data_sovereignty/pii.py +0 -0
  112. {admina-0.14.2 → admina-0.15.0}/admina/domains/data_sovereignty/residency.py +0 -0
  113. {admina-0.14.2 → admina-0.15.0}/admina/domains/governance.py +0 -0
  114. {admina-0.14.2 → admina-0.15.0}/admina/engines/pii_plugins.py +0 -0
  115. {admina-0.14.2 → admina-0.15.0}/admina/integrations/__init__.py +0 -0
  116. {admina-0.14.2 → admina-0.15.0}/admina/integrations/cheshirecat/__init__.py +0 -0
  117. {admina-0.14.2 → admina-0.15.0}/admina/integrations/cheshirecat/admina-plugin/admina_governance.py +0 -0
  118. {admina-0.14.2 → admina-0.15.0}/admina/integrations/crewai/__init__.py +0 -0
  119. {admina-0.14.2 → admina-0.15.0}/admina/integrations/crewai/callbacks.py +0 -0
  120. {admina-0.14.2 → admina-0.15.0}/admina/integrations/langchain/__init__.py +0 -0
  121. {admina-0.14.2 → admina-0.15.0}/admina/integrations/langchain/callbacks.py +0 -0
  122. {admina-0.14.2 → admina-0.15.0}/admina/integrations/n8n/__init__.py +0 -0
  123. {admina-0.14.2 → admina-0.15.0}/admina/integrations/openclaw/__init__.py +0 -0
  124. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/__init__.py +0 -0
  125. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/adapters/__init__.py +0 -0
  126. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/adapters/_streaming.py +0 -0
  127. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/alerts/__init__.py +0 -0
  128. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/alerts/log.py +0 -0
  129. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/alerts/webhook.py +0 -0
  130. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/auth/__init__.py +0 -0
  131. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/auth/apikey.py +0 -0
  132. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/compliance/__init__.py +0 -0
  133. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/compliance/eu_ai_act.py +0 -0
  134. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/connectors/__init__.py +0 -0
  135. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/connectors/filesystem.py +0 -0
  136. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/forensic/__init__.py +0 -0
  137. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/forensic/filesystem.py +0 -0
  138. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/guards/__init__.py +0 -0
  139. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/guards/guardrailsai_guard.py +0 -0
  140. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/pii/__init__.py +0 -0
  141. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/pii/spacy_regex.py +0 -0
  142. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/transports/__init__.py +0 -0
  143. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/transports/http_rest.py +0 -0
  144. {admina-0.14.2 → admina-0.15.0}/admina/plugins/builtin/transports/mcp.py +0 -0
  145. {admina-0.14.2 → admina-0.15.0}/admina/proxy/__init__.py +0 -0
  146. {admina-0.14.2 → admina-0.15.0}/admina/proxy/api/__init__.py +0 -0
  147. {admina-0.14.2 → admina-0.15.0}/admina/proxy/api/gateway.py +0 -0
  148. {admina-0.14.2 → admina-0.15.0}/admina/proxy/api/integration.py +0 -0
  149. {admina-0.14.2 → admina-0.15.0}/admina/proxy/body_limit.py +0 -0
  150. {admina-0.14.2 → admina-0.15.0}/admina/proxy/config.py +0 -0
  151. {admina-0.14.2 → admina-0.15.0}/admina/proxy/dashboard_session.py +0 -0
  152. {admina-0.14.2 → admina-0.15.0}/admina/proxy/decisions.py +0 -0
  153. {admina-0.14.2 → admina-0.15.0}/admina/proxy/engine_bridge.py +0 -0
  154. {admina-0.14.2 → admina-0.15.0}/admina/proxy/engine_report.py +0 -0
  155. {admina-0.14.2 → admina-0.15.0}/admina/proxy/forensic_probe.py +0 -0
  156. {admina-0.14.2 → admina-0.15.0}/admina/proxy/gateway_body.py +0 -0
  157. {admina-0.14.2 → admina-0.15.0}/admina/proxy/gateway_correlation.py +0 -0
  158. {admina-0.14.2 → admina-0.15.0}/admina/proxy/gateway_outcome.py +0 -0
  159. {admina-0.14.2 → admina-0.15.0}/admina/proxy/gateway_response_scan.py +0 -0
  160. {admina-0.14.2 → admina-0.15.0}/admina/proxy/gateway_scan.py +0 -0
  161. {admina-0.14.2 → admina-0.15.0}/admina/proxy/gateway_transport.py +0 -0
  162. {admina-0.14.2 → admina-0.15.0}/admina/proxy/gateway_upstreams.py +0 -0
  163. {admina-0.14.2 → admina-0.15.0}/admina/proxy/governance.py +0 -0
  164. {admina-0.14.2 → admina-0.15.0}/admina/proxy/log_format.py +0 -0
  165. {admina-0.14.2 → admina-0.15.0}/admina/proxy/loop_lag.py +0 -0
  166. {admina-0.14.2 → admina-0.15.0}/admina/proxy/pipeline_executor.py +0 -0
  167. {admina-0.14.2 → admina-0.15.0}/admina/proxy/request_metrics.py +0 -0
  168. {admina-0.14.2 → admina-0.15.0}/admina/proxy/surfaces.py +0 -0
  169. {admina-0.14.2 → admina-0.15.0}/admina/py.typed +0 -0
  170. {admina-0.14.2 → admina-0.15.0}/admina/redteam/__init__.py +0 -0
  171. {admina-0.14.2 → admina-0.15.0}/admina/redteam/baselines/baseline.json +0 -0
  172. {admina-0.14.2 → admina-0.15.0}/admina/redteam/corpora/SHA256SUMS +0 -0
  173. {admina-0.14.2 → admina-0.15.0}/admina/redteam/corpora/coordination.jsonl +0 -0
  174. {admina-0.14.2 → admina-0.15.0}/admina/redteam/corpora/injection.jsonl +0 -0
  175. {admina-0.14.2 → admina-0.15.0}/admina/redteam/corpora/loop.jsonl +0 -0
  176. {admina-0.14.2 → admina-0.15.0}/admina/redteam/corpora/pii.jsonl +0 -0
  177. {admina-0.14.2 → admina-0.15.0}/admina/redteam/corpora.py +0 -0
  178. {admina-0.14.2 → admina-0.15.0}/admina/redteam/detectors.py +0 -0
  179. {admina-0.14.2 → admina-0.15.0}/admina/redteam/gate.py +0 -0
  180. {admina-0.14.2 → admina-0.15.0}/admina/redteam/metrics.py +0 -0
  181. {admina-0.14.2 → admina-0.15.0}/admina/redteam/report.py +0 -0
  182. {admina-0.14.2 → admina-0.15.0}/admina/redteam/runner.py +0 -0
  183. {admina-0.14.2 → admina-0.15.0}/admina/sdk/__init__.py +0 -0
  184. {admina-0.14.2 → admina-0.15.0}/admina/sdk/_compat.py +0 -0
  185. {admina-0.14.2 → admina-0.15.0}/admina/sdk/errors.py +0 -0
  186. {admina-0.14.2 → admina-0.15.0}/admina/sdk/governed_agent.py +0 -0
  187. {admina-0.14.2 → admina-0.15.0}/admina/sdk/governed_data.py +0 -0
  188. {admina-0.14.2 → admina-0.15.0}/admina/sdk/governed_model.py +0 -0
  189. {admina-0.14.2 → admina-0.15.0}/admina/sdk/retry.py +0 -0
  190. {admina-0.14.2 → admina-0.15.0}/admina/sdk/streaming.py +0 -0
  191. {admina-0.14.2 → admina-0.15.0}/admina.egg-info/dependency_links.txt +0 -0
  192. {admina-0.14.2 → admina-0.15.0}/admina.egg-info/entry_points.txt +0 -0
  193. {admina-0.14.2 → admina-0.15.0}/admina.egg-info/top_level.txt +0 -0
  194. {admina-0.14.2 → admina-0.15.0}/setup.cfg +0 -0
  195. {admina-0.14.2 → admina-0.15.0}/tests/test_admina_config_path.py +0 -0
  196. {admina-0.14.2 → admina-0.15.0}/tests/test_admina_framework_sdist.py +0 -0
  197. {admina-0.14.2 → admina-0.15.0}/tests/test_ai_act_terms.py +0 -0
  198. {admina-0.14.2 → admina-0.15.0}/tests/test_audit_api_source.py +0 -0
  199. {admina-0.14.2 → admina-0.15.0}/tests/test_auth_middleware_errors.py +0 -0
  200. {admina-0.14.2 → admina-0.15.0}/tests/test_banner_engine_info.py +0 -0
  201. {admina-0.14.2 → admina-0.15.0}/tests/test_bus_event_metadata.py +0 -0
  202. {admina-0.14.2 → admina-0.15.0}/tests/test_canary_no_content.py +0 -0
  203. {admina-0.14.2 → admina-0.15.0}/tests/test_check_versions.py +0 -0
  204. {admina-0.14.2 → admina-0.15.0}/tests/test_cli_forensic_export.py +0 -0
  205. {admina-0.14.2 → admina-0.15.0}/tests/test_cli_redteam.py +0 -0
  206. {admina-0.14.2 → admina-0.15.0}/tests/test_config_schema_validation.py +0 -0
  207. {admina-0.14.2 → admina-0.15.0}/tests/test_coordination.py +0 -0
  208. {admina-0.14.2 → admina-0.15.0}/tests/test_coordination_cli.py +0 -0
  209. {admina-0.14.2 → admina-0.15.0}/tests/test_coordination_corpus.py +0 -0
  210. {admina-0.14.2 → admina-0.15.0}/tests/test_coordination_wiring.py +0 -0
  211. {admina-0.14.2 → admina-0.15.0}/tests/test_core_config.py +0 -0
  212. {admina-0.14.2 → admina-0.15.0}/tests/test_dashboard_container.py +0 -0
  213. {admina-0.14.2 → admina-0.15.0}/tests/test_data_classifier_restricted.py +0 -0
  214. {admina-0.14.2 → admina-0.15.0}/tests/test_domains.py +0 -0
  215. {admina-0.14.2 → admina-0.15.0}/tests/test_domains_governance.py +0 -0
  216. {admina-0.14.2 → admina-0.15.0}/tests/test_egress_analyze.py +0 -0
  217. {admina-0.14.2 → admina-0.15.0}/tests/test_egress_cli.py +0 -0
  218. {admina-0.14.2 → admina-0.15.0}/tests/test_egress_pipeline.py +0 -0
  219. {admina-0.14.2 → admina-0.15.0}/tests/test_egress_policy.py +0 -0
  220. {admina-0.14.2 → admina-0.15.0}/tests/test_egress_surfaces.py +0 -0
  221. {admina-0.14.2 → admina-0.15.0}/tests/test_enabled_surfaces.py +0 -0
  222. {admina-0.14.2 → admina-0.15.0}/tests/test_engine_effective.py +0 -0
  223. {admina-0.14.2 → admina-0.15.0}/tests/test_engine_startup_errors.py +0 -0
  224. {admina-0.14.2 → admina-0.15.0}/tests/test_engines.py +0 -0
  225. {admina-0.14.2 → admina-0.15.0}/tests/test_entrypoint_script.py +0 -0
  226. {admina-0.14.2 → admina-0.15.0}/tests/test_error_disclosure.py +0 -0
  227. {admina-0.14.2 → admina-0.15.0}/tests/test_event_loop_lag_metric.py +0 -0
  228. {admina-0.14.2 → admina-0.15.0}/tests/test_fingerprint.py +0 -0
  229. {admina-0.14.2 → admina-0.15.0}/tests/test_firewall_heuristic_config.py +0 -0
  230. {admina-0.14.2 → admina-0.15.0}/tests/test_firewall_it_baseline.py +0 -0
  231. {admina-0.14.2 → admina-0.15.0}/tests/test_firewall_it_benign.py +0 -0
  232. {admina-0.14.2 → admina-0.15.0}/tests/test_firewall_parity.py +0 -0
  233. {admina-0.14.2 → admina-0.15.0}/tests/test_firewall_pattern_ids.py +0 -0
  234. {admina-0.14.2 → admina-0.15.0}/tests/test_firewall_pattern_packs.py +0 -0
  235. {admina-0.14.2 → admina-0.15.0}/tests/test_firewall_pattern_timing.py +0 -0
  236. {admina-0.14.2 → admina-0.15.0}/tests/test_forensic_atomic_write.py +0 -0
  237. {admina-0.14.2 → admina-0.15.0}/tests/test_forensic_blackbox.py +0 -0
  238. {admina-0.14.2 → admina-0.15.0}/tests/test_forensic_config_coherence.py +0 -0
  239. {admina-0.14.2 → admina-0.15.0}/tests/test_forensic_fail_mode.py +0 -0
  240. {admina-0.14.2 → admina-0.15.0}/tests/test_forensic_gateway_records.py +0 -0
  241. {admina-0.14.2 → admina-0.15.0}/tests/test_forensic_incremental_verify.py +0 -0
  242. {admina-0.14.2 → admina-0.15.0}/tests/test_forensic_integrity.py +0 -0
  243. {admina-0.14.2 → admina-0.15.0}/tests/test_forensic_rebuilt_and_duplicates.py +0 -0
  244. {admina-0.14.2 → admina-0.15.0}/tests/test_forensic_record_signature.py +0 -0
  245. {admina-0.14.2 → admina-0.15.0}/tests/test_forensic_restart.py +0 -0
  246. {admina-0.14.2 → admina-0.15.0}/tests/test_forensic_s3_reads.py +0 -0
  247. {admina-0.14.2 → admina-0.15.0}/tests/test_forensic_volume.py +0 -0
  248. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_block_status.py +0 -0
  249. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_config.py +0 -0
  250. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_correlation.py +0 -0
  251. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_endpoints.py +0 -0
  252. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_errors.py +0 -0
  253. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_forward_body.py +0 -0
  254. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_governed_stream.py +0 -0
  255. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_guard_fail_mode.py +0 -0
  256. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_helpers.py +0 -0
  257. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_latency_bench.py +0 -0
  258. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_mount.py +0 -0
  259. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_outcome_headers.py +0 -0
  260. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_passthrough.py +0 -0
  261. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_pii_contract.py +0 -0
  262. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_ruleset_endpoint.py +0 -0
  263. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_scan_coverage.py +0 -0
  264. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_upstream_auth.py +0 -0
  265. {admina-0.14.2 → admina-0.15.0}/tests/test_gateway_upstream_routes.py +0 -0
  266. {admina-0.14.2 → admina-0.15.0}/tests/test_governance_pipeline.py +0 -0
  267. {admina-0.14.2 → admina-0.15.0}/tests/test_guard_fail_mode.py +0 -0
  268. {admina-0.14.2 → admina-0.15.0}/tests/test_health_forensic_probe.py +0 -0
  269. {admina-0.14.2 → admina-0.15.0}/tests/test_iban_it.py +0 -0
  270. {admina-0.14.2 → admina-0.15.0}/tests/test_jcs.py +0 -0
  271. {admina-0.14.2 → admina-0.15.0}/tests/test_lazy_imports.py +0 -0
  272. {admina-0.14.2 → admina-0.15.0}/tests/test_log_format.py +0 -0
  273. {admina-0.14.2 → admina-0.15.0}/tests/test_mcp_block_reason.py +0 -0
  274. {admina-0.14.2 → admina-0.15.0}/tests/test_mcp_transport.py +0 -0
  275. {admina-0.14.2 → admina-0.15.0}/tests/test_metrics_docs_auth.py +0 -0
  276. {admina-0.14.2 → admina-0.15.0}/tests/test_metrics_gateway.py +0 -0
  277. {admina-0.14.2 → admina-0.15.0}/tests/test_model_allowlist_post.py +0 -0
  278. {admina-0.14.2 → admina-0.15.0}/tests/test_offline_guarantee.py +0 -0
  279. {admina-0.14.2 → admina-0.15.0}/tests/test_oisg_evidence.py +0 -0
  280. {admina-0.14.2 → admina-0.15.0}/tests/test_otel_enabled_flag.py +0 -0
  281. {admina-0.14.2 → admina-0.15.0}/tests/test_pattern_probe.py +0 -0
  282. {admina-0.14.2 → admina-0.15.0}/tests/test_person_names.py +0 -0
  283. {admina-0.14.2 → admina-0.15.0}/tests/test_pii_email_matching.py +0 -0
  284. {admina-0.14.2 → admina-0.15.0}/tests/test_pii_mask_style.py +0 -0
  285. {admina-0.14.2 → admina-0.15.0}/tests/test_pii_plugin_engines.py +0 -0
  286. {admina-0.14.2 → admina-0.15.0}/tests/test_pipeline_executor.py +0 -0
  287. {admina-0.14.2 → admina-0.15.0}/tests/test_presidio_engine.py +0 -0
  288. {admina-0.14.2 → admina-0.15.0}/tests/test_proxy_dashboard_session.py +0 -0
  289. {admina-0.14.2 → admina-0.15.0}/tests/test_proxy_forensic_would_action.py +0 -0
  290. {admina-0.14.2 → admina-0.15.0}/tests/test_proxy_governance_mode_config.py +0 -0
  291. {admina-0.14.2 → admina-0.15.0}/tests/test_proxy_guard_fail_mode.py +0 -0
  292. {admina-0.14.2 → admina-0.15.0}/tests/test_proxy_mcp_response_pii.py +0 -0
  293. {admina-0.14.2 → admina-0.15.0}/tests/test_proxy_metrics_endpoint.py +0 -0
  294. {admina-0.14.2 → admina-0.15.0}/tests/test_proxy_minimal_extra.py +0 -0
  295. {admina-0.14.2 → admina-0.15.0}/tests/test_proxy_plugins.py +0 -0
  296. {admina-0.14.2 → admina-0.15.0}/tests/test_proxy_security.py +0 -0
  297. {admina-0.14.2 → admina-0.15.0}/tests/test_query_api_key_deprecation.py +0 -0
  298. {admina-0.14.2 → admina-0.15.0}/tests/test_record_decision.py +0 -0
  299. {admina-0.14.2 → admina-0.15.0}/tests/test_redaction_values_only.py +0 -0
  300. {admina-0.14.2 → admina-0.15.0}/tests/test_redteam_efficacy.py +0 -0
  301. {admina-0.14.2 → admina-0.15.0}/tests/test_redteam_external_corpora.py +0 -0
  302. {admina-0.14.2 → admina-0.15.0}/tests/test_redteam_lib.py +0 -0
  303. {admina-0.14.2 → admina-0.15.0}/tests/test_release_workflows.py +0 -0
  304. {admina-0.14.2 → admina-0.15.0}/tests/test_request_sha256.py +0 -0
  305. {admina-0.14.2 → admina-0.15.0}/tests/test_request_size_cap.py +0 -0
  306. {admina-0.14.2 → admina-0.15.0}/tests/test_response_scan_option.py +0 -0
  307. {admina-0.14.2 → admina-0.15.0}/tests/test_ruleset_parity.py +0 -0
  308. {admina-0.14.2 → admina-0.15.0}/tests/test_ruleset_sha256.py +0 -0
  309. {admina-0.14.2 → admina-0.15.0}/tests/test_scan_depth.py +0 -0
  310. {admina-0.14.2 → admina-0.15.0}/tests/test_scan_policy.py +0 -0
  311. {admina-0.14.2 → admina-0.15.0}/tests/test_secret_files.py +0 -0
  312. {admina-0.14.2 → admina-0.15.0}/tests/test_unknown_admina_env.py +0 -0
  313. {admina-0.14.2 → admina-0.15.0}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: admina
3
- Version: 0.14.2
3
+ Version: 0.15.0
4
4
  Summary: Admina — governed AI development framework
5
5
  Author-email: Stefano Noferi <info@admina.org>
6
6
  Maintainer-email: Stefano Noferi <info@admina.org>
@@ -59,7 +59,7 @@ Requires-Dist: opentelemetry-sdk<2,>=1.20; extra == "telemetry"
59
59
  Requires-Dist: opentelemetry-exporter-otlp-proto-grpc<2,>=1.20; extra == "telemetry"
60
60
  Requires-Dist: opentelemetry-instrumentation-fastapi<1,>=0.40b0; extra == "telemetry"
61
61
  Provides-Extra: rust
62
- Requires-Dist: admina-core<0.15,>=0.14.0; extra == "rust"
62
+ Requires-Dist: admina-core<0.16,>=0.15.0; extra == "rust"
63
63
  Provides-Extra: full
64
64
  Requires-Dist: admina[nlp,proxy,telemetry]; extra == "full"
65
65
  Provides-Extra: openai
@@ -210,48 +210,61 @@ report = kit.gap_analysis(risk_category="high", current_compliance={...})
210
210
  ```bash
211
211
  # Recommended for new users: SDK + proxy + dashboard.
212
212
  # Lets you run `admina dev` and see the dashboard out of the box.
213
- pip install "admina[proxy]"
213
+ uv add "admina[proxy]"
214
+ # in an existing virtual environment: uv pip install "admina[proxy]"
215
+ # with pip: pip install "admina[proxy]"
216
+
217
+ # The `admina` command on your PATH, outside any project:
218
+ uv tool install "admina[proxy]"
214
219
 
215
220
  # Everything (proxy + NLP + telemetry). Use this if you also want
216
221
  # spaCy-based NER for PII detection or OpenTelemetry export.
217
- pip install "admina[full]"
218
- python -m spacy download en_core_web_sm # for [full] only
222
+ uv add "admina[full]"
223
+ # for [full] only: the spaCy English model, declared in the project
224
+ uv add "en-core-web-sm @ https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl"
219
225
 
220
226
  # Model-adapter provider SDKs (per-provider extras):
221
- pip install "admina[openai]" # openai>=1.0
222
- pip install "admina[ollama]" # ollama>=0.3
223
- pip install "admina[anthropic]" # anthropic>=0.39
224
- pip install "admina[mistral]" # mistralai>=1.0
225
- pip install "admina[gemini]" # google-genai>=1.0
226
- pip install "admina[bedrock]" # boto3>=1.34 (AWS Bedrock)
227
+ uv add "admina[openai]" # openai>=1.0
228
+ uv add "admina[ollama]" # ollama>=0.3
229
+ uv add "admina[anthropic]" # anthropic>=0.39
230
+ uv add "admina[mistral]" # mistralai>=1.0
231
+ uv add "admina[gemini]" # google-genai>=1.0
232
+ uv add "admina[bedrock]" # boto3>=1.34 (AWS Bedrock)
227
233
 
228
234
  # All provider SDKs at once:
229
- pip install "admina[adapters]"
235
+ uv add "admina[adapters]"
230
236
 
231
237
  # Everything (proxy + NLP + telemetry + all adapters):
232
- pip install "admina[all]"
233
- python -m spacy download en_core_web_sm # for [all] only
238
+ uv add "admina[all]"
239
+ # for [all] only: the spaCy English model, as for [full]
234
240
 
235
241
  # Optional: Rust-accelerated engine (auto-detected at runtime).
236
242
  # Opt-in extra — pulls in the admina-core wheel from PyPI.
237
- pip install "admina[rust]"
243
+ uv add "admina[rust]"
238
244
 
239
245
  # The proxy for the OpenAI-compatible gateway only: without Redis,
240
246
  # ClickHouse, boto3 and the scientific stack (see "Embedded deployment").
241
- pip install "admina[proxy-minimal]"
247
+ uv add "admina[proxy-minimal]"
242
248
 
243
249
  # Advanced: SDK only (no proxy, no dashboard, no `admina dev`).
244
250
  # Use this when embedding the SDK into another service and you don't
245
251
  # need the local dev server.
246
- pip install admina
252
+ uv add admina
247
253
  ```
248
254
 
249
- > The PyPI distribution name is `admina`; the Python import
250
- > name is `admina` (e.g. `from admina import GovernedModel`). This is
251
- > a normal Python pattern — same as `python-dateutil` → `import dateutil`.
255
+ > Each `uv add` line above adds a dependency to the `pyproject.toml` of the
256
+ > current project (`uv init` creates one). In an existing virtual environment,
257
+ > use `uv pip install` with the same argument; with pip, use `pip install`
258
+ > with the same argument (for example `pip install "admina[full]"`), and
259
+ > `python -m spacy download en_core_web_sm` for the spaCy model.
260
+ > To upgrade: `uv add --upgrade-package admina "admina[proxy]"`,
261
+ > `uv pip install -U "admina[proxy]"` or `pip install -U "admina[proxy]"`.
262
+
263
+ > The PyPI distribution and the Python module are both named `admina`
264
+ > (e.g. `from admina import GovernedModel`).
252
265
 
253
266
  > The Rust engine is an **optional, opt-in** accelerator. The default
254
- > `pip install admina` ships only the pure-Python implementation;
267
+ > `admina` package ships only the pure-Python implementation;
255
268
  > `admina[rust]` adds the `admina-core` wheel, which Admina
256
269
  > auto-detects at runtime: under `ADMINA_ENGINE=auto` (the default) the
257
270
  > firewall and the loop breaker run on Rust whenever it is installed, as in
@@ -271,16 +284,21 @@ git clone https://github.com/admina-org/admina.git
271
284
  cd admina
272
285
 
273
286
  # Recommended: proxy + dashboard + infra deps (enables `admina dev`)
274
- pip install -e ".[proxy]"
287
+ uv sync --extra proxy
288
+ # in an existing virtual environment: uv pip install -e ".[proxy]"
289
+ # with pip: pip install -e ".[proxy]"
275
290
 
276
291
  # Everything (proxy + NLP + telemetry)
277
- pip install -e ".[full]"
292
+ uv sync --extra full
278
293
 
279
294
  # All model-adapter SDKs
280
- pip install -e ".[adapters]"
295
+ uv sync --extra adapters
281
296
 
282
297
  # Everything (proxy + NLP + telemetry + all adapters)
283
- pip install -e ".[all]"
298
+ uv sync --extra all
299
+
300
+ # `uv sync` installs into .venv/: activate it (source .venv/bin/activate)
301
+ # or prefix the commands below with `uv run`.
284
302
 
285
303
  # CLI workflow
286
304
  admina init my-project # Scaffold a governed AI project
@@ -295,7 +313,7 @@ docker compose up --build # Credentials printed at bootstrap
295
313
  # and pull a model first: ollama pull llama3.1:8b
296
314
 
297
315
  # Advanced: SDK only (no proxy, no dashboard)
298
- pip install -e .
316
+ uv sync --no-dev # with pip: pip install -e .
299
317
  python -c "from admina import GovernedModel; print('SDK ready')"
300
318
  ```
301
319
 
@@ -346,7 +364,7 @@ from admina import GovernedModel, GovernedData, GovernedAgent, ComplianceKit
346
364
 
347
365
  ## Plugin System
348
366
 
349
- 9 plugin interfaces, auto-discovered from `plugins/builtin/` or installed via CLI:
367
+ 10 plugin interfaces, auto-discovered from `plugins/builtin/` or installed via CLI:
350
368
 
351
369
  | Interface | Builtin implementations |
352
370
  |-----------|------------------------|
@@ -357,11 +375,12 @@ from admina import GovernedModel, GovernedData, GovernedAgent, ComplianceKit
357
375
  | Transport Adapter | MCP, HTTP REST |
358
376
  | Forensic Store | Filesystem, S3-compatible (boto3 — AWS S3, MinIO, R2, …) |
359
377
  | Auth Provider | API Key |
360
- | PII Engine | spaCy + Regex (default), Microsoft Presidio (`pip install admina[presidio]`, `ADMINA_PII_ENGINE=presidio`); engines of other packages through the `admina.pii_engines` entry-point group (see [PII engines](#pii-engines)) |
378
+ | PII Engine | spaCy + Regex (default), Microsoft Presidio (`uv add "admina[presidio]"` or `pip install "admina[presidio]"`, `ADMINA_PII_ENGINE=presidio`); engines of other packages through the `admina.pii_engines` entry-point group (see [PII engines](#pii-engines)) |
361
379
  | Alert Channel | Log, Webhook |
380
+ | Execution Sandbox | Docker / Podman (runc or runsc), see [Execution sandbox](#execution-sandbox) |
362
381
 
363
382
  Model adapters lazy-import their provider SDK, so install the ones you
364
- use: `pip install admina[adapters]` for all of them, or a
383
+ use: `uv add "admina[adapters]"` (with pip: `pip install "admina[adapters]"`) for all of them, or a
365
384
  single provider (`[openai]`, `[ollama]`, `[anthropic]`, `[mistral]`,
366
385
  `[gemini]`, `[bedrock]`). vLLM has no extra of its own — it serves an
367
386
  OpenAI-compatible API and subclasses the OpenAI adapter, so install
@@ -460,9 +479,9 @@ stops when they are not set.
460
479
 
461
480
  Real-time governance dashboard on port 3000:
462
481
 
463
- - **Governance Score** — 0-100 composite metric (data residency, audit coverage, attack rate, forensic integrity, EU AI Act compliance)
482
+ - **Governance Score** — 0-100 composite metric (data residency, audit coverage, attack rate, forensic integrity, EU AI Act compliance). When the latest EU AI Act assessment is `NOT_APPLICABLE` (a limited- or minimal-risk system), that component is `null` in `GET /api/dashboard/score`, listed in `not_applicable`, and the score is rescaled over the other components
464
483
  - **Live Feed** — streaming governance events via WebSocket
465
- - **Compliance Gaps** — EU AI Act gap analysis with article-level detail
484
+ - **Compliance Gaps** — EU AI Act gap analysis with article-level detail; a limited- or minimal-risk system is shown as "Articles 9–15 not required"
466
485
  - **Infrastructure Health** — proxy, Redis, forensic store, ClickHouse, OTEL status
467
486
 
468
487
  API backend: `GET /api/dashboard/score`, `/feed`, `/compliance`, `/sovereignty`, `/infra`, `/models`
@@ -794,6 +813,36 @@ the message text of `POST /v1/chat/completions`, in characters (the text of
794
813
  every message, as scanned); longer requests get 413 (`invalid_request_error`,
795
814
  code `prompt_too_long`) before any governance check.
796
815
 
816
+ ### MCP routing to several servers
817
+
818
+ `/mcp` forwards to `UPSTREAM_MCP_URL`. To put several MCP servers behind
819
+ one proxy, set `ROUTING_CONFIG_PATH` to a routing file (JSON, or YAML with a
820
+ `.yaml`/`.yml` suffix):
821
+
822
+ ```yaml
823
+ default_upstream: http://localhost:9000
824
+ routes:
825
+ github:
826
+ upstream_url: http://github-mcp:8000/mcp
827
+ headers: { Authorization: "Bearer <token>" }
828
+ tools: [create_issue, git_push]
829
+ files:
830
+ upstream_url: http://files-mcp:8000/mcp
831
+ tools: [read_file, write_file]
832
+ ```
833
+
834
+ A request picks a route in one of two ways:
835
+
836
+ - **By path**: `POST /mcp/route/<name>` goes to that route's `upstream_url`.
837
+ - **By tool name**: a call on `/mcp` whose `params.name` is listed in a
838
+ route's `tools` goes to that route (`tools/call` for `git_push` above goes
839
+ to `github`). A tool not listed by any route goes to `UPSTREAM_MCP_URL`.
840
+
841
+ `tools` is a list of tool names; anything else, or a tool listed by two
842
+ routes, stops the proxy at startup. The tools are declared, not discovered:
843
+ list each tool a server provides that should be routed to it. `GET /api/stats`
844
+ reports the routes and the number of mapped tools under `routing`.
845
+
797
846
  ### PII engines
798
847
 
799
848
  `ADMINA_PII_ENGINE` (or `pii_engine` in `admina.yaml`, default `spacy-regex`)
@@ -1061,7 +1110,7 @@ attempt. The `proxy-minimal` extra installs the proxy without Redis,
1061
1110
  ClickHouse, boto3, typer and the scientific stack of the Python loop breaker:
1062
1111
 
1063
1112
  ```bash
1064
- pip install "admina[proxy-minimal]"
1113
+ uv pip install "admina[proxy-minimal]" # with pip: pip install "admina[proxy-minimal]"
1065
1114
  ADMINA_ENABLED_SURFACES=gateway REDIS_URL= CLICKHOUSE_HOST= \
1066
1115
  ADMINA_API_KEY_FILE=/run/secrets/admina_api_key \
1067
1116
  uvicorn admina.proxy.main:app --host 0.0.0.0 --port 8080
@@ -1206,6 +1255,53 @@ connection is made for telemetry.
1206
1255
  `ADMINA_API_KEY` or `ADMINA_API_KEY_FILE` and prints only whether the key
1207
1256
  is set, never any part of it.
1208
1257
 
1258
+ ### Execution sandbox
1259
+
1260
+ Admina can execute the tool calls it allows instead of forwarding them:
1261
+ a tool declared under `domains.agent_security.sandbox.tools` (for example
1262
+ a `python_exec` code interpreter) runs in a fresh container per call, with
1263
+ no network, a read-only root filesystem, an unprivileged user, no
1264
+ capabilities and memory, CPU, process and disk limits; the container is
1265
+ removed afterwards. Off by default.
1266
+
1267
+ ```yaml
1268
+ domains:
1269
+ agent_security:
1270
+ sandbox:
1271
+ enabled: true
1272
+ provider: docker # the built-in provider; binary: podman in plugin_config.docker
1273
+ runtime: runc # runsc: gVisor, registered with the engine (Linux)
1274
+ tools:
1275
+ python_exec:
1276
+ profile: python # code → /work/main.py, run with python -I
1277
+ timeout_seconds: 10
1278
+ memory_mb: 256
1279
+ ```
1280
+
1281
+ ```bash
1282
+ docker pull python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1
1283
+ ```
1284
+
1285
+ On `/mcp`, a `tools/call` of `python_exec` that the pipeline allows is
1286
+ executed in the sandbox and never forwarded upstream; the result (stdout,
1287
+ stderr, files written to `out/`) goes through PII redaction and the
1288
+ response guards like an upstream response, and `tools/list` lists the
1289
+ sandboxed tools next to the upstream's. Each execution adds a forensic
1290
+ record `<event_id>:sandbox` with hashes and sizes only, a
1291
+ `sandbox_execution` bus event, `admina_sandbox_*` metrics and a `sandbox`
1292
+ field in `/health`. If the sandbox is unavailable the call is refused with
1293
+ `data.reason: sandbox_unavailable`: it is never executed outside it, in any
1294
+ fail mode or governance mode. The SDK helper
1295
+ `admina.sdk.sandbox.sandbox_upstream` gives `GovernedAgent` the same
1296
+ execution.
1297
+
1298
+ The sandbox needs a Docker or Podman engine the proxy can reach. Access to
1299
+ the Docker socket is equivalent to root on the host: use rootless Docker or
1300
+ rootless Podman, or a dedicated host. The example `docker-compose.yml` does
1301
+ not mount the socket. `network: egress` is not supported yet. See the
1302
+ [execution sandbox guide](docs/guides/execution-sandbox.md) and what it does
1303
+ not guarantee in [MODEL_CARD.md §5d](MODEL_CARD.md#5d-execution-sandbox).
1304
+
1209
1305
  ### OpenAI-compatible gateway
1210
1306
 
1211
1307
  The proxy serves an OpenAI-compatible API at `/v1` (`POST /v1/chat/completions`,
@@ -1696,7 +1792,7 @@ ML-based content validation (toxic language, jailbreak, bias, PII via Presidio)
1696
1792
  # manually from your local mirror or wheel cache; once available, the
1697
1793
  # plugin in admina/plugins/builtin/guards/guardrailsai_guard.py will
1698
1794
  # detect it automatically.
1699
- pip install <your-guardrails-ai-wheel>
1795
+ uv pip install <your-guardrails-ai-wheel> # with pip: pip install <your-guardrails-ai-wheel>
1700
1796
  ```
1701
1797
 
1702
1798
  Enable in `admina.yaml` under `agent_security.domains.guardrailsai`. All inference runs locally by default — no data leaves the deployment perimeter.
@@ -1787,9 +1883,9 @@ See [full integration docs](https://github.com/admina-org/admina/blob/main/docs/
1787
1883
  ## Performance — Hybrid Python + Rust engine
1788
1884
 
1789
1885
  The Rust core engine is an optional accelerator. The default
1790
- `pip install admina` ships only the pure-Python implementation;
1791
- enable the Rust engine with the opt-in extra `pip install
1792
- "admina[rust]"` (or build from source for local development —
1886
+ `admina` package ships only the pure-Python implementation;
1887
+ enable the Rust engine with the opt-in extra `uv add "admina[rust]"`
1888
+ (with pip: `pip install "admina[rust]"`) (or build from source for local development —
1793
1889
  `maturin develop --release --manifest-path core-rust/Cargo.toml`, see
1794
1890
  [CONTRIBUTING.md](https://github.com/admina-org/admina/blob/main/CONTRIBUTING.md)). Under `ADMINA_ENGINE=auto` Admina
1795
1891
  runs the Rust firewall and loop breaker when the extension is installed and
@@ -1920,10 +2016,12 @@ production.
1920
2016
  | `ADMINA_CONFIG` | *(empty)* | `admina.yaml` to load (empty: current directory, then package directory) |
1921
2017
  | `ADMINA_ENABLED_SURFACES` | *(empty = all)* | Surfaces served: `gateway`, `mcp`, `integration`, `compliance`, `dashboard` |
1922
2018
  | `UPSTREAM_MCP_URL` | `http://localhost:9000` | Default upstream MCP server |
2019
+ | `ROUTING_CONFIG_PATH` | *(empty)* | Routing file for several MCP servers (see [MCP routing to several servers](#mcp-routing-to-several-servers)) |
1923
2020
  | `REDIS_URL` | `redis://localhost:6379/0` | Session state + rate limiting (empty = no Redis) |
1924
2021
  | `CLICKHOUSE_HOST` | `localhost` | Event analytics (empty = no ClickHouse) |
1925
2022
  | `FORENSIC_BACKEND` | `memory` | Forensic store: `memory` \| `filesystem` \| `s3` (else `domains.compliance.forensic.backend` of `admina.yaml`) |
1926
2023
  | `FORENSIC_BASE_DIR` | *(empty)* | Directory of the `filesystem` store (else `domains.compliance.forensic.base_dir`) |
2024
+ | `ADMINA_EU_AI_ACT_ASSESSMENTS_PATH` | *(empty)* | JSON file keeping the last 100 EU AI Act assessments across restarts (empty: in memory only; the compose files set it on the `compliance-data` volume) |
1927
2025
  | `ADMINA_FORENSIC_FAIL_MODE` | `open` | A forensic record that cannot be written: `open` (logged, request served) \| `closed` (`503`, not forwarded) |
1928
2026
  | `LOG_LEVEL` | `INFO` | Logging verbosity |
1929
2027
  | `ADMINA_LOG_FORMAT` | `text` | Log output: `text` \| `json` |
@@ -2001,6 +2099,14 @@ curl -X POST http://localhost:8080/api/compliance/classify \
2001
2099
  -H "Content-Type: application/json" \
2002
2100
  -d '{"description":"AI credit scoring","use_case":"lending","data_types":["financial"]}'
2003
2101
 
2102
+ # EU AI Act assessment of a limited-risk system (recorded as NOT_APPLICABLE)
2103
+ curl -X POST http://localhost:8080/api/compliance/gap-analysis \
2104
+ -H "Content-Type: application/json" \
2105
+ -d '{"risk_category":"limited","system_name":"Helpdesk bot"}'
2106
+
2107
+ # The most recent EU AI Act assessment (404 without one)
2108
+ curl http://localhost:8080/api/compliance/gap-analysis/latest
2109
+
2004
2110
  # Dashboard governance score
2005
2111
  curl http://localhost:8080/api/dashboard/score
2006
2112
  ```
@@ -126,48 +126,61 @@ report = kit.gap_analysis(risk_category="high", current_compliance={...})
126
126
  ```bash
127
127
  # Recommended for new users: SDK + proxy + dashboard.
128
128
  # Lets you run `admina dev` and see the dashboard out of the box.
129
- pip install "admina[proxy]"
129
+ uv add "admina[proxy]"
130
+ # in an existing virtual environment: uv pip install "admina[proxy]"
131
+ # with pip: pip install "admina[proxy]"
132
+
133
+ # The `admina` command on your PATH, outside any project:
134
+ uv tool install "admina[proxy]"
130
135
 
131
136
  # Everything (proxy + NLP + telemetry). Use this if you also want
132
137
  # spaCy-based NER for PII detection or OpenTelemetry export.
133
- pip install "admina[full]"
134
- python -m spacy download en_core_web_sm # for [full] only
138
+ uv add "admina[full]"
139
+ # for [full] only: the spaCy English model, declared in the project
140
+ uv add "en-core-web-sm @ https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl"
135
141
 
136
142
  # Model-adapter provider SDKs (per-provider extras):
137
- pip install "admina[openai]" # openai>=1.0
138
- pip install "admina[ollama]" # ollama>=0.3
139
- pip install "admina[anthropic]" # anthropic>=0.39
140
- pip install "admina[mistral]" # mistralai>=1.0
141
- pip install "admina[gemini]" # google-genai>=1.0
142
- pip install "admina[bedrock]" # boto3>=1.34 (AWS Bedrock)
143
+ uv add "admina[openai]" # openai>=1.0
144
+ uv add "admina[ollama]" # ollama>=0.3
145
+ uv add "admina[anthropic]" # anthropic>=0.39
146
+ uv add "admina[mistral]" # mistralai>=1.0
147
+ uv add "admina[gemini]" # google-genai>=1.0
148
+ uv add "admina[bedrock]" # boto3>=1.34 (AWS Bedrock)
143
149
 
144
150
  # All provider SDKs at once:
145
- pip install "admina[adapters]"
151
+ uv add "admina[adapters]"
146
152
 
147
153
  # Everything (proxy + NLP + telemetry + all adapters):
148
- pip install "admina[all]"
149
- python -m spacy download en_core_web_sm # for [all] only
154
+ uv add "admina[all]"
155
+ # for [all] only: the spaCy English model, as for [full]
150
156
 
151
157
  # Optional: Rust-accelerated engine (auto-detected at runtime).
152
158
  # Opt-in extra — pulls in the admina-core wheel from PyPI.
153
- pip install "admina[rust]"
159
+ uv add "admina[rust]"
154
160
 
155
161
  # The proxy for the OpenAI-compatible gateway only: without Redis,
156
162
  # ClickHouse, boto3 and the scientific stack (see "Embedded deployment").
157
- pip install "admina[proxy-minimal]"
163
+ uv add "admina[proxy-minimal]"
158
164
 
159
165
  # Advanced: SDK only (no proxy, no dashboard, no `admina dev`).
160
166
  # Use this when embedding the SDK into another service and you don't
161
167
  # need the local dev server.
162
- pip install admina
168
+ uv add admina
163
169
  ```
164
170
 
165
- > The PyPI distribution name is `admina`; the Python import
166
- > name is `admina` (e.g. `from admina import GovernedModel`). This is
167
- > a normal Python pattern — same as `python-dateutil` → `import dateutil`.
171
+ > Each `uv add` line above adds a dependency to the `pyproject.toml` of the
172
+ > current project (`uv init` creates one). In an existing virtual environment,
173
+ > use `uv pip install` with the same argument; with pip, use `pip install`
174
+ > with the same argument (for example `pip install "admina[full]"`), and
175
+ > `python -m spacy download en_core_web_sm` for the spaCy model.
176
+ > To upgrade: `uv add --upgrade-package admina "admina[proxy]"`,
177
+ > `uv pip install -U "admina[proxy]"` or `pip install -U "admina[proxy]"`.
178
+
179
+ > The PyPI distribution and the Python module are both named `admina`
180
+ > (e.g. `from admina import GovernedModel`).
168
181
 
169
182
  > The Rust engine is an **optional, opt-in** accelerator. The default
170
- > `pip install admina` ships only the pure-Python implementation;
183
+ > `admina` package ships only the pure-Python implementation;
171
184
  > `admina[rust]` adds the `admina-core` wheel, which Admina
172
185
  > auto-detects at runtime: under `ADMINA_ENGINE=auto` (the default) the
173
186
  > firewall and the loop breaker run on Rust whenever it is installed, as in
@@ -187,16 +200,21 @@ git clone https://github.com/admina-org/admina.git
187
200
  cd admina
188
201
 
189
202
  # Recommended: proxy + dashboard + infra deps (enables `admina dev`)
190
- pip install -e ".[proxy]"
203
+ uv sync --extra proxy
204
+ # in an existing virtual environment: uv pip install -e ".[proxy]"
205
+ # with pip: pip install -e ".[proxy]"
191
206
 
192
207
  # Everything (proxy + NLP + telemetry)
193
- pip install -e ".[full]"
208
+ uv sync --extra full
194
209
 
195
210
  # All model-adapter SDKs
196
- pip install -e ".[adapters]"
211
+ uv sync --extra adapters
197
212
 
198
213
  # Everything (proxy + NLP + telemetry + all adapters)
199
- pip install -e ".[all]"
214
+ uv sync --extra all
215
+
216
+ # `uv sync` installs into .venv/: activate it (source .venv/bin/activate)
217
+ # or prefix the commands below with `uv run`.
200
218
 
201
219
  # CLI workflow
202
220
  admina init my-project # Scaffold a governed AI project
@@ -211,7 +229,7 @@ docker compose up --build # Credentials printed at bootstrap
211
229
  # and pull a model first: ollama pull llama3.1:8b
212
230
 
213
231
  # Advanced: SDK only (no proxy, no dashboard)
214
- pip install -e .
232
+ uv sync --no-dev # with pip: pip install -e .
215
233
  python -c "from admina import GovernedModel; print('SDK ready')"
216
234
  ```
217
235
 
@@ -262,7 +280,7 @@ from admina import GovernedModel, GovernedData, GovernedAgent, ComplianceKit
262
280
 
263
281
  ## Plugin System
264
282
 
265
- 9 plugin interfaces, auto-discovered from `plugins/builtin/` or installed via CLI:
283
+ 10 plugin interfaces, auto-discovered from `plugins/builtin/` or installed via CLI:
266
284
 
267
285
  | Interface | Builtin implementations |
268
286
  |-----------|------------------------|
@@ -273,11 +291,12 @@ from admina import GovernedModel, GovernedData, GovernedAgent, ComplianceKit
273
291
  | Transport Adapter | MCP, HTTP REST |
274
292
  | Forensic Store | Filesystem, S3-compatible (boto3 — AWS S3, MinIO, R2, …) |
275
293
  | Auth Provider | API Key |
276
- | PII Engine | spaCy + Regex (default), Microsoft Presidio (`pip install admina[presidio]`, `ADMINA_PII_ENGINE=presidio`); engines of other packages through the `admina.pii_engines` entry-point group (see [PII engines](#pii-engines)) |
294
+ | PII Engine | spaCy + Regex (default), Microsoft Presidio (`uv add "admina[presidio]"` or `pip install "admina[presidio]"`, `ADMINA_PII_ENGINE=presidio`); engines of other packages through the `admina.pii_engines` entry-point group (see [PII engines](#pii-engines)) |
277
295
  | Alert Channel | Log, Webhook |
296
+ | Execution Sandbox | Docker / Podman (runc or runsc), see [Execution sandbox](#execution-sandbox) |
278
297
 
279
298
  Model adapters lazy-import their provider SDK, so install the ones you
280
- use: `pip install admina[adapters]` for all of them, or a
299
+ use: `uv add "admina[adapters]"` (with pip: `pip install "admina[adapters]"`) for all of them, or a
281
300
  single provider (`[openai]`, `[ollama]`, `[anthropic]`, `[mistral]`,
282
301
  `[gemini]`, `[bedrock]`). vLLM has no extra of its own — it serves an
283
302
  OpenAI-compatible API and subclasses the OpenAI adapter, so install
@@ -376,9 +395,9 @@ stops when they are not set.
376
395
 
377
396
  Real-time governance dashboard on port 3000:
378
397
 
379
- - **Governance Score** — 0-100 composite metric (data residency, audit coverage, attack rate, forensic integrity, EU AI Act compliance)
398
+ - **Governance Score** — 0-100 composite metric (data residency, audit coverage, attack rate, forensic integrity, EU AI Act compliance). When the latest EU AI Act assessment is `NOT_APPLICABLE` (a limited- or minimal-risk system), that component is `null` in `GET /api/dashboard/score`, listed in `not_applicable`, and the score is rescaled over the other components
380
399
  - **Live Feed** — streaming governance events via WebSocket
381
- - **Compliance Gaps** — EU AI Act gap analysis with article-level detail
400
+ - **Compliance Gaps** — EU AI Act gap analysis with article-level detail; a limited- or minimal-risk system is shown as "Articles 9–15 not required"
382
401
  - **Infrastructure Health** — proxy, Redis, forensic store, ClickHouse, OTEL status
383
402
 
384
403
  API backend: `GET /api/dashboard/score`, `/feed`, `/compliance`, `/sovereignty`, `/infra`, `/models`
@@ -710,6 +729,36 @@ the message text of `POST /v1/chat/completions`, in characters (the text of
710
729
  every message, as scanned); longer requests get 413 (`invalid_request_error`,
711
730
  code `prompt_too_long`) before any governance check.
712
731
 
732
+ ### MCP routing to several servers
733
+
734
+ `/mcp` forwards to `UPSTREAM_MCP_URL`. To put several MCP servers behind
735
+ one proxy, set `ROUTING_CONFIG_PATH` to a routing file (JSON, or YAML with a
736
+ `.yaml`/`.yml` suffix):
737
+
738
+ ```yaml
739
+ default_upstream: http://localhost:9000
740
+ routes:
741
+ github:
742
+ upstream_url: http://github-mcp:8000/mcp
743
+ headers: { Authorization: "Bearer <token>" }
744
+ tools: [create_issue, git_push]
745
+ files:
746
+ upstream_url: http://files-mcp:8000/mcp
747
+ tools: [read_file, write_file]
748
+ ```
749
+
750
+ A request picks a route in one of two ways:
751
+
752
+ - **By path**: `POST /mcp/route/<name>` goes to that route's `upstream_url`.
753
+ - **By tool name**: a call on `/mcp` whose `params.name` is listed in a
754
+ route's `tools` goes to that route (`tools/call` for `git_push` above goes
755
+ to `github`). A tool not listed by any route goes to `UPSTREAM_MCP_URL`.
756
+
757
+ `tools` is a list of tool names; anything else, or a tool listed by two
758
+ routes, stops the proxy at startup. The tools are declared, not discovered:
759
+ list each tool a server provides that should be routed to it. `GET /api/stats`
760
+ reports the routes and the number of mapped tools under `routing`.
761
+
713
762
  ### PII engines
714
763
 
715
764
  `ADMINA_PII_ENGINE` (or `pii_engine` in `admina.yaml`, default `spacy-regex`)
@@ -977,7 +1026,7 @@ attempt. The `proxy-minimal` extra installs the proxy without Redis,
977
1026
  ClickHouse, boto3, typer and the scientific stack of the Python loop breaker:
978
1027
 
979
1028
  ```bash
980
- pip install "admina[proxy-minimal]"
1029
+ uv pip install "admina[proxy-minimal]" # with pip: pip install "admina[proxy-minimal]"
981
1030
  ADMINA_ENABLED_SURFACES=gateway REDIS_URL= CLICKHOUSE_HOST= \
982
1031
  ADMINA_API_KEY_FILE=/run/secrets/admina_api_key \
983
1032
  uvicorn admina.proxy.main:app --host 0.0.0.0 --port 8080
@@ -1122,6 +1171,53 @@ connection is made for telemetry.
1122
1171
  `ADMINA_API_KEY` or `ADMINA_API_KEY_FILE` and prints only whether the key
1123
1172
  is set, never any part of it.
1124
1173
 
1174
+ ### Execution sandbox
1175
+
1176
+ Admina can execute the tool calls it allows instead of forwarding them:
1177
+ a tool declared under `domains.agent_security.sandbox.tools` (for example
1178
+ a `python_exec` code interpreter) runs in a fresh container per call, with
1179
+ no network, a read-only root filesystem, an unprivileged user, no
1180
+ capabilities and memory, CPU, process and disk limits; the container is
1181
+ removed afterwards. Off by default.
1182
+
1183
+ ```yaml
1184
+ domains:
1185
+ agent_security:
1186
+ sandbox:
1187
+ enabled: true
1188
+ provider: docker # the built-in provider; binary: podman in plugin_config.docker
1189
+ runtime: runc # runsc: gVisor, registered with the engine (Linux)
1190
+ tools:
1191
+ python_exec:
1192
+ profile: python # code → /work/main.py, run with python -I
1193
+ timeout_seconds: 10
1194
+ memory_mb: 256
1195
+ ```
1196
+
1197
+ ```bash
1198
+ docker pull python:3.12-slim@sha256:a6e34c598f2467ed0e9a8d349809fcd8b5c603269512df273a0bb1784edc11b1
1199
+ ```
1200
+
1201
+ On `/mcp`, a `tools/call` of `python_exec` that the pipeline allows is
1202
+ executed in the sandbox and never forwarded upstream; the result (stdout,
1203
+ stderr, files written to `out/`) goes through PII redaction and the
1204
+ response guards like an upstream response, and `tools/list` lists the
1205
+ sandboxed tools next to the upstream's. Each execution adds a forensic
1206
+ record `<event_id>:sandbox` with hashes and sizes only, a
1207
+ `sandbox_execution` bus event, `admina_sandbox_*` metrics and a `sandbox`
1208
+ field in `/health`. If the sandbox is unavailable the call is refused with
1209
+ `data.reason: sandbox_unavailable`: it is never executed outside it, in any
1210
+ fail mode or governance mode. The SDK helper
1211
+ `admina.sdk.sandbox.sandbox_upstream` gives `GovernedAgent` the same
1212
+ execution.
1213
+
1214
+ The sandbox needs a Docker or Podman engine the proxy can reach. Access to
1215
+ the Docker socket is equivalent to root on the host: use rootless Docker or
1216
+ rootless Podman, or a dedicated host. The example `docker-compose.yml` does
1217
+ not mount the socket. `network: egress` is not supported yet. See the
1218
+ [execution sandbox guide](docs/guides/execution-sandbox.md) and what it does
1219
+ not guarantee in [MODEL_CARD.md §5d](MODEL_CARD.md#5d-execution-sandbox).
1220
+
1125
1221
  ### OpenAI-compatible gateway
1126
1222
 
1127
1223
  The proxy serves an OpenAI-compatible API at `/v1` (`POST /v1/chat/completions`,
@@ -1612,7 +1708,7 @@ ML-based content validation (toxic language, jailbreak, bias, PII via Presidio)
1612
1708
  # manually from your local mirror or wheel cache; once available, the
1613
1709
  # plugin in admina/plugins/builtin/guards/guardrailsai_guard.py will
1614
1710
  # detect it automatically.
1615
- pip install <your-guardrails-ai-wheel>
1711
+ uv pip install <your-guardrails-ai-wheel> # with pip: pip install <your-guardrails-ai-wheel>
1616
1712
  ```
1617
1713
 
1618
1714
  Enable in `admina.yaml` under `agent_security.domains.guardrailsai`. All inference runs locally by default — no data leaves the deployment perimeter.
@@ -1703,9 +1799,9 @@ See [full integration docs](https://github.com/admina-org/admina/blob/main/docs/
1703
1799
  ## Performance — Hybrid Python + Rust engine
1704
1800
 
1705
1801
  The Rust core engine is an optional accelerator. The default
1706
- `pip install admina` ships only the pure-Python implementation;
1707
- enable the Rust engine with the opt-in extra `pip install
1708
- "admina[rust]"` (or build from source for local development —
1802
+ `admina` package ships only the pure-Python implementation;
1803
+ enable the Rust engine with the opt-in extra `uv add "admina[rust]"`
1804
+ (with pip: `pip install "admina[rust]"`) (or build from source for local development —
1709
1805
  `maturin develop --release --manifest-path core-rust/Cargo.toml`, see
1710
1806
  [CONTRIBUTING.md](https://github.com/admina-org/admina/blob/main/CONTRIBUTING.md)). Under `ADMINA_ENGINE=auto` Admina
1711
1807
  runs the Rust firewall and loop breaker when the extension is installed and
@@ -1836,10 +1932,12 @@ production.
1836
1932
  | `ADMINA_CONFIG` | *(empty)* | `admina.yaml` to load (empty: current directory, then package directory) |
1837
1933
  | `ADMINA_ENABLED_SURFACES` | *(empty = all)* | Surfaces served: `gateway`, `mcp`, `integration`, `compliance`, `dashboard` |
1838
1934
  | `UPSTREAM_MCP_URL` | `http://localhost:9000` | Default upstream MCP server |
1935
+ | `ROUTING_CONFIG_PATH` | *(empty)* | Routing file for several MCP servers (see [MCP routing to several servers](#mcp-routing-to-several-servers)) |
1839
1936
  | `REDIS_URL` | `redis://localhost:6379/0` | Session state + rate limiting (empty = no Redis) |
1840
1937
  | `CLICKHOUSE_HOST` | `localhost` | Event analytics (empty = no ClickHouse) |
1841
1938
  | `FORENSIC_BACKEND` | `memory` | Forensic store: `memory` \| `filesystem` \| `s3` (else `domains.compliance.forensic.backend` of `admina.yaml`) |
1842
1939
  | `FORENSIC_BASE_DIR` | *(empty)* | Directory of the `filesystem` store (else `domains.compliance.forensic.base_dir`) |
1940
+ | `ADMINA_EU_AI_ACT_ASSESSMENTS_PATH` | *(empty)* | JSON file keeping the last 100 EU AI Act assessments across restarts (empty: in memory only; the compose files set it on the `compliance-data` volume) |
1843
1941
  | `ADMINA_FORENSIC_FAIL_MODE` | `open` | A forensic record that cannot be written: `open` (logged, request served) \| `closed` (`503`, not forwarded) |
1844
1942
  | `LOG_LEVEL` | `INFO` | Logging verbosity |
1845
1943
  | `ADMINA_LOG_FORMAT` | `text` | Log output: `text` \| `json` |
@@ -1917,6 +2015,14 @@ curl -X POST http://localhost:8080/api/compliance/classify \
1917
2015
  -H "Content-Type: application/json" \
1918
2016
  -d '{"description":"AI credit scoring","use_case":"lending","data_types":["financial"]}'
1919
2017
 
2018
+ # EU AI Act assessment of a limited-risk system (recorded as NOT_APPLICABLE)
2019
+ curl -X POST http://localhost:8080/api/compliance/gap-analysis \
2020
+ -H "Content-Type: application/json" \
2021
+ -d '{"risk_category":"limited","system_name":"Helpdesk bot"}'
2022
+
2023
+ # The most recent EU AI Act assessment (404 without one)
2024
+ curl http://localhost:8080/api/compliance/gap-analysis/latest
2025
+
1920
2026
  # Dashboard governance score
1921
2027
  curl http://localhost:8080/api/dashboard/score
1922
2028
  ```
@@ -23,7 +23,7 @@ from __future__ import annotations
23
23
 
24
24
  from admina.sdk import ComplianceKit, GovernedAgent, GovernedData, GovernedModel
25
25
 
26
- __version__ = "0.14.2"
26
+ __version__ = "0.15.0"
27
27
 
28
28
  __all__ = [
29
29
  "__version__",