Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 115 additions & 83 deletions POLICY_INDEX.md

Large diffs are not rendered by default.

31 changes: 24 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ static analyzer's policy ruleset. Canonical YAML rules live in
[trustabl/trustabl-rules](https://github.com/trustabl/trustabl-rules) — this
repo links into them and explains the threat model behind each rule.

Coverage spans three agent SDKs:
Coverage spans three agent SDKs plus a protocol-level rule family for the
Model Context Protocol:

- **Claude Agent SDK** (`CSDK-*`) — [claude_sdk/](claude_sdk/)
- **OpenAI Agents SDK** (`OAI-*`) — [openai_sdk/](openai_sdk/)
- **Google ADK** (`ADK-*`) — [google_adk/](google_adk/)
- **Model Context Protocol** (`MCP-*`) — [mcp/](mcp/) (rules ship; rationale docs not yet authored — see [coverage](#current-totals) below)

## What lives here

Expand All @@ -35,12 +37,27 @@ Risk score = `severity_weight × confidence × 100`. Weights: `low=0.15`,

## Current totals

| SDK | Tool | Agent | Subagent | Repo | Total |
| ------------------- | ------ | ------ | -------- | ----- | ------ |
| Claude Agent SDK | 7 | 2 | 1 | 0 | 10 |
| OpenAI Agents SDK | 13 | 6 | 0 | 1 | 20 |
| Google ADK | 8 | 5 | 0 | 0 | 13 |
| **All** | **28** | **13** | **1** | **1** | **43** |
The engine ships **102 rules across 45 files** in
[trustabl-rules](https://github.com/trustabl/trustabl-rules). This rulebook
documents **88 of them across 37 rationale docs** — full rationale coverage of
the three agent SDKs (Claude Agent SDK, OpenAI Agents SDK, Google ADK). The
breakdown below counts **shipped rules per family**; the rightmost column flags
where rationale docs are still missing.

| Family | Tool | Agent | Subagent | Repo | Shipped | Rationale docs |
| ---------------------- | ------ | ------ | -------- | ----- | ------- | -------------- |
| Claude Agent SDK | 17 | 8 | 2 | 3 | 30 | 30 ✓ |
| OpenAI Agents SDK | 21 | 9 | 0 | 2 | 32 | 32 ✓ |
| Google ADK | 14 | 11 | 0 | 1 | 26 | 26 ✓ |
| Model Context Protocol | 14 | 0 | 0 | 0 | 14 | 0 — see gap |
| **All** | **66** | **28** | **2** | **6** | **102** | **88** |

**Coverage gap (honest):** the `mcp/` pack — 14 rules, `MCP-001`–`MCP-014`, all
tool-scope — ships in `trustabl-rules` and now appears in
[POLICY_INDEX.md](POLICY_INDEX.md), but **has no rationale docs yet** (no
`docs/Policy/mcp/` directory). Until those are authored, `tools/check_rulebook.py`
fails on the 14 missing-doc errors. Authoring them (threat models + OWASP
citations) is tracked separately.

Full breakdown: [POLICY_INDEX.md](POLICY_INDEX.md).

Expand Down
57 changes: 33 additions & 24 deletions claude_sdk/POLICY_INDEX.md

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions docs/policy-rationale-doc-template-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ rule's detection scope.
| `claude_sdk/network.yaml` | `docs/Policy/claude_sdk/network.md` |
| `openai_sdk/agent_safety.yaml` | `docs/Policy/openai_sdk/agent_safety.md` |
| `google_adk/tool_definition.yaml` | `docs/Policy/google_adk/tool_definition.md` |
| `mcp/injection.yaml` | `docs/Policy/mcp/injection.md` |
| `mcp/tool_definition.yaml` | `docs/Policy/mcp/tool_definition.md` |

Category subdirectories under `docs/Policy/` mirror the repo root exactly.
If a new category directory is created, create the matching directory in `docs/Policy/`.
Expand Down Expand Up @@ -245,8 +245,8 @@ These docs are the canonical format examples. Read one before writing a new doc.

| Best for | Doc |
|---|---|
| Security rule (Critical) | [Policy/mcp/injection.md](Policy/mcp/injection.md) |
| Security rule (high severity) | [Policy/claude_sdk/code_execution.md](Policy/claude_sdk/code_execution.md) |
| Reliability rule with low confidence | [Policy/claude_sdk/idempotency.md](Policy/claude_sdk/idempotency.md) |
| Cross-framework rule | [Policy/catalog/capability_class.md](Policy/catalog/capability_class.md) |
| Capability-class rule shared across SDKs | [Policy/google_adk/shell_safety.md](Policy/google_adk/shell_safety.md) |
| Agent-scope rule | [Policy/openai_sdk/agent_safety.md](Policy/openai_sdk/agent_safety.md) |
| Cross-reference pattern | [Policy/openai_sdk/tool_definition.md](Policy/openai_sdk/tool_definition.md) |
26 changes: 15 additions & 11 deletions google_adk/POLICY_INDEX.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<!-- Generated by tools/gen_index.py. Do not edit by hand. -->
# Google ADK policy index

22 rules — 11 tool · 10 agent · 1 repo
26 rules — 14 tool · 11 agent · 1 repo

Risk score = `severity_weight × confidence × 100` (engine formula; weights: low=0.15, medium=0.40, high=0.70). Higher = worse.

Expand All @@ -19,13 +19,17 @@ Risk score = `severity_weight × confidence × 100` (engine formula; weights: lo
| 10 | ADK-010 | Google ADK | tool | adk_function_tool | Tool body spawns a subprocess | high | 0.90 | 63.0 | [shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/shell_safety.yaml) |
| 11 | ADK-011 | Google ADK | tool | adk_function_tool | Tool body calls eval/exec/compile on dynamic input | high | 0.90 | 63.0 | [code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/code_execution.yaml) |
| 12 | ADK-012 | Google ADK | tool | adk_function_tool | Tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/ssrf.yaml) |
| 13 | ADK-101 | Google ADK | agent | adk_llm_agent | LlmAgent has no description | medium | 0.85 | 34.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 14 | ADK-102 | Google ADK | agent | adk_llm_agent | Agent with BashTool has no before_tool_callback | high | 0.85 | 59.5 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 15 | ADK-103 | Google ADK | agent | adk_llm_agent | Sub-agent is granted BashTool | high | 0.90 | 63.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 16 | ADK-104 | Google ADK | agent | adk_llm_agent | Agent has no safety_settings | medium | 0.75 | 30.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 17 | ADK-105 | Google ADK | agent | adk_llm_agent | Agent uses web search built-in without before_tool_callback | high | 0.85 | 59.5 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 18 | ADK-106 | Google ADK | agent | adk_llm_agent | Agent has a code_executor but no before_model_callback | high | 0.80 | 56.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 19 | ADK-107 | Google ADK | agent | adk_llm_agent | Agent grants AgentTool but has no before_tool_callback | high | 0.70 | 49.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 20 | ADK-108 | Google ADK | agent | adk_loop_agent | LoopAgent has no max_iterations | medium | 0.70 | 28.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 21 | ADK-110 | Google ADK | agent | adk_llm_agent | Agent fetches web content via UrlContextTool/LoadWebPage without before_tool_callback | medium | 0.70 | 28.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 22 | ADK-201 | Google ADK | repo | google_adk | Google ADK project missing CLAUDE.md | low | 0.90 | 13.5 | [repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/repo_hygiene.yaml) |
| 13 | ADK-013 | Google ADK | tool | adk_function_tool | TypeScript FunctionTool has no description | low | 0.80 | 12.0 | [tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/tool_definition.yaml) |
| 14 | ADK-015 | Google ADK | tool | adk_function_tool | TypeScript FunctionTool body evaluates dynamic code | high | 0.90 | 63.0 | [code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/code_execution.yaml) |
| 15 | ADK-016 | Google ADK | tool | adk_function_tool | TypeScript FunctionTool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/ssrf.yaml) |
| 16 | ADK-101 | Google ADK | agent | adk_llm_agent | LlmAgent has no description | medium | 0.85 | 34.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 17 | ADK-102 | Google ADK | agent | adk_llm_agent | Agent with BashTool has no before_tool_callback | high | 0.85 | 59.5 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 18 | ADK-103 | Google ADK | agent | adk_llm_agent | Sub-agent is granted BashTool | high | 0.90 | 63.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 19 | ADK-104 | Google ADK | agent | adk_llm_agent | Agent has no safety_settings | medium | 0.75 | 30.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 20 | ADK-105 | Google ADK | agent | adk_llm_agent | Agent uses web search built-in without before_tool_callback | high | 0.85 | 59.5 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 21 | ADK-106 | Google ADK | agent | adk_llm_agent | Agent has a code_executor but no before_model_callback | high | 0.80 | 56.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 22 | ADK-107 | Google ADK | agent | adk_llm_agent | Agent grants AgentTool but has no before_tool_callback | high | 0.70 | 49.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 23 | ADK-108 | Google ADK | agent | adk_loop_agent | LoopAgent has no max_iterations | medium | 0.70 | 28.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 24 | ADK-109 | Google ADK | agent | adk_llm_agent | TypeScript LlmAgent has no description | medium | 0.85 | 34.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 25 | ADK-110 | Google ADK | agent | adk_llm_agent | Agent fetches web content via UrlContextTool/LoadWebPage without before_tool_callback | medium | 0.70 | 28.0 | [agent_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/agent_safety.yaml) |
| 26 | ADK-201 | Google ADK | repo | google_adk | Google ADK project ships no agent-guidance doc (AGENTS.md/CLAUDE.md) | low | 0.90 | 13.5 | [repo_hygiene.yaml](https://github.com/trustabl/trustabl-rules/blob/main/google_adk/repo_hygiene.yaml) |
23 changes: 23 additions & 0 deletions mcp/POLICY_INDEX.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- Generated by tools/gen_index.py. Do not edit by hand. -->
# Model Context Protocol policy index

14 rules — 14 tool

Risk score = `severity_weight × confidence × 100` (engine formula; weights: low=0.15, medium=0.40, high=0.70). Higher = worse.

| | Id | SDK/ADK | Scope | Applies To | Policy | Severity | Confidence | Risk | Source |
| -- | ------- | ------- | ----- | ---------- | ---------------------------------------------------------- | -------- | ---------- | ---- | ----------------------------------------------------------------------------------------------------- |
| 1 | MCP-001 | MCP | tool | mcp_tool | Tool has no description | low | 0.90 | 13.5 | [tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) |
| 2 | MCP-002 | MCP | tool | mcp_tool | Tool has no type-annotated parameters | medium | 0.85 | 34.0 | [tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) |
| 3 | MCP-003 | MCP | tool | mcp_tool | Ambiguous tool name | low | 0.85 | 12.8 | [tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) |
| 4 | MCP-004 | MCP | tool | mcp_tool | Network call has no timeout | high | 0.85 | 59.5 | [network.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/network.yaml) |
| 5 | MCP-005 | MCP | tool | mcp_tool | Path parameter used in I/O without validation | high | 0.70 | 49.0 | [path_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/path_safety.yaml) |
| 6 | MCP-006 | MCP | tool | mcp_tool | Tool raises exceptions without a structured error contract | medium | 0.60 | 24.0 | [error_handling.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/error_handling.yaml) |
| 7 | MCP-007 | MCP | tool | mcp_tool | Mutating tool has no idempotency key | medium | 0.55 | 22.0 | [idempotency.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/idempotency.yaml) |
| 8 | MCP-008 | MCP | tool | mcp_tool | Tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/ssrf.yaml) |
| 9 | MCP-009 | MCP | tool | mcp_tool | Tool body calls eval/exec/compile on dynamic input | high | 0.85 | 59.5 | [code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/code_execution.yaml) |
| 10 | MCP-010 | MCP | tool | mcp_tool | Tool body spawns a subprocess | high | 0.70 | 49.0 | [shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/shell_safety.yaml) |
| 11 | MCP-011 | MCP | tool | mcp_tool | TypeScript MCP tool has no description | low | 0.85 | 12.8 | [tool_definition.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/tool_definition.yaml) |
| 12 | MCP-012 | MCP | tool | mcp_tool | TypeScript MCP tool spawns a subprocess | high | 0.70 | 49.0 | [shell_safety.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/shell_safety.yaml) |
| 13 | MCP-013 | MCP | tool | mcp_tool | TypeScript MCP tool fetches a caller-controlled URL (SSRF) | high | 0.60 | 42.0 | [ssrf.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/ssrf.yaml) |
| 14 | MCP-014 | MCP | tool | mcp_tool | TypeScript MCP tool evaluates dynamic code | high | 0.90 | 63.0 | [code_execution.yaml](https://github.com/trustabl/trustabl-rules/blob/main/mcp/code_execution.yaml) |
Loading
Loading