""" Defines the Tool Policy Engine. """ from typing import Dict from contracts.common import CallerContext, ToolRiskLevel # This matrix defines the risk level for each known tool. # Tools not in this list will fall back to a default policy. _TOOL_POLICY_MATRIX: Dict[str, ToolRiskLevel] = { # Read Only "get_health": "read_only", "get_build_status": "read_only", "get_state": "read_only", "get_telemetry": "read_only", "list_commits": "read_only", "get_file": "read_only", "list_repo_files": "read_only", "list_open_issues": "read_only", "list_emma_models": "read_only", "run_emma": "read_only", "call_emma": "read_only", # Requires Approval "create_issue": "requires_approval", "push_file": "requires_approval", "create_branch": "requires_approval", "create_commit": "requires_approval", "create_pull_request": "requires_approval", "trigger_build": "requires_approval", "send_email": "requires_approval", "set_billing_budget": "requires_approval", # Requires High Approval "deploy_revision": "requires_high_approval", "merge_pull_request": "requires_high_approval", "IAM-policy change": "requires_high_approval", # Placeholder name "firewall change": "requires_high_approval", # Placeholder name "secret rotation": "requires_high_approval", # Placeholder name "production database migration": "requires_high_approval", # Placeholder "destructive repository action": "requires_high_approval", # Placeholder # Propose Only "run_terminal": "propose_only", "arbitrary gcloud": "propose_only", # Placeholder name "arbitrary curl": "propose_only", # Placeholder name "arbitrary SQL": "propose_only", # Placeholder name # Forbidden "read_secret_value": "forbidden", "token export": "forbidden", "disable security controls": "forbidden", "project deletion": "forbidden", "VPC Service Controls disablement": "forbidden", } class ToolPolicyEngine: """A simple engine to check if a caller can execute a tool.""" def get_access_decision(self, caller: CallerContext, tool_name: str) -> str: """ Determines if a tool call is allowed, requires approval, or is denied. Returns: One of: "allowed_directly", "requires_approval", "requires_high_approval", "propose_only", "denied". """ tool_risk = _TOOL_POLICY_MATRIX.get(tool_name) if not tool_risk or tool_risk == "forbidden": return "denied" caller_permission = caller.allowed_tool_policy.get(tool_risk, caller.allowed_tool_policy.get("default")) if not caller_permission: return "denied" # This logic determines the final decision based on the tool's risk # and the caller's permission for that risk level. if tool_risk == "read_only" and caller_permission == "read_only": return "allowed_directly" if tool_risk == "requires_approval" and caller_permission in ["requires_approval", "requires_high_approval"]: return "requires_approval" if tool_risk == "requires_high_approval" and caller_permission == "requires_high_approval": return "requires_high_approval" if tool_risk == "propose_only" and caller_permission == "propose_only": return "propose_only" return "denied"