Files
awoooi/scripts/security/high-value-config-control-coverage.py
Your Name a1bce80842
Some checks failed
CD Pipeline / build-and-deploy (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled
Code Review / ai-code-review (push) Has been cancelled
CD Pipeline / tests (push) Has been cancelled
feat(iwooos): 整合 SOC SIEM Kali Wazuh 控制
2026-06-18 12:04:06 +08:00

540 lines
36 KiB
Python
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.
#!/usr/bin/env python3
"""
IwoooS 高價值配置控管覆蓋矩陣。
本工具讀取 high-value-config-change-gate.py 的 CATEGORIES 定義,產生一份
全域配置控管覆蓋 snapshot。它只整理 source-of-truth、owner gate、
evidence refs、缺口與 0/false 邊界,不讀 live host、不連外、不執行
Nginx / DNS / K8s / workflow / agent runtime 動作。
"""
from __future__ import annotations
import argparse
import json
import runpy
import subprocess
import sys
from datetime import datetime, timedelta, timezone
from pathlib import Path
from typing import Any
TAIPEI = timezone(timedelta(hours=8))
CONTROL_STATUS_BY_CATEGORY = {
"nginx_public_gateway": {
"coverage_status": "post_incident_readback_plan_ready_needs_public_gateway_owner_evidence",
"coverage_percent": 92,
"evidence_refs": [
"docs/security/NGINX-CONFIG-DRIFT-DETECTOR.md",
"docs/security/nginx-config-drift-repo.snapshot.json",
"docs/security/DOMAIN-TLS-CERTBOT-INVENTORY.md",
"docs/security/PUBLIC-GATEWAY-PREFLIGHT-INVENTORY.md",
"docs/security/public-gateway-preflight-inventory.snapshot.json",
"docs/security/PUBLIC-GATEWAY-OWNER-RESPONSE-ACCEPTANCE.md",
"docs/security/public-gateway-owner-response-acceptance.snapshot.json",
"docs/security/PUBLIC-GATEWAY-RENDERED-DIFF-ACCEPTANCE.md",
"docs/security/public-gateway-rendered-diff-acceptance.snapshot.json",
"docs/security/PUBLIC-GATEWAY-POST-INCIDENT-READBACK-PLAN.md",
"docs/security/public-gateway-post-incident-readback-plan.snapshot.json",
"docs/schemas/public_gateway_preflight_inventory_v1.schema.json",
],
"current_gap": "已固定 owner response acceptance、手動 / 緊急 gateway 變更回補欄位、rendered diff evidence acceptance 與 post-incident readback plan 只讀帳本actor、時間窗、改前改後 route、source-to-live diff、nginx -t readback、reload / no-reload、route smoke、TLS / ACME、WebSocket、upstream、AI provider、monitoring、跨專案同步、防再發與 no-false-green 已納入owner response、live conf、rendered diff evidence、nginx -t evidence、route smoke evidence、事故回讀包、maintenance window 與 rollback owner 仍全部為 0。",
"next_owner_action": "補 Public Gateway / Nginx 事故回讀包owner 回覆、owner-provided live conf、source-to-live rendered diff ref、nginx -t evidence ref、route smoke evidence ref、change intent / break-glass、actor role / team、變更時間窗、改前改後 route state、upstream / WebSocket / TLS / ACME 影響、AI provider / monitoring 影響、跨專案同步、route health impact、rollback validation、post-change monitoring、recurrence guard、maintenance window 與 rollback owner。",
},
"dns_tls_certbot": {
"coverage_status": "owner_response_acceptance_ledger_ready_needs_certificate_owner_evidence",
"coverage_percent": 78,
"evidence_refs": [
"docs/security/DOMAIN-TLS-CERTBOT-INVENTORY.md",
"docs/security/domain-tls-certbot-inventory.snapshot.json",
"docs/security/DOMAIN-TLS-CERTBOT-OWNER-CONFIRMATION-REQUEST.md",
"docs/security/domain-tls-certbot-owner-confirmation-request.snapshot.json",
"docs/security/DOMAIN-TLS-CERTBOT-OWNER-RESPONSE-ACCEPTANCE.md",
"docs/security/domain-tls-certbot-owner-response-acceptance.snapshot.json",
],
"current_gap": "已固定 4 份 DNS / TLS / certbot owner response acceptance candidate仍缺 owner response、certificate coverage metadata ref、expiry metadata ref、renewal owner、ACME route owner、maintenance window、rollback owner 與 validation plan。",
"next_owner_action": "補 SAN / wildcard / 共用憑證覆蓋依據 ref、到期 metadata ref、renewal owner、ACME route owner、維護窗口、rollback owner 與 validation plan。",
},
"k8s_production_gitops": {
"coverage_status": "post_incident_readback_plan_ready_needs_gitops_owner_evidence",
"coverage_percent": 66,
"evidence_refs": [
"docs/security/HIGH-VALUE-CONFIG-CHANGE-GATE.md",
"docs/security/K8S-ARGOCD-MANIFEST-INVENTORY.md",
"docs/security/k8s-argocd-manifest-inventory.snapshot.json",
"docs/security/K8S-ARGOCD-OWNER-RESPONSE-ACCEPTANCE.md",
"docs/security/k8s-argocd-owner-response-acceptance.snapshot.json",
"docs/security/K8S-ARGOCD-CHANGE-EVIDENCE-ACCEPTANCE.md",
"docs/security/k8s-argocd-change-evidence-acceptance.snapshot.json",
"docs/security/K8S-ARGOCD-POST-INCIDENT-READBACK-PLAN.md",
"docs/security/k8s-argocd-post-incident-readback-plan.snapshot.json",
"k8s/awoooi-prod",
"k8s/argocd",
],
"current_gap": "已固定 owner response acceptance、GitOps 變更證據驗收與事故後回讀計畫只讀帳本ArgoCD sync / health / degraded、Pending workload、image pull / scheduling、rollout before-after、event / metrics / alert、drift scanner、CronJob schedule、NetworkPolicy / RBAC、route / AI provider / monitoring 影響、防再發與 no-false-green 已納入;仍缺 owner response、事故回讀包、rendered manifest diff、ArgoCD revision、maintenance window、rollback revision、post-check owner 與 no-secret-value evidence。",
"next_owner_action": "補 GitOps / K8s 事故回讀包incident / change ref、actor role / team、ArgoCD sync / health / revision、degraded / Pending / image pull / scheduling 摘要、rollout before-after、event summary、metrics / alert、drift scanner、CronJob schedule、NetworkPolicy / Service / RBAC 影響、public/admin route、AI provider、monitoring、operator notification、cross-project sync、recovery 或 still-degraded ref、recurrence guard、maintenance window、rollback revision、rollback owner、post-check owner 與 no-secret-value evidence。",
},
"secret_metadata": {
"coverage_status": "post_incident_readback_plan_ready_needs_secret_injection_owner_evidence",
"coverage_percent": 70,
"evidence_refs": [
"docs/security/SOURCE-CONTROL-WORKFLOW-SECRET-NAME-INVENTORY.md",
"docs/security/source-control-workflow-secret-name-inventory.snapshot.json",
"docs/security/SOURCE-CONTROL-WORKFLOW-SECRET-NAME-OWNER-RESPONSE.md",
"docs/security/source-control-workflow-secret-name-owner-response.snapshot.json",
"docs/security/CD-RUNNER-SECRET-INJECTION-CHANGE-EVIDENCE-ACCEPTANCE.md",
"docs/security/cd-runner-secret-injection-change-evidence-acceptance.snapshot.json",
"docs/security/CD-RUNNER-SECRET-INJECTION-POST-INCIDENT-READBACK-PLAN.md",
"docs/security/cd-runner-secret-injection-post-incident-readback-plan.snapshot.json",
"docs/security/SECRETS_REFERENCE.md",
],
"current_gap": "已固定 secret name / injection owner 變更證據驗收帳本並新增事故後回讀計畫secret name parity state、secret injection route、step-env secret guard、log redaction、deploy marker / Gitea run readback、rollback、post-check、防再發與 no-false-green 已納入secret value、hash、partial token、runner token、secret store read、secret rotation、repo secret change 與 injection path change 仍全部為 0。",
"next_owner_action": "補 secret name parity state ref、secret injection route state ref、step-env secret guard result、log redaction readback、deploy marker / Gitea run readback、notification receipt、rollback owner、post-check evidence、recurrence guard 與 no-secret-value evidence。",
},
"gitea_workflow_runner_source_control": {
"coverage_status": "post_incident_readback_plan_ready_needs_workflow_runner_owner_evidence",
"coverage_percent": 74,
"evidence_refs": [
"docs/security/SOURCE-CONTROL-WORKFLOW-SECRET-NAME-INVENTORY.md",
"docs/security/SOURCE-CONTROL-WORKFLOW-SECRET-NAME-OWNER-RESPONSE.md",
"docs/security/CD-RUNNER-SECRET-INJECTION-CHANGE-EVIDENCE-ACCEPTANCE.md",
"docs/security/cd-runner-secret-injection-change-evidence-acceptance.snapshot.json",
"docs/security/CD-RUNNER-SECRET-INJECTION-POST-INCIDENT-READBACK-PLAN.md",
"docs/security/cd-runner-secret-injection-post-incident-readback-plan.snapshot.json",
"docs/security/SOURCE-CONTROL-PRIMARY-READINESS-GATE.md",
],
"current_gap": "已固定 CD / runner / secret injection 變更證據驗收帳本並新增事故後回讀計畫workflow diff state、runner attestation、executor / host、workspace cleanup、permission scope、webhook / notification、deploy key / branch protection / CODEOWNERS、deploy marker / Gitea run、rollback、post-change monitoring、防再發與 no-false-green 已納入workflow 修改、dispatch、runner 啟用 / 重啟、GitHub hosted runner、webhook / deploy key / branch protection / CODEOWNERS 修改仍全部為 0。",
"next_owner_action": "補 workflow diff state ref、runner owner attestation、executor / host readback、workspace cleanup、permission scope、Gitea run readback、deploy marker readback、webhook / notification receipt、maintenance window、rollback owner、post-change monitoring 與 recurrence guard evidence。",
},
"public_admin_api_runtime_config": {
"coverage_status": "frontend_sensitive_surface_guard_ready_needs_runtime_config_owner_evidence",
"coverage_percent": 66,
"evidence_refs": [
"docs/HARD_RULES.md",
"docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md",
"docs/security/PUBLIC-RUNTIME-CONFIG-CHANGE-EVIDENCE-ACCEPTANCE.md",
"docs/security/public-runtime-config-change-evidence-acceptance.snapshot.json",
"docs/security/public-frontend-sensitive-surface-guard.snapshot.json",
],
"current_gap": "已固定 Public / Admin / API runtime config 變更證據驗收只讀帳本,並新增前台 source / messages 敏感資訊防洩漏 guardaffected route、admin/auth boundary、API readback、CORS diff、frontend env diff、i18n redaction、webhook owner、desktop/mobile production smoke、bundle scan、rollback 與 post-check evidence 仍全部為 0。",
"next_owner_action": "補 affected route refs、admin/auth boundary、API contract readback、CORS origin diff、frontend env diff、i18n redaction review、webhook/callback owner、desktop/mobile production smoke、bundle sensitive scan、rollback owner 與 post-check evidence。",
},
"backup_restore_credential": {
"coverage_status": "post_incident_readback_plan_ready_needs_backup_restore_owner_evidence",
"coverage_percent": 66,
"evidence_refs": [
"docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md",
"docs/security/BACKUP-RESTORE-ESCROW-INVENTORY.md",
"docs/security/backup-restore-escrow-inventory.snapshot.json",
"docs/security/BACKUP-RESTORE-OWNER-RESPONSE-ACCEPTANCE.md",
"docs/security/backup-restore-owner-response-acceptance.snapshot.json",
"docs/security/BACKUP-RESTORE-POST-INCIDENT-READBACK-PLAN.md",
"docs/security/backup-restore-post-incident-readback-plan.snapshot.json",
"docs/schemas/backup_restore_escrow_inventory_v1.schema.json",
],
"current_gap": "已固定 owner response acceptance、restore recovery backfill 與事故後回讀計畫freshness before-after、backup status readback、restore drill、隔離 restore target、offsite sync、remote delete guard、credential escrow non-secret proof、retention runway、alert textfile、cold-start scorecard、rollback、post-change monitoring、防再發與 no-false-green 已納入只讀帳本owner response、事故回讀包、live backup evidence、restore drill accepted、offsite / escrow / retention accepted 與 runtime gate 仍全部為 0。",
"next_owner_action": "補 Backup / Restore / Escrow 事故回讀包incident / change ref、actor role / team、時間窗、改前改後 freshness、backup status readback、restore drill、隔離 restore target、offsite sync、remote delete guard、credential escrow non-secret proof、credential recovery metadata、retention runway、retention / prune decision、依賴圖、資料分級、restore observer / stop condition、alert textfile、cold-start / DR scorecard、rollback validation、post-change monitoring、recurrence guard 與 no-secret-value evidence。",
},
"agent_bounty_protocol_runtime": {
"coverage_status": "owner_request_draft_ready_needs_runtime_owner",
"coverage_percent": 68,
"evidence_refs": [
"docs/security/AGENT-BOUNTY-IWOOOS-ONBOARDING-HANDOFF.md",
"docs/security/agent-bounty-iwooos-onboarding-handoff.snapshot.json",
"docs/security/AGENT-BOUNTY-OWNER-REQUEST-DRAFT.md",
"docs/security/agent-bounty-owner-request-draft.snapshot.json",
"docs/security/GITHUB-TARGET-OWNER-DECISION-RESPONSE.md",
],
"current_gap": "owner request draft 已固定 11 份草稿;尚未收到 runtime / MCP / A2A / treasury / payout owner responseruntime gate 必須維持 0。",
"next_owner_action": "補 repo owner、external agent owner、treasury owner、runtime gate owner、maintenance window、rollback owner 與 validation plan。",
},
"monitoring_alerting_observability": {
"coverage_status": "soc_siem_kali_wazuh_integration_control_ready_needs_soc_owner_evidence",
"coverage_percent": 78,
"evidence_refs": [
"docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md",
"docs/security/MONITORING-ALERTING-OBSERVABILITY-INVENTORY.md",
"docs/security/monitoring-alerting-observability-inventory.snapshot.json",
"docs/security/MONITORING-OWNER-REQUEST-DRAFT.md",
"docs/security/monitoring-owner-request-draft.snapshot.json",
"docs/security/MONITORING-OWNER-RESPONSE-ACCEPTANCE.md",
"docs/security/monitoring-owner-response-acceptance.snapshot.json",
"docs/security/MONITORING-POST-INCIDENT-READBACK-PLAN.md",
"docs/security/monitoring-post-incident-readback-plan.snapshot.json",
"docs/security/WAZUH-IWOOOS-INTRUSION-READBACK-PLAN.md",
"docs/security/wazuh-iwooos-intrusion-readback-plan.snapshot.json",
"scripts/security/wazuh-iwooos-intrusion-readback-plan.py",
"docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md",
"docs/security/external-host-intrusion-prevention-control.snapshot.json",
"scripts/security/external-host-intrusion-prevention-control.py",
"docs/security/SOC-SIEM-KALI-WAZUH-INTEGRATION-CONTROL.md",
"docs/security/soc-siem-kali-wazuh-integration-control.snapshot.json",
"scripts/security/soc-siem-kali-wazuh-integration-control.py",
"apps/web/src/app/api/iwooos/wazuh/route.ts",
"docs/schemas/monitoring_alerting_observability_inventory_v1.schema.json",
],
"current_gap": "已固定 60 份 monitoring / alerting / observability owner response acceptance candidate、事故後回讀計畫、Wazuh / 主機入侵 readback plan、外部入侵主機防堵控制矩陣並新增 SOC / SIEM / Kali 112 / Wazuh 整合控制NIST CSF、CIS Controls、CISA KEV、OWASP ASVS、Wazuh、Suricata 與 Kali tooling 已映射到 16 個控制域、12 個訊號源與 20 個控制候選。仍缺 Wazuh event refs、Kali scope refs、host forensic refs、SIEM correlation、alert route owner、incident case owner、postcheck、recurrence guard、owner response 與 maintenance window。",
"next_owner_action": "補 SOC owner packetWazuh manager / agent / event refs、Kali scope / health / normalized finding refs、Prometheus / Alertmanager route refs、SigNoz / Sentry correlation refs、host forensic refs、gateway diff refs、runner / workflow refs、KEV / CVE refs、incident case ref、dedupe / noise budget、chain of custody、rollback owner、postcheck owner 與 no-secret / no-raw-payload / no-false-green attestation。",
},
"docker_compose_systemd_host_config": {
"coverage_status": "external_host_intrusion_prevention_control_ready_needs_host_service_owner_evidence",
"coverage_percent": 68,
"evidence_refs": [
"docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md",
"docs/security/HOST-SERVICE-CONFIG-INVENTORY.md",
"docs/security/host-service-config-inventory.snapshot.json",
"docs/security/HOST-SERVICE-OWNER-REQUEST-DRAFT.md",
"docs/security/host-service-owner-request-draft.snapshot.json",
"docs/security/HOST-SERVICE-OWNER-RESPONSE-ACCEPTANCE.md",
"docs/security/host-service-owner-response-acceptance.snapshot.json",
"docs/security/HOST-SERVICE-CHANGE-EVIDENCE-ACCEPTANCE.md",
"docs/security/host-service-change-evidence-acceptance.snapshot.json",
"docs/security/HOST-SERVICE-POST-INCIDENT-READBACK-PLAN.md",
"docs/security/host-service-post-incident-readback-plan.snapshot.json",
"docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md",
"docs/security/external-host-intrusion-prevention-control.snapshot.json",
"scripts/security/external-host-intrusion-prevention-control.py",
"docs/security/DEV-HOSTS-112-111-168-OBSERVE-ONLY-MAPPING.md",
],
"current_gap": "已固定 9 份 Docker / systemd / host service owner response acceptance candidate、change evidence acceptance、post-incident readback plan 與外部入侵防堵控制矩陣;重啟 actor、boot / recovery window、before / after state、Docker daemon、compose / systemd state、failed unit、port binding、dependency、process / persistence baseline、public/admin route recovery、AI provider health、monitoring alert、operator notice、cross-project sync、restoration、recurrence guard 與 no-false-green 皆已納入;仍缺 owner response、live hash、Wazuh / host forensic refs、maintenance / restart window、rollback owner、post-check plan、disable switch 與 no-secret-value evidence。",
"next_owner_action": "補 host service 防堵包owner-provided live hash / disposition、change / incident ref、actor role / team、boot time、restart / recovery window、before / after state、Docker daemon state、compose / systemd state、failed unit review、port binding、process / persistence refs、服務依賴圖、public/admin route recovery、AI provider health、monitoring alert、operator notification、cross-project sync、restoration evidence、recurrence guard、rollback owner、post-check plan 與 no-secret-value evidence。",
},
"ssh_firewall_network_access": {
"coverage_status": "external_host_intrusion_prevention_control_ready_needs_network_owner_evidence",
"coverage_percent": 70,
"evidence_refs": [
"docs/HARD_RULES.md",
"docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md",
"docs/security/SSH-NETWORK-ACCESS-INVENTORY.md",
"docs/security/ssh-network-access-inventory.snapshot.json",
"docs/security/SSH-NETWORK-OWNER-REQUEST-DRAFT.md",
"docs/security/ssh-network-owner-request-draft.snapshot.json",
"docs/security/SSH-NETWORK-OWNER-RESPONSE-ACCEPTANCE.md",
"docs/security/ssh-network-owner-response-acceptance.snapshot.json",
"docs/security/PORT-FIREWALL-CHANGE-EVIDENCE-ACCEPTANCE.md",
"docs/security/port-firewall-change-evidence-acceptance.snapshot.json",
"docs/security/SSH-NETWORK-POST-INCIDENT-READBACK-PLAN.md",
"docs/security/ssh-network-post-incident-readback-plan.snapshot.json",
"docs/security/EXTERNAL-HOST-INTRUSION-PREVENTION-CONTROL.md",
"docs/security/external-host-intrusion-prevention-control.snapshot.json",
"scripts/security/external-host-intrusion-prevention-control.py",
],
"current_gap": "owner response acceptance、端口 / 防火牆事故型變更證據驗收、post-incident readback plan 與外部入侵防堵控制矩陣都已固定SSH / sudo、authorized_keys、known_hosts、firewall、WireGuard、NodePort、NetworkPolicy、port close / open 與 break-glass 邊界已納入;仍缺 owner-provided change / incident evidence、actor、before / after state、Wazuh / host forensic refs、service / AI provider / monitoring impact、operator notification、cross-project sync、restoration evidence、recurrence guard、maintenance window、rollback owner 與 post-check evidence。",
"next_owner_action": "補 SSH / 端口 / 防火牆防堵包change / incident ref、actor role / team、affected scope、before / after state、service dependency、public route impact、AI provider impact、monitoring alert impact、operator notification、cross-project sync、restoration evidence、recurrence guard、maintenance window、rollback owner 與 post-check 指標。",
},
"ai_provider_model_routing": {
"coverage_status": "owner_response_acceptance_ready_needs_provider_owner_evidence",
"coverage_percent": 64,
"evidence_refs": [
"docs/HARD_RULES.md",
"docs/ai",
"docs/security/AI-PROVIDER-OWNER-RESPONSE-ACCEPTANCE.md",
"docs/security/ai-provider-owner-response-acceptance.snapshot.json",
],
"current_gap": "已固定 AI provider / model routing owner response acceptance 帳本provider owner、fallback order、dry-run、benchmark、成本、privacy、data classification、prompt redaction、rollback 與 post-check evidence 仍全部為 0目前不切 production。",
"next_owner_action": "補 provider owner、fallback order、dry-run result、benchmark result、cost review、privacy review、data classification、prompt redaction、quota budget、quality gate、rollback owner 與 post-check evidence。",
},
"product_surface_runtime_routes": {
"coverage_status": "scope_inventory_ready",
"coverage_percent": 72,
"evidence_refs": [
"docs/security/IWOOOS-CONFIG-CONTROL-INVENTORY.md",
"docs/security/VIBEWORK-IWOOOS-ONBOARDING-HANDOFF.md",
"docs/security/AGENT-BOUNTY-IWOOOS-ONBOARDING-HANDOFF.md",
"docs/security/AGENT-BOUNTY-OWNER-REQUEST-DRAFT.md",
],
"current_gap": "跨產品 owner response 尚未 accepted產品 route / admin / webhook 仍需逐產品補證。",
"next_owner_action": "補 AWOOOI、AwoooP、IwoooS、VibeWork、agent-bounty-protocol 與公開網站 owner response。",
},
"security_evidence_tooling": {
"coverage_status": "soc_siem_guard_ready",
"coverage_percent": 88,
"evidence_refs": [
"scripts/security/security-mirror-progress-guard.py",
"scripts/security/high-value-config-change-gate.py",
"scripts/security/high-value-config-owner-packet.py",
"docs/security/high-value-config-change-gate.snapshot.json",
"scripts/security/soc-siem-kali-wazuh-integration-control.py",
"docs/security/soc-siem-kali-wazuh-integration-control.snapshot.json",
],
"current_gap": "guard 已可重跑,且 SOC / SIEM / Kali / Wazuh 整合矩陣已納入 snapshot尚未接 blocking CI本階段刻意維持低摩擦。",
"next_owner_action": "維持 guard / doc secret sanity / SOC snapshot若要 CI blocking、active scan 或 active response 需另開人工批准與 rollout plan。",
},
}
FALSE_BOUNDARIES = {
"runtime_execution_authorized": False,
"host_write_authorized": False,
"host_live_conf_read_authorized": False,
"nginx_test_authorized": False,
"public_gateway_reload_authorized": False,
"public_route_change_authorized": False,
"admin_route_change_authorized": False,
"websocket_route_change_authorized": False,
"acme_challenge_change_authorized": False,
"route_smoke_authorized": False,
"rollback_executed": False,
"nginx_reload_authorized": False,
"dns_tls_change_authorized": False,
"certbot_renew_authorized": False,
"argocd_api_read_authorized": False,
"argocd_sync_authorized": False,
"kubectl_action_authorized": False,
"helm_upgrade_authorized": False,
"network_policy_apply_authorized": False,
"nodeport_change_authorized": False,
"rbac_change_authorized": False,
"backup_run_authorized": False,
"restore_run_authorized": False,
"restore_drill_authorized": False,
"offsite_sync_authorized": False,
"offsite_remote_delete_authorized": False,
"credential_escrow_marker_write_authorized": False,
"retention_change_authorized": False,
"restic_prune_authorized": False,
"rclone_config_authorized": False,
"velero_restore_authorized": False,
"workflow_modification_authorized": False,
"runner_change_authorized": False,
"refs_sync_authorized": False,
"force_push_authorized": False,
"prometheus_reload_authorized": False,
"alertmanager_reload_authorized": False,
"grafana_dashboard_apply_authorized": False,
"signoz_rule_apply_authorized": False,
"sentry_deploy_authorized": False,
"langfuse_config_change_authorized": False,
"otel_collector_reload_authorized": False,
"receiver_route_change_authorized": False,
"silence_policy_change_authorized": False,
"telegram_send_authorized": False,
"notification_route_change_authorized": False,
"webhook_receiver_change_authorized": False,
"remote_write_change_authorized": False,
"exporter_deploy_authorized": False,
"live_alert_fire_authorized": False,
"alert_chain_smoke_authorized": False,
"runtime_config_change_authorized": False,
"api_route_change_authorized": False,
"cors_change_authorized": False,
"frontend_env_change_authorized": False,
"middleware_auth_change_authorized": False,
"callback_url_change_authorized": False,
"webhook_secret_change_authorized": False,
"security_header_change_authorized": False,
"cookie_policy_change_authorized": False,
"csrf_disable_authorized": False,
"rate_limit_disable_authorized": False,
"api_contract_change_authorized": False,
"i18n_public_text_internal_identity_allowed": False,
"internal_ip_exposure_allowed": False,
"repo_namespace_exposure_allowed": False,
"owner_namespace_exposure_allowed": False,
"internal_status_code_exposure_allowed": False,
"internal_transcript_exposure_allowed": False,
"raw_payload_storage_allowed": False,
"desktop_mobile_smoke_authorized": False,
"database_migration_authorized": False,
"secret_value_collection_allowed": False,
"active_scan_authorized": False,
"agent_bounty_runtime_authorized": False,
"payout_or_withdrawal_authorized": False,
"action_buttons_allowed": False,
}
def git_short_sha(root: Path) -> str:
try:
result = subprocess.run(
["git", "rev-parse", "--short", "HEAD"],
cwd=root,
check=True,
capture_output=True,
text=True,
)
return result.stdout.strip()
except Exception:
return "unknown"
def load_gate_categories(root: Path) -> list[Any]:
gate_path = root / "scripts" / "security" / "high-value-config-change-gate.py"
namespace = runpy.run_path(str(gate_path))
return list(namespace["CATEGORIES"])
def category_to_dict(category: Any) -> dict[str, Any]:
status = CONTROL_STATUS_BY_CATEGORY[category.category_id]
return {
"category_id": category.category_id,
"label": category.label,
"priority": category.priority,
"control_tier": category.control_tier,
"required_gate": category.required_gate,
"coverage_status": status["coverage_status"],
"coverage_percent": status["coverage_percent"],
"patterns": list(category.patterns),
"required_validation": list(category.required_validation),
"evidence_refs": status["evidence_refs"],
"current_gap": status["current_gap"],
"next_owner_action": status["next_owner_action"],
"owner_response_required": True,
"owner_response_received": False,
"owner_response_accepted": False,
"runtime_gate_open": False,
"action_buttons_allowed": False,
}
def count_by(items: list[dict[str, Any]], key: str, value: Any) -> int:
return sum(1 for item in items if item[key] == value)
def build_report(root: Path, generated_at: str | None) -> dict[str, Any]:
report_time = generated_at or datetime.now(TAIPEI).isoformat(timespec="seconds")
categories = [category_to_dict(category) for category in load_gate_categories(root)]
c0_categories = [item for item in categories if item["control_tier"] == "C0"]
c1_categories = [item for item in categories if item["control_tier"] == "C1"]
needs_live_evidence = [
item
for item in categories
if item["coverage_status"]
in {
"gate_defined_needs_runtime_evidence",
"policy_defined_needs_restore_drill_owner",
"repo_only_inventory_ready_needs_restore_drill_owner",
"repo_only_inventory_ready_needs_live_route_evidence",
"repo_only_preflight_contract_ready_needs_owner_live_diff",
"owner_response_acceptance_ledger_ready_needs_owner_live_diff",
"rendered_diff_acceptance_ledger_ready_needs_owner_live_diff",
"emergency_change_backfill_ready_needs_owner_live_diff",
"post_incident_readback_plan_ready_needs_public_gateway_owner_evidence",
"owner_response_acceptance_ledger_ready_needs_runtime_evidence",
"change_evidence_acceptance_ready_needs_gitops_owner_evidence",
"post_incident_readback_plan_ready_needs_gitops_owner_evidence",
"secret_injection_change_evidence_acceptance_ready_needs_owner_evidence",
"cd_runner_secret_injection_change_evidence_acceptance_ready_needs_owner_evidence",
"post_incident_readback_plan_ready_needs_secret_injection_owner_evidence",
"post_incident_readback_plan_ready_needs_workflow_runner_owner_evidence",
"change_evidence_acceptance_ready_needs_runtime_config_owner_evidence",
"frontend_sensitive_surface_guard_ready_needs_runtime_config_owner_evidence",
"owner_response_acceptance_ledger_ready_needs_restore_drill_owner",
"restore_recovery_backfill_ready_needs_owner_live_evidence",
"post_incident_readback_plan_ready_needs_backup_restore_owner_evidence",
"owner_response_acceptance_ledger_ready_needs_network_owner",
"owner_response_acceptance_ledger_ready_needs_live_route_evidence",
"alert_chain_no_false_green_backfill_ready_needs_live_evidence_receipt",
"post_incident_readback_plan_ready_needs_monitoring_owner_evidence",
"wazuh_intrusion_readback_plan_ready_needs_wazuh_owner_evidence",
"external_host_intrusion_prevention_control_ready_needs_wazuh_owner_evidence",
"soc_siem_kali_wazuh_integration_control_ready_needs_soc_owner_evidence",
"change_evidence_acceptance_ready_needs_network_owner_evidence",
"incident_change_evidence_acceptance_ready_needs_network_owner_evidence",
"post_incident_readback_plan_ready_needs_network_owner_evidence",
"external_host_intrusion_prevention_control_ready_needs_network_owner_evidence",
"policy_ready_needs_drift_evidence",
"inventory_needed",
"repo_only_inventory_ready_needs_live_owner_evidence",
"incident_recovery_backfill_ready_needs_live_owner_evidence",
"change_evidence_acceptance_ready_needs_host_service_owner_evidence",
"external_host_intrusion_prevention_control_ready_needs_host_service_owner_evidence",
"policy_ready_needs_network_matrix",
"policy_ready_needs_dry_run_pack",
"owner_response_acceptance_ready_needs_provider_owner_evidence",
}
]
average_coverage = round(sum(item["coverage_percent"] for item in categories) / len(categories))
lowest_categories = sorted(categories, key=lambda item: item["coverage_percent"])[:4]
return {
"schema_version": "high_value_config_control_coverage_v1",
"generated_at": report_time,
"git_commit": git_short_sha(root),
"source_category_definition": "scripts/security/high-value-config-change-gate.py",
"status": "coverage_matrix_ready",
"summary": {
"category_count": len(categories),
"c0_category_count": len(c0_categories),
"c1_category_count": len(c1_categories),
"c2_category_count": count_by(categories, "control_tier", "C2"),
"c3_category_count": count_by(categories, "control_tier", "C3"),
"registered_control_count": len(categories),
"owner_response_required_count": len(categories),
"owner_response_received_count": 0,
"owner_response_accepted_count": 0,
"runtime_gate_count": 0,
"action_button_count": 0,
"average_coverage_percent": average_coverage,
"needs_live_evidence_count": len(needs_live_evidence),
"lowest_coverage_category_count": len(lowest_categories),
},
"execution_boundaries": FALSE_BOUNDARIES,
"coverage_categories": categories,
"lowest_coverage_categories": [
{
"category_id": item["category_id"],
"label": item["label"],
"coverage_percent": item["coverage_percent"],
"current_gap": item["current_gap"],
"next_owner_action": item["next_owner_action"],
}
for item in lowest_categories
],
"next_collection_order": [
"nginx_public_gateway",
"dns_tls_certbot",
"k8s_production_gitops",
"secret_metadata",
"gitea_workflow_runner_source_control",
"public_admin_api_runtime_config",
"ssh_firewall_network_access",
"docker_compose_systemd_host_config",
"monitoring_alerting_observability",
"agent_bounty_protocol_runtime",
"ai_provider_model_routing",
"backup_restore_credential",
],
"operator_interpretation": [
"這是全域配置控管覆蓋矩陣,不是單次 git diff 變更分類。",
"所有 category 都已有高價值配置 Gate 註冊與 owner response 欄位,但 owner response received / accepted 仍為 0。",
"C0 / C1 coverage percent 只代表只讀框架成熟度,不代表 runtime 可執行。",
"缺 live evidence 的項目只能收 owner-provided redacted evidence不得主動 SSH、reload、scan 或讀 secret value。",
],
}
def main() -> int:
parser = argparse.ArgumentParser(description="IwoooS 高價值配置控管覆蓋矩陣")
parser.add_argument("--root", default=".", help="repo root")
parser.add_argument("--output", help="寫出 JSON 報告")
parser.add_argument("--generated-at", help="固定報告時間,供 committed snapshot 使用")
args = parser.parse_args()
root = Path(args.root).resolve()
report = build_report(root, args.generated_at)
payload = json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True)
if args.output:
output = Path(args.output)
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text(payload + "\n", encoding="utf-8")
else:
print(payload)
summary = report["summary"]
print(
"HIGH_VALUE_CONFIG_CONTROL_COVERAGE_OK "
f"categories={summary['category_count']} "
f"c0={summary['c0_category_count']} "
f"avg={summary['average_coverage_percent']} "
f"runtime_gate={summary['runtime_gate_count']}",
file=sys.stderr,
)
return 0
if __name__ == "__main__":
sys.exit(main())