Files
microdao-daarion/docs/tools/data_governance_tool.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

276 lines
9.7 KiB
Markdown
Raw 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.
# data_governance_tool — Data Governance & Privacy
**Категорія:** Security / Privacy / Compliance
**RBAC:** `tools.data_gov.read` (scan_repo, scan_audit, retention_check, policy), `tools.data_gov.gate` (gate)
**Ролі:** `agent_cto` (read + gate), `agent_oncall` (read)
**Timeout:** 30 s
**Rate limit:** 5 rpm
---
## Призначення
`data_governance_tool` — детермінований, read-only сканер для виявлення:
- **PII в коді/доках** (email, телефон, кредитні картки, паспорти)
- **Хардкоджених секретів** (API keys, private keys, токени)
- **Ризиків логування** (sensitive fields у logger calls, raw payload в audit records)
- **Відсутності retention/TTL** при збереженні даних
- **Аномалій в audit-стрімі** (PII у metadata, аномально великі outputs)
- **Наявності cleanup-механізмів** (task_registry.yml, runbooks)
**Перший рівень — warning-only**: gate `privacy_watch` завжди `pass=True`, але генерує конкретні рекомендації.
---
## Actions
### `scan_repo` — статичний аналіз файлів
```json
{
"action": "scan_repo",
"mode": "fast",
"max_files": 200,
"paths_include": ["services/", "config/", "ops/"],
"paths_exclude": ["**/node_modules/**", "**/*.lock"],
"focus": ["pii", "secrets", "logging", "retention"]
}
```
**Режими:**
- `fast` (default): `.py`, `.yml`, `.yaml`, `.json`, `.sh` — оптимізовано для CI
- `full`: всі розширення з `config/data_governance_policy.yml`
**Категорії перевірок:**
| ID | Категорія | Severity | Опис |
|----|-----------|----------|------|
| `DG-PII-001` | pii | warning | Email address |
| `DG-PII-002` | pii | warning | Phone number |
| `DG-PII-003` | pii | **error** | Credit card |
| `DG-PII-004` | pii | warning | Passport-like ID |
| `DG-SEC-000` | secrets | **error** | Secret value (inherited from governance) |
| `DG-SEC-001` | secrets | **error** | Private key block |
| `DG-LOG-001` | logging | warning | Sensitive field in logger call |
| `DG-AUD-001` | logging | **error** | Raw payload near audit/log write |
| `DG-RET-001` | retention | warning | Storage write без TTL/retention |
**Відповідь:**
```json
{
"pass": true,
"summary": "Scanned 87 files (fast mode). Found 0 errors, 3 warnings, 1 info.",
"stats": { "errors": 0, "warnings": 3, "infos": 1, "files_scanned": 87 },
"findings": [
{
"id": "DG-LOG-001",
"category": "logging",
"severity": "warning",
"title": "Potential sensitive field logged in auth.py",
"evidence": { "path": "services/router/auth.py", "lines": "L42-L46", "details": "token=***REDACTED***" },
"recommended_fix": "Apply redact() before logging. Log hash+last4 for identifiers."
}
],
"recommendations": ["Review logger calls for sensitive fields. Apply redact()..."]
}
```
---
### `scan_audit` — аналіз audit-стріму
```json
{
"action": "scan_audit",
"backend": "jsonl",
"time_window_hours": 24,
"max_events": 50000
}
```
**Перевірки:**
| ID | Опис |
|----|------|
| `DG-AUD-101` | PII-like pattern в полях метадата audit event (user_id, workspace_id) |
| `DG-AUD-102` | Аномально великий `out_size` (>64KB за замовчуванням) |
---
### `retention_check` — перевірка cleanup-механізмів
```json
{
"action": "retention_check",
"check_audit_cleanup_task": true,
"check_jsonl_rotation": true,
"check_memory_retention_docs": true,
"check_logs_retention_docs": true
}
```
| ID | Severity | Опис |
|----|----------|------|
| `DG-RET-201` | warning | Не знайдено cleanup task або runbook для audit |
| `DG-RET-202` | info | Cleanup/rotation задокументовано |
| `DG-RET-203` | info | JSONL rotation реалізовано |
| `DG-RET-204` | warning | JSONL rotation не підтверджено |
| `DG-RET-205` | info | Memory retention policy не знайдено |
| `DG-RET-206` | info | Log retention не задокументовано |
---
### `policy` — поточні політики
```json
{ "action": "policy" }
```
Повертає конфіг `config/data_governance_policy.yml`: retention, pii_patterns, logging_rules, severity_behavior.
---
## Evidence masking
**Всі evidence snippets маскуються** перед поверненням:
1. Через `redact()` з `tool_governance` (успадковані `_SECRET_PATTERNS`)
2. Truncate до 200 символів
3. Ніяких raw значень у відповіді
---
## Інтеграція в release_check (privacy_watch gate)
`privacy_watch`**warning-only gate**: завжди `pass=true`, додає рекомендації.
```yaml
# ops/task_registry.yml (release_check inputs)
run_privacy_watch: true # вмикає gate (default: true)
privacy_watch_mode: "fast" # fast|full
privacy_audit_window_hours: 24 # вікно для scan_audit
```
**Gate output:**
```json
{
"name": "privacy_watch",
"status": "pass",
"errors": 0,
"warnings": 2,
"infos": 1,
"top_findings": [
{ "id": "DG-LOG-001", "title": "...", "severity": "warning" }
],
"note": "3 finding(s): 0 error(s), 2 warning(s)",
"recommendations": ["Review logger calls for sensitive fields."]
}
```
Якщо `data_governance_tool` недоступний → `skipped: true`, реліз не блокується.
---
## Конфігурація: `config/data_governance_policy.yml`
```yaml
retention:
audit_jsonl_days: 30
audit_postgres_days: 90
large_output_bytes: 65536 # threshold для DG-AUD-102
pii_patterns:
email: { severity: "warning", ... }
credit_card: { severity: "error", ... }
logging_rules:
forbid_logging_fields: [password, token, secret, api_key, ...]
raw_payload_indicators: [payload, prompt, messages, transcript, ...]
redaction_calls: [redact, mask, sanitize, ...]
severity_behavior:
gate_mode: "warning_only" # або "strict" (блокує на error)
```
---
## RBAC
```yaml
data_governance_tool:
actions:
scan_repo: { entitlements: ["tools.data_gov.read"] }
scan_audit: { entitlements: ["tools.data_gov.read"] }
retention_check: { entitlements: ["tools.data_gov.read"] }
policy: { entitlements: ["tools.data_gov.read"] }
gate: { entitlements: ["tools.data_gov.gate"] }
role_entitlements:
agent_cto: [..., tools.data_gov.read, tools.data_gov.gate]
agent_oncall: [..., tools.data_gov.read]
```
---
## Limits
```yaml
data_governance_tool:
timeout_ms: 30000 # 30s (file I/O + regex)
max_chars_in: 3000 # params only
max_bytes_out: 1MB
rate_limit_rpm: 5
concurrency: 1 # serial (filesystem-bound)
```
---
## Security
- **Read-only**: ніяких записів, змін, видалень
- **Path traversal protection**: всі шляхи перевіряються проти `repo_root`
- **Evidence masking**: `redact()` + truncation — raw secrets ніколи не повертаються
- **Never-scan list**: `.env`, `.pem`, `.key` файли не читаються
- **Lock files excluded** (за замовчуванням): `*.lock` — запобігає false positives від hash-рядків у lock-файлах
---
## Тести
`tests/test_data_governance.py` (22 тести):
| Тест | Перевірка |
|------|-----------|
| `test_scan_repo_detects_pii_logging` | Email у logger call → DG-PII-001 |
| `test_scan_repo_detects_logging_forbidden_field` | `token=` у logger → DG-LOG-001 |
| `test_scan_repo_detects_secret` | Hardcoded API key → DG-SEC-000, masked |
| `test_scan_repo_detects_private_key` | `-----BEGIN RSA PRIVATE KEY-----` → error |
| `test_scan_repo_detects_credit_card` | 16-digit number → DG-PII-003 error |
| `test_scan_repo_no_findings_clean` | Clean code → 0 error findings |
| `test_scan_audit_detects_pii_in_meta` | Email у user_id → DG-AUD-101 |
| `test_scan_audit_detects_large_output` | 200KB out_size → DG-AUD-102 |
| `test_scan_audit_no_findings_for_clean_events` | Normal events → 0 findings |
| `test_retention_check_missing_cleanup` | No runbook → DG-RET-201 |
| `test_retention_check_with_cleanup` | Runbook mentions cleanup → DG-RET-202 |
| `test_scan_repo_raw_payload_audit_write` | `payload` near logger → DG-AUD-001 |
| `test_release_check_privacy_watch_integration` | Gate pass=True, adds recs |
| `test_privacy_watch_skipped_on_tool_error` | Tool exception → skipped=True |
| `test_rbac_deny` | alateya (agent_media) → denied |
| `test_rbac_allow` | sofiia (agent_cto) → allowed |
| `test_policy_action` | Returns structured policy |
| `test_path_traversal_protection` | `../../etc/passwd` → None |
| `test_scan_repo_excludes_lock_files` | `*.lock` excluded |
| `test_mask_evidence_redacts_secrets` | key=value → masked |
| `test_mask_evidence_truncates` | 500 chars → ≤120 |
| `test_unknown_action_returns_error` | Invalid action → error dict |
---
## Наступні кроки
1. **`strict` mode** — увімкнути для `credit_card` + `private_key` (блокувати реліз)
2. **AST-based analysis** — замість regex: точніший аналіз Python AST для logging calls
3. **Git history scan** — перевіряти, чи не були secrets раніше в git history
4. **GDPR retention report** — автоматичний звіт для DPO про час зберігання PII по системах
5. **Integration з incident_triage** — DG findings у RCA якщо є privacy-related incident