agenticdome-python-sdk 1.2.7__tar.gz → 1.2.8__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 (52) hide show
  1. {agenticdome_python_sdk-1.2.7/agenticdome_python_sdk.egg-info → agenticdome_python_sdk-1.2.8}/PKG-INFO +1 -1
  2. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8/agenticdome_python_sdk.egg-info}/PKG-INFO +1 -1
  3. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_python_sdk.egg-info/SOURCES.txt +1 -0
  4. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/client.py +107 -5
  5. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/pyproject.toml +1 -1
  6. agenticdome_python_sdk-1.2.8/tests/test_execution_broker.py +75 -0
  7. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/LICENSE +0 -0
  8. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/MANIFEST.in +0 -0
  9. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/README.md +0 -0
  10. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_python_sdk.egg-info/dependency_links.txt +0 -0
  11. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_python_sdk.egg-info/requires.txt +0 -0
  12. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_python_sdk.egg-info/top_level.txt +0 -0
  13. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/__init__.py +0 -0
  14. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/_framework_firewall.py +0 -0
  15. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/agno.py +0 -0
  16. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/autogen.py +0 -0
  17. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/aws_bedrock.py +0 -0
  18. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/claude.py +0 -0
  19. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/crewai.py +0 -0
  20. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/google_adk.py +0 -0
  21. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/identity.py +0 -0
  22. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/langgraph.py +0 -0
  23. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/llamaindex.py +0 -0
  24. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/mcp_host.py +0 -0
  25. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/microsoft_agent_framework.py +0 -0
  26. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/microsoft_ai_foundry.py +0 -0
  27. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/openai_agents.py +0 -0
  28. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/proof.py +0 -0
  29. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/pydantic.py +0 -0
  30. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/agenticdome_sdk/smolagents.py +0 -0
  31. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/examples/attack_demo.py +0 -0
  32. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/examples/crewai_agenticdome_firewall.py +0 -0
  33. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/setup.cfg +0 -0
  34. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/setup.py +0 -0
  35. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_agno_integration.py +0 -0
  36. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_attack_demo.py +0 -0
  37. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_autogen_integration.py +0 -0
  38. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_aws_bedrock_integration.py +0 -0
  39. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_claude_integration.py +0 -0
  40. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_client.py +0 -0
  41. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_crewai_integration.py +0 -0
  42. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_google_adk_integration.py +0 -0
  43. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_identity_context.py +0 -0
  44. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_langgraph_integration.py +0 -0
  45. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_live_tenant.py +0 -0
  46. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_llamaindex_integration.py +0 -0
  47. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_mcp_host_integration.py +0 -0
  48. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_microsoft_agent_framework_integration.py +0 -0
  49. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_microsoft_ai_foundry_integration.py +0 -0
  50. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_openai_agents_integration.py +0 -0
  51. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_pydanticai_integration.py +0 -0
  52. {agenticdome_python_sdk-1.2.7 → agenticdome_python_sdk-1.2.8}/tests/test_smolagents_integration.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agenticdome-python-sdk
3
- Version: 1.2.7
3
+ Version: 1.2.8
4
4
  Summary: Official Python SDK for AgenticDome security guardrails, DLP, tool authorization, and multi-agent delegation enforcement.
5
5
  Author: AgenticDome
6
6
  License: Proprietary
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agenticdome-python-sdk
3
- Version: 1.2.7
3
+ Version: 1.2.8
4
4
  Summary: Official Python SDK for AgenticDome security guardrails, DLP, tool authorization, and multi-agent delegation enforcement.
5
5
  Author: AgenticDome
6
6
  License: Proprietary
@@ -36,6 +36,7 @@ tests/test_aws_bedrock_integration.py
36
36
  tests/test_claude_integration.py
37
37
  tests/test_client.py
38
38
  tests/test_crewai_integration.py
39
+ tests/test_execution_broker.py
39
40
  tests/test_google_adk_integration.py
40
41
  tests/test_identity_context.py
41
42
  tests/test_langgraph_integration.py
@@ -1,4 +1,5 @@
1
1
  import base64
