# 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