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.
- agent_control_plane/__init__.py +662 -0
- agent_control_plane/a2a_adapter.py +543 -0
- agent_control_plane/adapter.py +417 -0
- agent_control_plane/agent_hibernation.py +394 -0
- agent_control_plane/agent_kernel.py +470 -0
- agent_control_plane/compliance.py +720 -0
- agent_control_plane/constraint_graphs.py +478 -0
- agent_control_plane/control_plane.py +854 -0
- agent_control_plane/example_executors.py +195 -0
- agent_control_plane/execution_engine.py +231 -0
- agent_control_plane/flight_recorder.py +846 -0
- agent_control_plane/governance_layer.py +435 -0
- agent_control_plane/hf_utils.py +563 -0
- agent_control_plane/interfaces/__init__.py +55 -0
- agent_control_plane/interfaces/kernel_interface.py +361 -0
- agent_control_plane/interfaces/plugin_interface.py +497 -0
- agent_control_plane/interfaces/protocol_interfaces.py +387 -0
- agent_control_plane/kernel_space.py +1009 -0
- agent_control_plane/langchain_adapter.py +424 -0
- agent_control_plane/lifecycle.py +3113 -0
- agent_control_plane/mcp_adapter.py +653 -0
- agent_control_plane/ml_safety.py +563 -0
- agent_control_plane/multimodal.py +727 -0
- agent_control_plane/mute_agent.py +422 -0
- agent_control_plane/observability.py +787 -0
- agent_control_plane/orchestrator.py +482 -0
- agent_control_plane/plugin_registry.py +750 -0
- agent_control_plane/policy_engine.py +954 -0
- agent_control_plane/process_isolation.py +777 -0
- agent_control_plane/shadow_mode.py +310 -0
- agent_control_plane/signals.py +493 -0
- agent_control_plane/supervisor_agents.py +430 -0
- agent_control_plane/time_travel_debugger.py +557 -0
- agent_control_plane/tool_registry.py +452 -0
- agent_control_plane/vfs.py +697 -0
- agent_kernel/__init__.py +69 -0
- agent_kernel/analyzer.py +435 -0
- agent_kernel/auditor.py +36 -0
- agent_kernel/completeness_auditor.py +237 -0
- agent_kernel/detector.py +203 -0
- agent_kernel/kernel.py +744 -0
- agent_kernel/memory_manager.py +85 -0
- agent_kernel/models.py +374 -0
- agent_kernel/nudge_mechanism.py +263 -0
- agent_kernel/outcome_analyzer.py +338 -0
- agent_kernel/patcher.py +582 -0
- agent_kernel/semantic_analyzer.py +316 -0
- agent_kernel/semantic_purge.py +349 -0
- agent_kernel/simulator.py +449 -0
- agent_kernel/teacher.py +85 -0
- agent_kernel/triage.py +152 -0
- agent_os/__init__.py +409 -0
- agent_os/_adversarial_impl.py +200 -0
- agent_os/_circuit_breaker_impl.py +232 -0
- agent_os/_mcp_metrics.py +193 -0
- agent_os/adversarial.py +20 -0
- agent_os/agents_compat.py +490 -0
- agent_os/audit_logger.py +135 -0
- agent_os/base_agent.py +651 -0
- agent_os/circuit_breaker.py +34 -0
- agent_os/cli/__init__.py +659 -0
- agent_os/cli/cmd_audit.py +128 -0
- agent_os/cli/cmd_init.py +152 -0
- agent_os/cli/cmd_policy.py +41 -0
- agent_os/cli/cmd_policy_gen.py +180 -0
- agent_os/cli/cmd_validate.py +258 -0
- agent_os/cli/mcp_scan.py +265 -0
- agent_os/cli/output.py +192 -0
- agent_os/cli/policy_checker.py +330 -0
- agent_os/compat.py +74 -0
- agent_os/constraint_graph.py +234 -0
- agent_os/content_governance.py +140 -0
- agent_os/context_budget.py +305 -0
- agent_os/credential_redactor.py +224 -0
- agent_os/diff_policy.py +89 -0
- agent_os/egress_policy.py +159 -0
- agent_os/escalation.py +276 -0
- agent_os/event_bus.py +124 -0
- agent_os/exceptions.py +180 -0
- agent_os/execution_context_policy.py +141 -0
- agent_os/github_enterprise.py +96 -0
- agent_os/health.py +20 -0
- agent_os/integrations/__init__.py +279 -0
- agent_os/integrations/a2a_adapter.py +279 -0
- agent_os/integrations/agent_lightning/__init__.py +30 -0
- agent_os/integrations/anthropic_adapter.py +420 -0
- agent_os/integrations/autogen_adapter.py +620 -0
- agent_os/integrations/base.py +1137 -0
- agent_os/integrations/compat.py +229 -0
- agent_os/integrations/config.py +98 -0
- agent_os/integrations/conversation_guardian.py +957 -0
- agent_os/integrations/crewai_adapter.py +467 -0
- agent_os/integrations/drift_detector.py +425 -0
- agent_os/integrations/dry_run.py +124 -0
- agent_os/integrations/escalation.py +582 -0
- agent_os/integrations/gemini_adapter.py +364 -0
- agent_os/integrations/google_adk_adapter.py +633 -0
- agent_os/integrations/guardrails_adapter.py +394 -0
- agent_os/integrations/health.py +197 -0
- agent_os/integrations/langchain_adapter.py +654 -0
- agent_os/integrations/llamafirewall.py +343 -0
- agent_os/integrations/llamaindex_adapter.py +188 -0
- agent_os/integrations/logging.py +191 -0
- agent_os/integrations/maf_adapter.py +631 -0
- agent_os/integrations/mistral_adapter.py +365 -0
- agent_os/integrations/openai_adapter.py +816 -0
- agent_os/integrations/openai_agents_sdk.py +406 -0
- agent_os/integrations/policy_compose.py +171 -0
- agent_os/integrations/profiling.py +144 -0
- agent_os/integrations/pydantic_ai_adapter.py +420 -0
- agent_os/integrations/rate_limiter.py +130 -0
- agent_os/integrations/rbac.py +143 -0
- agent_os/integrations/registry.py +113 -0
- agent_os/integrations/scope_guard.py +303 -0
- agent_os/integrations/semantic_kernel_adapter.py +769 -0
- agent_os/integrations/smolagents_adapter.py +629 -0
- agent_os/integrations/templates.py +178 -0
- agent_os/integrations/token_budget.py +134 -0
- agent_os/integrations/tool_aliases.py +190 -0
- agent_os/integrations/webhooks.py +177 -0
- agent_os/lite.py +208 -0
- agent_os/mcp_gateway.py +385 -0
- agent_os/mcp_message_signer.py +273 -0
- agent_os/mcp_protocols.py +161 -0
- agent_os/mcp_response_scanner.py +232 -0
- agent_os/mcp_security.py +924 -0
- agent_os/mcp_session_auth.py +231 -0
- agent_os/mcp_sliding_rate_limiter.py +184 -0
- agent_os/memory_guard.py +409 -0
- agent_os/metrics.py +134 -0
- agent_os/mute.py +428 -0
- agent_os/mute_agent.py +209 -0
- agent_os/policies/__init__.py +77 -0
- agent_os/policies/async_evaluator.py +275 -0
- agent_os/policies/backends.py +670 -0
- agent_os/policies/bridge.py +169 -0
- agent_os/policies/budget.py +85 -0
- agent_os/policies/cli.py +294 -0
- agent_os/policies/conflict_resolution.py +270 -0
- agent_os/policies/data_classification.py +252 -0
- agent_os/policies/evaluator.py +239 -0
- agent_os/policies/policy_schema.json +228 -0
- agent_os/policies/rate_limiting.py +145 -0
- agent_os/policies/schema.py +115 -0
- agent_os/policies/shared.py +331 -0
- agent_os/prompt_injection.py +694 -0
- agent_os/providers.py +182 -0
- agent_os/py.typed +0 -0
- agent_os/retry.py +81 -0
- agent_os/reversibility.py +251 -0
- agent_os/sandbox.py +432 -0
- agent_os/sandbox_provider.py +140 -0
- agent_os/secure_codegen.py +525 -0
- agent_os/security_skills.py +538 -0
- agent_os/semantic_policy.py +422 -0
- agent_os/server/__init__.py +15 -0
- agent_os/server/__main__.py +25 -0
- agent_os/server/app.py +277 -0
- agent_os/server/models.py +104 -0
- agent_os/shift_left_metrics.py +130 -0
- agent_os/stateless.py +742 -0
- agent_os/supervisor.py +148 -0
- agent_os/task_outcome.py +148 -0
- agent_os/transparency.py +181 -0
- agent_os/trust_root.py +128 -0
- agent_os_kernel-3.1.0.dist-info/METADATA +1269 -0
- agent_os_kernel-3.1.0.dist-info/RECORD +337 -0
- agent_os_kernel-3.1.0.dist-info/WHEEL +4 -0
- agent_os_kernel-3.1.0.dist-info/entry_points.txt +2 -0
- agent_os_kernel-3.1.0.dist-info/licenses/LICENSE +21 -0
- agent_os_observability/__init__.py +27 -0
- agent_os_observability/dashboards.py +898 -0
- agent_os_observability/metrics.py +398 -0
- agent_os_observability/server.py +223 -0
- agent_os_observability/tracer.py +232 -0
- agent_primitives/__init__.py +24 -0
- agent_primitives/failures.py +84 -0
- agent_primitives/py.typed +0 -0
- amb_core/__init__.py +177 -0
- amb_core/adapters/__init__.py +57 -0
- amb_core/adapters/aws_sqs_broker.py +376 -0
- amb_core/adapters/azure_servicebus_broker.py +340 -0
- amb_core/adapters/kafka_broker.py +260 -0
- amb_core/adapters/nats_broker.py +285 -0
- amb_core/adapters/rabbitmq_broker.py +235 -0
- amb_core/adapters/redis_broker.py +262 -0
- amb_core/broker.py +145 -0
- amb_core/bus.py +481 -0
- amb_core/cloudevents.py +509 -0
- amb_core/dlq.py +345 -0
- amb_core/hf_utils.py +536 -0
- amb_core/memory_broker.py +410 -0
- amb_core/models.py +141 -0
- amb_core/persistence.py +529 -0
- amb_core/schema.py +294 -0
- amb_core/tracing.py +358 -0
- atr/__init__.py +640 -0
- atr/access.py +348 -0
- atr/composition.py +645 -0
- atr/decorator.py +357 -0
- atr/executor.py +384 -0
- atr/health.py +557 -0
- atr/hf_utils.py +449 -0
- atr/injection.py +422 -0
- atr/metrics.py +440 -0
- atr/policies.py +403 -0
- atr/py.typed +2 -0
- atr/registry.py +452 -0
- atr/schema.py +480 -0
- atr/tools/safe/__init__.py +75 -0
- atr/tools/safe/calculator.py +467 -0
- atr/tools/safe/datetime_tool.py +443 -0
- atr/tools/safe/file_reader.py +402 -0
- atr/tools/safe/http_client.py +316 -0
- atr/tools/safe/json_parser.py +374 -0
- atr/tools/safe/text_tool.py +537 -0
- atr/tools/safe/toolkit.py +175 -0
- caas/__init__.py +162 -0
- caas/api/__init__.py +7 -0
- caas/api/server.py +1328 -0
- caas/caching.py +834 -0
- caas/cli.py +210 -0
- caas/conversation.py +223 -0
- caas/decay.py +72 -0
- caas/detection/__init__.py +9 -0
- caas/detection/detector.py +238 -0
- caas/enrichment.py +130 -0
- caas/gateway/__init__.py +27 -0
- caas/gateway/trust_gateway.py +474 -0
- caas/hf_utils.py +479 -0
- caas/ingestion/__init__.py +23 -0
- caas/ingestion/processors.py +253 -0
- caas/ingestion/structure_parser.py +188 -0
- caas/models.py +356 -0
- caas/pragmatic_truth.py +444 -0
- caas/routing/__init__.py +10 -0
- caas/routing/heuristic_router.py +58 -0
- caas/storage/__init__.py +9 -0
- caas/storage/store.py +389 -0
- caas/triad.py +213 -0
- caas/tuning/__init__.py +9 -0
- caas/tuning/tuner.py +329 -0
- caas/vfs/__init__.py +14 -0
- caas/vfs/filesystem.py +452 -0
- cmvk/__init__.py +218 -0
- cmvk/audit.py +402 -0
- cmvk/benchmarks.py +478 -0
- cmvk/constitutional.py +904 -0
- cmvk/hf_utils.py +301 -0
- cmvk/metrics.py +473 -0
- cmvk/profiles.py +300 -0
- cmvk/py.typed +0 -0
- cmvk/types.py +12 -0
- cmvk/verification.py +956 -0
- emk/__init__.py +89 -0
- emk/causal.py +352 -0
- emk/hf_utils.py +421 -0
- emk/indexer.py +83 -0
- emk/py.typed +0 -0
- emk/schema.py +204 -0
- emk/sleep_cycle.py +347 -0
- emk/store.py +281 -0
- iatp/__init__.py +166 -0
- iatp/attestation.py +461 -0
- iatp/cli.py +317 -0
- iatp/hf_utils.py +472 -0
- iatp/ipc_pipes.py +580 -0
- iatp/main.py +412 -0
- iatp/models/__init__.py +447 -0
- iatp/policy_engine.py +337 -0
- iatp/py.typed +2 -0
- iatp/recovery.py +321 -0
- iatp/security/__init__.py +270 -0
- iatp/sidecar/__init__.py +519 -0
- iatp/telemetry/__init__.py +164 -0
- iatp/tests/__init__.py +1 -0
- iatp/tests/test_attestation.py +370 -0
- iatp/tests/test_cli.py +131 -0
- iatp/tests/test_ed25519_attestation.py +211 -0
- iatp/tests/test_models.py +130 -0
- iatp/tests/test_policy_engine.py +347 -0
- iatp/tests/test_recovery.py +281 -0
- iatp/tests/test_security.py +222 -0
- iatp/tests/test_sidecar.py +167 -0
- iatp/tests/test_telemetry.py +175 -0
- mcp_kernel_server/__init__.py +28 -0
- mcp_kernel_server/cli.py +274 -0
- mcp_kernel_server/resources.py +217 -0
- mcp_kernel_server/server.py +564 -0
- mcp_kernel_server/tools.py +1174 -0
- mute_agent/__init__.py +68 -0
- mute_agent/core/__init__.py +1 -0
- mute_agent/core/execution_agent.py +166 -0
- mute_agent/core/handshake_protocol.py +201 -0
- mute_agent/core/reasoning_agent.py +238 -0
- mute_agent/knowledge_graph/__init__.py +1 -0
- mute_agent/knowledge_graph/graph_elements.py +65 -0
- mute_agent/knowledge_graph/multidimensional_graph.py +170 -0
- mute_agent/knowledge_graph/subgraph.py +224 -0
- mute_agent/listener/__init__.py +43 -0
- mute_agent/listener/adapters/__init__.py +31 -0
- mute_agent/listener/adapters/base_adapter.py +189 -0
- mute_agent/listener/adapters/caas_adapter.py +344 -0
- mute_agent/listener/adapters/control_plane_adapter.py +436 -0
- mute_agent/listener/adapters/iatp_adapter.py +332 -0
- mute_agent/listener/adapters/scak_adapter.py +251 -0
- mute_agent/listener/listener.py +610 -0
- mute_agent/listener/state_observer.py +436 -0
- mute_agent/listener/threshold_config.py +313 -0
- mute_agent/super_system/__init__.py +1 -0
- mute_agent/super_system/router.py +204 -0
- mute_agent/visualization/__init__.py +10 -0
- mute_agent/visualization/graph_debugger.py +502 -0
- nexus/README.md +60 -0
- nexus/__init__.py +51 -0
- nexus/arbiter.py +359 -0
- nexus/client.py +466 -0
- nexus/dmz.py +444 -0
- nexus/escrow.py +430 -0
- nexus/exceptions.py +286 -0
- nexus/pyproject.toml +36 -0
- nexus/registry.py +393 -0
- nexus/reputation.py +425 -0
- nexus/schemas/__init__.py +51 -0
- nexus/schemas/compliance.py +276 -0
- nexus/schemas/escrow.py +251 -0
- nexus/schemas/manifest.py +225 -0
- nexus/schemas/receipt.py +208 -0
- nexus/tests/__init__.py +0 -0
- nexus/tests/conftest.py +146 -0
- nexus/tests/test_arbiter.py +192 -0
- nexus/tests/test_dmz.py +194 -0
- nexus/tests/test_escrow.py +276 -0
- nexus/tests/test_exceptions.py +225 -0
- nexus/tests/test_registry.py +232 -0
- nexus/tests/test_reputation.py +328 -0
- nexus/tests/test_schemas.py +295 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# Copyright (c) Microsoft Corporation.
|
|
2
|
+
# Licensed under the MIT License.
|
|
3
|
+
"""
|
|
4
|
+
Security and privacy validation logic.
|
|
5
|
+
"""
|
|
6
|
+
import re
|
|
7
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
8
|
+
|
|
9
|
+
from iatp.attestation import AttestationValidator
|
|
10
|
+
from iatp.models import (
|
|
11
|
+
AttestationRecord,
|
|
12
|
+
CapabilityManifest,
|
|
13
|
+
RetentionPolicy,
|
|
14
|
+
ReversibilityLevel,
|
|
15
|
+
TrustLevel,
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _luhn_check(card_number: str) -> bool:
|
|
20
|
+
"""
|
|
21
|
+
Validate a credit card number using the Luhn algorithm.
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
card_number: String of digits (spaces/dashes already removed)
|
|
25
|
+
|
|
26
|
+
Returns:
|
|
27
|
+
bool: True if valid according to Luhn algorithm
|
|
28
|
+
"""
|
|
29
|
+
if not card_number.isdigit() or len(card_number) < 13:
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
# Luhn algorithm
|
|
33
|
+
digits = [int(d) for d in card_number]
|
|
34
|
+
checksum = 0
|
|
35
|
+
|
|
36
|
+
# Double every second digit from right to left
|
|
37
|
+
for i in range(len(digits) - 2, -1, -2):
|
|
38
|
+
doubled = digits[i] * 2
|
|
39
|
+
checksum += doubled if doubled < 10 else doubled - 9
|
|
40
|
+
|
|
41
|
+
# Add remaining digits
|
|
42
|
+
for i in range(len(digits) - 1, -1, -2):
|
|
43
|
+
checksum += digits[i]
|
|
44
|
+
|
|
45
|
+
return checksum % 10 == 0
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class SecurityValidator:
|
|
49
|
+
"""Validates requests against capability manifests and security policies."""
|
|
50
|
+
|
|
51
|
+
# Patterns for detecting sensitive data
|
|
52
|
+
CREDIT_CARD_PATTERN = re.compile(r'\b\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}\b')
|
|
53
|
+
SSN_PATTERN = re.compile(r'\b\d{3}-\d{2}-\d{4}\b')
|
|
54
|
+
EMAIL_PATTERN = re.compile(r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b')
|
|
55
|
+
|
|
56
|
+
def __init__(self):
|
|
57
|
+
self.blocked_requests = []
|
|
58
|
+
self.warnings = []
|
|
59
|
+
self.attestation_validator = AttestationValidator()
|
|
60
|
+
|
|
61
|
+
def validate_attestation(
|
|
62
|
+
self,
|
|
63
|
+
attestation: AttestationRecord,
|
|
64
|
+
verify_signature: bool = True
|
|
65
|
+
) -> Tuple[bool, Optional[str]]:
|
|
66
|
+
"""
|
|
67
|
+
Validate an agent attestation record.
|
|
68
|
+
|
|
69
|
+
This ensures the agent is running verified code and not a hacked version.
|
|
70
|
+
|
|
71
|
+
Args:
|
|
72
|
+
attestation: The attestation record from the agent
|
|
73
|
+
verify_signature: Whether to verify cryptographic signature
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
Tuple of (is_valid, error_message)
|
|
77
|
+
"""
|
|
78
|
+
return self.attestation_validator.validate_attestation(
|
|
79
|
+
attestation, verify_signature=verify_signature
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
def detect_sensitive_data(self, payload: Dict[str, Any]) -> List[str]:
|
|
83
|
+
"""
|
|
84
|
+
Detect sensitive data in the request payload.
|
|
85
|
+
Uses Luhn algorithm to validate credit card numbers.
|
|
86
|
+
Returns a list of detected sensitive data types.
|
|
87
|
+
"""
|
|
88
|
+
sensitive_types = []
|
|
89
|
+
payload_str = str(payload)
|
|
90
|
+
|
|
91
|
+
# Check for credit cards with Luhn validation
|
|
92
|
+
card_matches = self.CREDIT_CARD_PATTERN.finditer(payload_str)
|
|
93
|
+
for match in card_matches:
|
|
94
|
+
card_number = match.group().replace(' ', '').replace('-', '')
|
|
95
|
+
if _luhn_check(card_number):
|
|
96
|
+
sensitive_types.append("credit_card")
|
|
97
|
+
break # Only need to detect once
|
|
98
|
+
|
|
99
|
+
if self.SSN_PATTERN.search(payload_str):
|
|
100
|
+
sensitive_types.append("ssn")
|
|
101
|
+
# Email is less sensitive but still PII
|
|
102
|
+
if self.EMAIL_PATTERN.search(payload_str):
|
|
103
|
+
sensitive_types.append("email")
|
|
104
|
+
|
|
105
|
+
return sensitive_types
|
|
106
|
+
|
|
107
|
+
def validate_privacy_policy(
|
|
108
|
+
self,
|
|
109
|
+
manifest: CapabilityManifest,
|
|
110
|
+
payload: Dict[str, Any]
|
|
111
|
+
) -> Tuple[bool, Optional[str]]:
|
|
112
|
+
"""
|
|
113
|
+
Validate that the request complies with privacy policies.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
Tuple of (is_valid, error_message)
|
|
117
|
+
is_valid: True if request should be allowed
|
|
118
|
+
error_message: Description of the violation if blocked
|
|
119
|
+
"""
|
|
120
|
+
sensitive_data = self.detect_sensitive_data(payload)
|
|
121
|
+
|
|
122
|
+
# Check for credit card data with permanent retention
|
|
123
|
+
if "credit_card" in sensitive_data and manifest.privacy_contract.retention in [
|
|
124
|
+
RetentionPolicy.PERMANENT,
|
|
125
|
+
RetentionPolicy.FOREVER
|
|
126
|
+
]:
|
|
127
|
+
return False, (
|
|
128
|
+
f"Privacy Violation: Agent '{manifest.agent_id}' stores data "
|
|
129
|
+
f"permanently and request contains credit card information. "
|
|
130
|
+
f"Request blocked for security."
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
# Check for SSN with any non-ephemeral retention
|
|
134
|
+
if "ssn" in sensitive_data:
|
|
135
|
+
if manifest.privacy_contract.retention != RetentionPolicy.EPHEMERAL:
|
|
136
|
+
return False, (
|
|
137
|
+
f"Privacy Violation: Agent '{manifest.agent_id}' retains data "
|
|
138
|
+
f"beyond session lifetime and request contains SSN. "
|
|
139
|
+
f"Request blocked for security."
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
return True, None
|
|
143
|
+
|
|
144
|
+
def generate_warning_message(
|
|
145
|
+
self,
|
|
146
|
+
manifest: CapabilityManifest,
|
|
147
|
+
payload: Dict[str, Any]
|
|
148
|
+
) -> Optional[str]:
|
|
149
|
+
"""
|
|
150
|
+
Generate a warning message for risky requests that aren't blocked.
|
|
151
|
+
Returns None if no warnings are needed.
|
|
152
|
+
"""
|
|
153
|
+
warnings = []
|
|
154
|
+
trust_score = manifest.calculate_trust_score()
|
|
155
|
+
|
|
156
|
+
# Low trust score warning
|
|
157
|
+
if trust_score < 5:
|
|
158
|
+
warnings.append(
|
|
159
|
+
f"Low trust score ({trust_score}/10) for agent '{manifest.agent_id}'"
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# No reversibility warning
|
|
163
|
+
if manifest.capabilities.reversibility == ReversibilityLevel.NONE:
|
|
164
|
+
warnings.append(
|
|
165
|
+
f"Agent '{manifest.agent_id}' does not support transaction reversal"
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
# No idempotency warning
|
|
169
|
+
if not manifest.capabilities.idempotency:
|
|
170
|
+
warnings.append(
|
|
171
|
+
f"Agent '{manifest.agent_id}' may not handle duplicate requests safely"
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
# Data retention warning
|
|
175
|
+
if manifest.privacy_contract.retention in [
|
|
176
|
+
RetentionPolicy.PERMANENT,
|
|
177
|
+
RetentionPolicy.FOREVER
|
|
178
|
+
]:
|
|
179
|
+
warnings.append(
|
|
180
|
+
f"Agent '{manifest.agent_id}' stores data indefinitely"
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
# Human review warning
|
|
184
|
+
if manifest.privacy_contract.human_review:
|
|
185
|
+
warnings.append(
|
|
186
|
+
f"Agent '{manifest.agent_id}' may have humans review your data"
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
if warnings:
|
|
190
|
+
return "⚠️ WARNING:\n" + "\n".join(f" • {w}" for w in warnings)
|
|
191
|
+
|
|
192
|
+
return None
|
|
193
|
+
|
|
194
|
+
def should_quarantine(self, manifest: CapabilityManifest) -> bool:
|
|
195
|
+
"""
|
|
196
|
+
Determine if requests to this agent should be quarantined.
|
|
197
|
+
"""
|
|
198
|
+
trust_score = manifest.calculate_trust_score()
|
|
199
|
+
|
|
200
|
+
# Quarantine if:
|
|
201
|
+
# - Trust score is very low
|
|
202
|
+
# - No reversibility and permanent storage
|
|
203
|
+
# - Untrusted agent
|
|
204
|
+
|
|
205
|
+
if trust_score < 3:
|
|
206
|
+
return True
|
|
207
|
+
|
|
208
|
+
if (manifest.capabilities.reversibility == ReversibilityLevel.NONE and
|
|
209
|
+
manifest.privacy_contract.retention in [
|
|
210
|
+
RetentionPolicy.PERMANENT,
|
|
211
|
+
RetentionPolicy.FOREVER
|
|
212
|
+
]):
|
|
213
|
+
return True
|
|
214
|
+
|
|
215
|
+
return manifest.trust_level == TrustLevel.UNTRUSTED
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
class PrivacyScrubber:
|
|
219
|
+
"""Scrubs sensitive data from payloads before logging."""
|
|
220
|
+
|
|
221
|
+
@staticmethod
|
|
222
|
+
def scrub_payload(payload: Dict[str, Any]) -> Dict[str, Any]:
|
|
223
|
+
"""
|
|
224
|
+
Create a scrubbed copy of the payload for logging.
|
|
225
|
+
Redacts sensitive information.
|
|
226
|
+
"""
|
|
227
|
+
scrubbed = payload.copy()
|
|
228
|
+
|
|
229
|
+
# Convert to string for pattern matching
|
|
230
|
+
payload_str = str(payload)
|
|
231
|
+
|
|
232
|
+
# Redact credit cards
|
|
233
|
+
if SecurityValidator.CREDIT_CARD_PATTERN.search(payload_str):
|
|
234
|
+
scrubbed = PrivacyScrubber._redact_in_dict(
|
|
235
|
+
scrubbed,
|
|
236
|
+
SecurityValidator.CREDIT_CARD_PATTERN,
|
|
237
|
+
"[CREDIT_CARD_REDACTED]"
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
# Redact SSN
|
|
241
|
+
if SecurityValidator.SSN_PATTERN.search(payload_str):
|
|
242
|
+
scrubbed = PrivacyScrubber._redact_in_dict(
|
|
243
|
+
scrubbed,
|
|
244
|
+
SecurityValidator.SSN_PATTERN,
|
|
245
|
+
"[SSN_REDACTED]"
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
return scrubbed
|
|
249
|
+
|
|
250
|
+
@staticmethod
|
|
251
|
+
def _redact_in_dict(
|
|
252
|
+
data: Any,
|
|
253
|
+
pattern: re.Pattern,
|
|
254
|
+
replacement: str
|
|
255
|
+
) -> Any:
|
|
256
|
+
"""Recursively redact patterns in dictionary."""
|
|
257
|
+
if isinstance(data, dict):
|
|
258
|
+
return {
|
|
259
|
+
k: PrivacyScrubber._redact_in_dict(v, pattern, replacement)
|
|
260
|
+
for k, v in data.items()
|
|
261
|
+
}
|
|
262
|
+
elif isinstance(data, list):
|
|
263
|
+
return [
|
|
264
|
+
PrivacyScrubber._redact_in_dict(item, pattern, replacement)
|
|
265
|
+
for item in data
|
|
266
|
+
]
|
|
267
|
+
elif isinstance(data, str):
|
|
268
|
+
return pattern.sub(replacement, data)
|
|
269
|
+
else:
|
|
270
|
+
return data
|