2
+ import hashlib
2
3
  import os
3
4
  import re
4
5
  from typing import Optional, Dict, List, Any, Tuple, Union, Mapping
@@ -60,6 +61,7 @@ class AgentGuardClient:
60
61
  pool_block: bool = False,
61
62
  service_token: Optional[str] = None,
62
63
  tool_provenance: Optional[Mapping[str, Mapping[str, str]]] = None,
64
+ execution_broker_mode: Optional[str] = None,
63
65
  ):
64
66
  self.api_base = self._require_nonempty("api_base", api_base).rstrip("/")
65
67
  self.api_key = self._require_nonempty(
@@ -86,6 +88,14 @@ class AgentGuardClient:
86
88
  default=5.0,
87
89
  )
88
90
  self.user_agent = user_agent
91
+ broker_mode = str(
92
+ execution_broker_mode
93
+ if execution_broker_mode is not None
94
+ else os.getenv("AGENTICDOME_EXECUTION_BROKER_MODE", "off")
95
+ ).strip().lower()
96
+ if broker_mode not in {"off", "observe", "enforce"}:
97
+ raise ValueError("execution_broker_mode must be off, observe, or enforce")
98
+ self.execution_broker_mode = broker_mode
89
99
  self._tool_provenance: Dict[str, Dict[str, str]] = {}
90
100
  for registered_name, provenance in dict(tool_provenance or {}).items():
91
101
  self.register_tool_provenance(
@@ -528,12 +538,23 @@ class AgentGuardClient:
528
538
  actual_role: Optional[str] = None,
529
539
  source_agent_role: Optional[str] = None,
530
540
  target_agent_role: Optional[str] = None,
541
+ actor_chain: Optional[List[Dict[str, Any]]] = None,
542
+ scopes: Optional[List[str]] = None,
543
+ permissions: Optional[List[str]] = None,
544
+ parent_jti: Optional[str] = None,
545
+ root_jti: Optional[str] = None,
546
+ policy_id: Optional[str] = None,
547
+ policy_version: Optional[str] = None,
548
+ policy_hash: Optional[str] = None,
549
+ proof_thumbprint: Optional[str] = None,
531
550
  redact_pii: Optional[bool] = None,
532
551
  redact_secrets: Optional[bool] = None,
533
552
  block_on_sensitive_output: Optional[bool] = None,
534
553
  trusted_destination_domains: Optional[List[str]] = None,
535
554
  allowed_destination_domains: Optional[List[str]] = None,
536
555
  attachments: Optional[List[str]] = None,
556
+ execution_broker: Optional[bool] = None,
557
+ execution_boundary_id: Optional[str] = None,
537
558
  tenant_id: Optional[Union[str, int]] = None,
538
559
  ) -> Dict[str, Any]:
