Files
microdao-daarion/docs/tools/governance.md
Apple 67225a39fa docs(platform): add policy configs, runbooks, ops scripts and platform documentation
Config policies (16 files): alert_routing, architecture_pressure, backlog,
cost_weights, data_governance, incident_escalation, incident_intelligence,
network_allowlist, nodes_registry, observability_sources, rbac_tools_matrix,
release_gate, risk_attribution, risk_policy, slo_policy, tool_limits, tools_rollout

Ops (22 files): Caddyfile, calendar compose, grafana voice dashboard,
deployments/incidents logs, runbooks for alerts/audit/backlog/incidents/sofiia/voice,
cron jobs, scripts (alert_triage, audit_cleanup, migrate_*, governance, schedule),
task_registry, voice alerts/ha/latency/policy

Docs (30+ files): HUMANIZED_STEPAN v2.7-v3 changelogs and runbooks,
NODA1/NODA2 status and setup, audit index and traces, backlog, incident,
supervisor, tools, voice, opencode, release, risk, aistalk, spacebot

Made-with: Cursor
2026-03-03 07:14:53 -08:00

278 lines
7.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Tool Governance
**Система керування інструментами DAARION.city**
Версія: 2.0 | Нода: NODE2 (розробка) + NODA1 (production)
---
## Огляд
Tool Governance — єдина система контролю над усіма tool-викликами агентів.
Складається з чотирьох компонентів:
| Компонент | Файл | Що робить |
|-----------|------|-----------|
| **Rollout Policy** | `config/tools_rollout.yml` | Визначає, які tools отримує кожен агент за роллю |
| **RBAC Matrix** | `config/rbac_tools_matrix.yml` | Матриця `tool → action → entitlement → role` |
| **Safety Middleware** | `services/router/tool_governance.py` | Limits, redaction, allowlist, audit |
| **Release Gate** | `ops/task_registry.yml` + `services/router/release_check_runner.py` | Єдиний release verdict |
---
## 1. Global Tools Rollout
### 1.1 Merge Policy
```
effective_tools = unique(DEFAULT_TOOLS_BY_ROLE FULL_STANDARD_STACK agent.specialized_tools)
```
Кожен агент **автоматично** отримує набір tools відповідно до ролі — без необхідності явно вказувати їх.
### 1.2 Конфіг (`config/tools_rollout.yml`)
```yaml
# Групи tools
default_tools_read:
- repo_tool
- kb_tool
- oncall_tool
- observability_tool
...
cto_tools:
- pr_reviewer_tool
- contract_tool
- config_linter_tool
- threatmodel_tool
- job_orchestrator_tool
# Ролі → групи
role_map:
agent_default:
tools: ["@default_tools_read", "@content_tools"]
agent_cto:
tools: ["@default_tools_read", "@cto_tools", "@content_tools", "@media_tools"]
agent_oncall:
tools: ["@default_tools_read", "job_orchestrator_tool"]
# Агент → роль
agent_roles:
sofiia: agent_cto
helion: agent_oncall
alateya: agent_media
```
### 1.3 Ролі
| Роль | Хто | Набір |
|------|-----|-------|
| `agent_cto` | sofiia, yaromir | Все: read + cto + content + media |
| `agent_oncall` | helion | Read + job_orchestrator |
| `agent_media` | alateya, nutra, agromatrix, greenfood... | Read + content + media |
| `agent_default` | всі інші / нові агенти | Read + content |
### 1.4 Розширення груп (`@group`)
`@group_name` у конфігу розгортається рекурсивно. Підтримуються вкладені групи:
```yaml
my_super_group:
- "@cto_tools"
- "@media_tools"
- custom_tool
```
### 1.5 Як перевірити tools агента
```python
from agent_tools_config import get_agent_tools, get_agent_role
tools = get_agent_tools("sofiia") # → список всіх tools
role = get_agent_role("sofiia") # → "agent_cto"
```
**Acceptance**: новий агент без явного `tools` отримує read-набір автоматично.
---
## 2. RBAC Matrix
### 2.1 Структура (`config/rbac_tools_matrix.yml`)
```yaml
tools:
pr_reviewer_tool:
actions:
review:
entitlements: ["tools.pr_review.use"]
gate:
entitlements: ["tools.pr_review.gate"]
role_entitlements:
agent_cto:
- tools.pr_review.use
- tools.pr_review.gate
...
agent_default:
- tools.repo.read
- tools.kb.read
...
```
### 2.2 Enforcement Flow
```
execute_tool(tool, action, agent_id)
→ get_agent_role(agent_id) → "agent_cto"
→ get_role_entitlements(role) → ["tools.pr_review.use", ...]
→ get_required_entitlements(tool, action) → ["tools.pr_review.gate"]
→ missing = required - agent_ents
→ if missing: DENY
```
### 2.3 Entitlement схема
```
tools.<tool_short>.<scope>
Приклади:
tools.repo.read
tools.oncall.incident_write
tools.pr_review.gate
tools.jobs.run.deploy
```
### 2.4 Перевірка вручну
```python
from tool_governance import check_rbac
ok, reason = check_rbac("sofiia", "pr_reviewer_tool", "gate")
# → (True, "")
ok, reason = check_rbac("helion", "pr_reviewer_tool", "gate")
# → (False, "Missing entitlements: ['tools.pr_review.gate']")
```
**Acceptance**: всі tool handlers використовують матрицю — жодного хардкоду прав у коді.
---
## 3. Tool Safety Middleware
Реалізовано у `services/router/tool_governance.py`.
Застосовується автоматично до **кожного** `execute_tool(...)` виклику.
### 3.1 Limits (`config/tool_limits.yml`)
| Параметр | Опис |
|----------|------|
| `timeout_ms` | Максимальний час виконання |
| `max_chars_in` | Максимальна довжина вхідного тексту |
| `max_bytes_out` | Максимальний розмір відповіді |
| `rate_limit_rpm` | Запитів на хвилину |
| `concurrency` | Паралельних викликів |
Приклад:
```yaml
pr_reviewer_tool:
timeout_ms: 60000 # 60s
max_chars_in: 409600 # 400KB
rate_limit_rpm: 10
```
### 3.2 Redaction
Модуль `redact(text)` у `tool_governance.py` маскує:
- API ключі (`api_key=***REDACTED***`)
- Токени (`token=***REDACTED***`)
- Паролі (`password=***REDACTED***`)
- Bearer tokens, JWT, OAuth secrets, private keys
Застосовується до:
- Evidence/snippets у результатах pr_reviewer_tool
- Evidence у config_linter_tool
- Log lines у observability_tool
**Включено за замовчуванням.** Вимкнути: `ToolGovernance(enable_redaction=False)`.
### 3.3 Network Allowlist (`config/network_allowlist.yml`)
Tools, що роблять HTTP-запити, обмежені allowlist:
```python
from tool_governance import check_url_allowed
ok, reason = check_url_allowed("oncall_tool", "http://localhost:9102/health")
# → (True, "")
ok, reason = check_url_allowed("oncall_tool", "http://evil.com/steal")
# → (False, "Host 'evil.com' not in allowlist for tool 'oncall_tool'")
```
`web_extract` та `crawl4ai_scrape` мають `allow_any_public: true` але блокують private IPs (RFC1918/loopback).
### 3.4 Audit Events
На кожен tool-виклик емітується structured event у log:
```json
{
"ts": "2026-02-23T12:00:00Z",
"req_id": "abc123def456",
"tool": "pr_reviewer_tool",
"action": "review",
"workspace_id": "default",
"user_id": "user_123",
"agent_id": "sofiia",
"status": "pass",
"duration_ms": 234.5,
"limits_applied": {"timeout_ms": 60000, "max_chars_in": 409600},
"input_hash": "a1b2c3d4e5f6",
"input_chars": 1024,
"output_size_bytes": 2048
}
```
**Payload не логується** — тільки hash та розміри.
Log prefix: `TOOL_AUDIT`.
### 3.5 Integration у `execute_tool`
```python
# В tool_manager.py, автоматично:
governance = get_governance()
pre = governance.pre_call(tool, action, agent_id, user_id, workspace_id, input_text)
if not pre.allowed:
return ToolResult(success=False, error=pre.reason)
result = await _handler(args) # actual tool execution
governance.post_call(pre.call_ctx, result.result, error=result.error)
```
---
## 4. Налаштування та Hot-Reload
```python
# Force reload конфігів (без перезапуску)
from agent_tools_config import reload_rollout_config
from tool_governance import _reload_yaml_cache
reload_rollout_config()
_reload_yaml_cache()
```
---
## 5. Acceptance Criteria
- ✅ Новий агент без явного `tools` отримує read-набір автоматично
- ✅ Sofiia/CTO має повний набір через роль `agent_cto`
- ✅ Будь-який tool call проходить через middleware (limits/redaction/audit)
- ✅ RBAC денить без entitlement, без хардкоду в коді
- ✅ Allowlist блокує довільні URL для HTTP-tools
- ✅ 31/31 тест проходить