539
560
  """
@@ -596,6 +617,15 @@ class AgentGuardClient:
596
617
  actual_role=actual_role,
597
618
  source_agent_role=source_agent_role,
598
619
  target_agent_role=target_agent_role,
620
+ actor_chain=actor_chain,
621
+ scopes=scopes,
622
+ permissions=permissions,
623
+ parent_jti=parent_jti,
624
+ root_jti=root_jti,
625
+ policy_id=policy_id,
626
+ policy_version=policy_version,
627
+ policy_hash=policy_hash,
628
+ proof_thumbprint=proof_thumbprint,
599
629
  redact_pii=redact_pii,
600
630
  redact_secrets=redact_secrets,
601
631
  block_on_sensitive_output=block_on_sensitive_output,
@@ -628,6 +658,15 @@ class AgentGuardClient:
628
658
  "actual_role": actual_role,
629
659
  "source_agent_role": source_agent_role,
630
660
  "target_agent_role": target_agent_role,
661
+ "actor_chain": actor_chain,
662
+ "scopes": scopes,
663
+ "permissions": permissions,
664
+ "parent_jti": parent_jti,
665
+ "root_jti": root_jti,
666
+ "policy_id": policy_id,
667
+ "policy_version": policy_version,
668
+ "policy_hash": policy_hash,
669
+ "proof_thumbprint": proof_thumbprint,
631
670
  "redact_pii": redact_pii,
632
671
  "redact_secrets": redact_secrets,
633
672
  "block_on_sensitive_output": block_on_sensitive_output,
@@ -637,12 +676,33 @@ class AgentGuardClient:
637
676
  }
638
677
  )
639
678
 
640
- return self._request(
641
- "POST",
642
- "/tools/guardrail/validate",
643
- json_body=payload,
644
- tenant_id=tenant_id,
679
+ broker_enabled = bool(
680
+ tool_name
681
+ and (self.execution_broker_mode in {"observe", "enforce"} or execution_broker is True)
645
682
  )
683
+ if broker_enabled:
684
+ boundary_id = self._normalize_optional_string(execution_boundary_id)
685
+ if boundary_id is None:
686
+ material = "|".join([
687
+ str(platform or "unknown"),
688
+ str(agent_id),
689
+ str(tool_name),
690
+ str(session_id or "stateless"),
691
+ ])
692
+ boundary_id = "sdk:" + hashlib.sha256(material.encode("utf-8")).hexdigest()[:32]
693
+ payload["boundary_id"] = boundary_id
694
+
695
+ path = "/tools/execution/authorize" if broker_enabled else "/tools/guardrail/validate"
696
+ response = self._request("POST", path, json_body=payload, tenant_id=tenant_id)
697
+ if broker_enabled:
698
+ broker = response.get("broker") if isinstance(response.get("broker"), dict) else {}
699
+ verified = bool(broker.get("verified")) and bool(broker.get("token_consumed"))
700
+ must_enforce = self.execution_broker_mode == "enforce" or execution_broker is True
701
+ if must_enforce and not verified:
702
+ raise AgentGuardError(
703
+ "AgenticDome execution broker did not return a verified, atomically consumed decision"
704
+ )
705
+ return response
646
706
 
647
707
  # Backward compatibility alias
648
708
  def guardrail_check(
@@ -661,6 +721,13 @@ class AgentGuardClient:
661
721
  policy_context=policy_context,
662
722
  )
663
723
 
724
+ def get_tool_provenance_status(
725
+ self,
726
+ tenant_id: Optional[Union[str, int]] = None,
727
+ ) -> Dict[str, Any]:
728
+ """Return the tenant's signed provenance cache readiness and tool count."""
729
+ return self._request("GET", "/tools/provenance/status", tenant_id=tenant_id)
730
+
664
731
  # ------------------------------------------------------------------
665
732
  # Mesh
666
733
  # ------------------------------------------------------------------
@@ -1340,6 +1407,41 @@ class AgentGuardClient:
1340
1407
  }
1341
1408
  )
1342
1409
 
1410
+ # In broker mode the official MCP adapter uses the same one-request
1411
+ # execution boundary as REST. This preserves immediate decision
1412
+ # consumption without adding a second network round trip.
1413
+ if tool_name and self.execution_broker_mode in {"observe", "enforce"}:
1414
+ return self.guardrail_validate(
1415
+ text=text,
1416
+ agent_id=agent_id,
1417
+ platform=platform,
1418
+ source_platform=source_platform,
1419
+ tool_platform=tool_platform,
1420
+ tool_name=tool_name,
1421
+ tool_args=tool_args,
1422
+ tool_version=tool_version,
1423
+ tool_digest=tool_digest,
1424
+ policy_context=policy_context,
1425
+ direction=direction,
1426
+ source_agent_id=source_agent_id,
1427
+ user_id=user_id,
1428
+ reasoning_trace=reasoning_trace,
1429
+ request_purpose=request_purpose,
1430
+ purpose=purpose,
1431
+ intent=intent,
1432
+ claimed_role=claimed_role,
1433
+ actual_role=actual_role,
1434
+ source_agent_role=source_agent_role,
1435
+ target_agent_role=target_agent_role,
1436
+ redact_pii=redact_pii,
1437
+ redact_secrets=redact_secrets,
1438
+ block_on_sensitive_output=block_on_sensitive_output,
1439
+ trusted_destination_domains=trusted_destination_domains,
1440
+ allowed_destination_domains=allowed_destination_domains,
1441
+ execution_broker=True,
1442
+ tenant_id=tenant_id,
1443
+ )
1444
+
1343
1445
  return self.mcp_tool_call(
1344
1446
  "guardrail.validate",
1345
1447
  arguments,
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "agenticdome-python-sdk"
7
- version = "1.2.7"
7
+ version = "1.2.8"
8
8
  description = "Official Python SDK for AgenticDome security guardrails, DLP, tool authorization, and multi-agent delegation enforcement."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -0,0 +1,75 @@
1
+ from agenticdome_sdk.client import AgentGuardClient, AgentGuardError
2
+
3
+
4
+ def _client(mode="enforce"):
5
+ return AgentGuardClient(
6
+ "https://sidecar.example",
7
+ api_key="test-key",
8
+ tenant_id="tenant-1",
9
+ execution_broker_mode=mode,
10
+ max_retries=0,
11
+ )
12
+
13
+
14
+ def test_tool_authorization_uses_one_request_broker_and_requires_receipt(monkeypatch):
15
+ client = _client()
16
+ observed = {}
17
+
18
+ def request(method, path, **kwargs):
19
+ observed.update({"method": method, "path": path, **kwargs})
20
+ return {"verdict": "ALLOWED", "broker": {"verified": True, "token_consumed": True}}
21
+
22
+ monkeypatch.setattr(client, "_request", request)
23
+ response = client.guardrail_validate(
24
+ text="lookup customer",
25
+ agent_id="support-agent",
26
+ platform="custom_python",
27
+ source_agent_id="support-manager",
28
+ source_platform="microsoft",
29
+ tool_name="crm.lookup",
30
+ tool_args={"id": "123"},
31
+ actor_chain=[
32
+ {"id": "support-manager", "framework": "microsoft"},
33
+ {"id": "support-agent", "framework": "custom_python"},
34
+ ],
35
+ scopes=["crm.customer.read"],
36
+ permissions=["case.status.read"],
37
+ parent_jti="parent-decision",
38
+ root_jti="root-decision",
39
+ policy_id="support-policy",
40
+ policy_version="3",
41
+ policy_hash="sha256:" + "a" * 64,
42
+ proof_thumbprint="proof-thumbprint",
43
+ )
44
+
45
+ assert response["verdict"] == "ALLOWED"
46
+ assert observed["path"] == "/tools/execution/authorize"
47
+ assert observed["json_body"]["boundary_id"].startswith("sdk:")
48
+ assert observed["json_body"]["actor_chain"][1]["id"] == "support-agent"
49
+ assert observed["json_body"]["scopes"] == ["crm.customer.read"]
50
+ assert observed["json_body"]["permissions"] == ["case.status.read"]
51
+ assert observed["json_body"]["parent_jti"] == "parent-decision"
52
+ assert observed["json_body"]["root_jti"] == "root-decision"
53
+ assert observed["json_body"]["policy_id"] == "support-policy"
54
+ assert observed["json_body"]["policy_version"] == "3"
55
+ assert observed["json_body"]["policy_hash"] == "sha256:" + "a" * 64
56
+ assert observed["json_body"]["proof_thumbprint"] == "proof-thumbprint"
57
+ assert observed["json_body"]["policy_context"]["actor_chain"][0]["id"] == "support-manager"
58
+
59
+
60
+ def test_enforced_broker_fails_closed_without_consumed_receipt(monkeypatch):
61
+ client = _client()
62
+ monkeypatch.setattr(client, "_request", lambda *args, **kwargs: {"verdict": "ALLOWED"})
63
+
64
+ try:
65
+ client.guardrail_validate(
66
+ text="lookup customer",
67
+ agent_id="support-agent",
68
+ platform="custom_python",
69
+ tool_name="crm.lookup",
70
+ tool_args={"id": "123"},
71
+ )
72
+ except AgentGuardError as exc:
73
+ assert "atomically consumed" in str(exc)
74
+ else:
75
+ raise AssertionError("missing broker receipt did not fail closed")