620 lines
26 KiB
Python
620 lines
26 KiB
Python
"""
|
|
IwoooS security tool closure readback.
|
|
|
|
This service joins the committed Wazuh, security operating-system and coverage
|
|
readbacks into a public-safe tool closure cockpit. It does not query live hosts,
|
|
read secrets, run scanners, trigger SOAR, or authorize runtime actions.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from src.services.iwooos_security_control_coverage import (
|
|
load_latest_iwooos_security_control_coverage,
|
|
)
|
|
from src.services.iwooos_security_operating_system import (
|
|
load_latest_iwooos_security_operating_system,
|
|
)
|
|
from src.services.iwooos_wazuh_allowlisted_check_mode_dry_run import (
|
|
load_latest_iwooos_wazuh_allowlisted_check_mode_dry_run,
|
|
)
|
|
from src.services.iwooos_wazuh_fim_vulnerability_alert_verifier import (
|
|
load_latest_iwooos_wazuh_fim_vulnerability_alert_verifier,
|
|
)
|
|
from src.services.iwooos_wazuh_managed_host_coverage import (
|
|
load_latest_iwooos_wazuh_managed_host_coverage,
|
|
)
|
|
from src.services.iwooos_wazuh_manager_registry_reviewer_validation import (
|
|
load_latest_iwooos_wazuh_manager_registry_reviewer_validation,
|
|
)
|
|
from src.services.iwooos_wazuh_runtime_controlled_apply_preflight import (
|
|
load_latest_iwooos_wazuh_runtime_controlled_apply_preflight,
|
|
)
|
|
from src.services.iwooos_wazuh_runtime_gate_owner_review_readback import (
|
|
load_latest_iwooos_wazuh_runtime_gate_owner_review_readback,
|
|
)
|
|
|
|
_SCHEMA_VERSION = "iwooos_security_tool_closure_readback_v2"
|
|
_REQUIRED_ZERO_SUMMARY_KEYS = {
|
|
"secret_value_collection_allowed_count",
|
|
"secret_value_collected_count",
|
|
}
|
|
|
|
|
|
def load_latest_iwooos_security_tool_closure_readback(
|
|
alert_receipt_readback: dict[str, Any] | None = None,
|
|
) -> dict[str, Any]:
|
|
"""Return the public-safe external tool closure rollup."""
|
|
coverage = load_latest_iwooos_security_control_coverage()
|
|
security_os = load_latest_iwooos_security_operating_system(
|
|
alert_receipt_readback=alert_receipt_readback
|
|
)
|
|
managed_hosts = load_latest_iwooos_wazuh_managed_host_coverage()
|
|
registry = load_latest_iwooos_wazuh_manager_registry_reviewer_validation()
|
|
controlled_apply = load_latest_iwooos_wazuh_runtime_controlled_apply_preflight()
|
|
owner_review = load_latest_iwooos_wazuh_runtime_gate_owner_review_readback()
|
|
dry_run = load_latest_iwooos_wazuh_allowlisted_check_mode_dry_run()
|
|
wazuh_verifier = load_latest_iwooos_wazuh_fim_vulnerability_alert_verifier(
|
|
alert_receipt_readback=alert_receipt_readback
|
|
)
|
|
|
|
source_payloads = [
|
|
coverage,
|
|
security_os,
|
|
managed_hosts,
|
|
registry,
|
|
controlled_apply,
|
|
owner_review,
|
|
dry_run,
|
|
wazuh_verifier,
|
|
]
|
|
_require_runtime_boundaries(source_payloads)
|
|
|
|
source_summaries = {
|
|
"coverage": _summary(coverage),
|
|
"security_os": _summary(security_os),
|
|
"managed_hosts": _summary(managed_hosts),
|
|
"registry": _summary(registry),
|
|
"controlled_apply": _summary(controlled_apply),
|
|
"owner_review": _summary(owner_review),
|
|
"dry_run": _summary(dry_run),
|
|
"wazuh_verifier": _summary(wazuh_verifier),
|
|
}
|
|
tracks = _tool_tracks(source_summaries)
|
|
summary = _summary_rollup(source_summaries, tracks)
|
|
|
|
return {
|
|
"schema_version": _SCHEMA_VERSION,
|
|
"status": "tool_source_readiness_available_runtime_closure_open",
|
|
"mode": "readback_rollup_controlled_apply_policy_no_execution_by_endpoint",
|
|
"summary": summary,
|
|
"tool_tracks": tracks,
|
|
"next_executable_queue": _next_executable_queue(source_summaries),
|
|
"acceptance_definition": [
|
|
"wazuh_live_event_forensics_case_response_and_independent_post_verifier_closed",
|
|
"sbom_and_vulnerability_reports_attached_to_package_and_image_artifacts",
|
|
"runtime_detection_events_normalized_and_reviewed_without_auto_block",
|
|
"web_api_dast_scope_rate_limit_and_baseline_report_closed",
|
|
"ai_controlled_apply_has_selector_diff_check_mode_rollback_post_verifier_km_writeback",
|
|
],
|
|
"boundary_markers": _boundary_markers(summary),
|
|
"boundaries": {
|
|
"live_host_query_performed": False,
|
|
"live_wazuh_query_performed": False,
|
|
"scanner_execution_performed": False,
|
|
"payload_persisted": False,
|
|
"runtime_execution_performed": False,
|
|
"controlled_apply_policy_active": True,
|
|
"low_risk_controlled_apply_allowed": True,
|
|
"medium_risk_controlled_apply_allowed": True,
|
|
"high_risk_controlled_apply_allowed": True,
|
|
"critical_break_glass_required": True,
|
|
"owner_review_required_for_low_medium_high": False,
|
|
"soar_action_authorized": False,
|
|
"secret_value_collection_allowed": False,
|
|
"readback_endpoint_is_executor": False,
|
|
},
|
|
"no_false_green_rules": [
|
|
"tool closure readback is a cockpit rollup, not an active scanner or SOAR switch",
|
|
"source readiness and runtime closure are separate; complete source signals only create an execution candidate",
|
|
"Wazuh manager registry accepted does not close FIM, vulnerability, alert receipt, or active response",
|
|
"SBOM, DAST, runtime detection and policy tracks remain not closed until artifacts and post-verifiers exist",
|
|
"readback endpoint never performs side effects; controlled executor still requires complete selector, diff, check-mode, rollback and independent verifier receipts",
|
|
"low, medium and high risk policy stays open; missing automation evidence creates an AI repair work item instead of a manual terminal",
|
|
],
|
|
"source_refs": [
|
|
*coverage.get("source_refs", []),
|
|
*security_os.get("source_refs", []),
|
|
*managed_hosts.get("source_refs", []),
|
|
*registry.get("source_refs", []),
|
|
*controlled_apply.get("source_refs", []),
|
|
*owner_review.get("source_refs", []),
|
|
*dry_run.get("source_refs", []),
|
|
*wazuh_verifier.get("source_refs", []),
|
|
],
|
|
}
|
|
|
|
|
|
def _tool_tracks(source_summaries: dict[str, dict[str, Any]]) -> list[dict[str, Any]]:
|
|
coverage = source_summaries["coverage"]
|
|
security_os = source_summaries["security_os"]
|
|
managed_hosts = source_summaries["managed_hosts"]
|
|
registry = source_summaries["registry"]
|
|
controlled_apply = source_summaries["controlled_apply"]
|
|
owner_review = source_summaries["owner_review"]
|
|
dry_run = source_summaries["dry_run"]
|
|
wazuh_verifier = source_summaries["wazuh_verifier"]
|
|
|
|
expected_hosts = max(
|
|
_int(managed_hosts.get("expected_host_scope_count")),
|
|
_int(registry.get("expected_scope_alias_count")),
|
|
_int(coverage.get("wazuh_expected_host_scope_count")),
|
|
)
|
|
accepted_hosts = max(
|
|
_int(managed_hosts.get("manager_registry_accepted_count")),
|
|
_int(registry.get("manager_registry_accepted_count")),
|
|
_int(coverage.get("wazuh_manager_registry_accepted_count")),
|
|
_int(security_os.get("wazuh_registry_accepted_count")),
|
|
)
|
|
registry_ready = expected_hosts > 0 and accepted_hosts >= expected_hosts
|
|
alert_ready = _int(security_os.get("alert_receipt_accepted_count")) > 0
|
|
wazuh_verifier_ready_signals = _int(
|
|
wazuh_verifier.get("verifier_ready_signal_count")
|
|
)
|
|
|
|
controlled_apply_ready_signals = sum(
|
|
1
|
|
for key in (
|
|
"target_selector_count",
|
|
"source_of_truth_diff_count",
|
|
"check_mode_plan_count",
|
|
"rollback_plan_count",
|
|
"post_apply_verifier_count",
|
|
"km_playbook_writeback_count",
|
|
"controlled_apply_preflight_ready_count",
|
|
)
|
|
if _int(controlled_apply.get(key)) > 0
|
|
)
|
|
owner_review_ready_signals = sum(
|
|
1
|
|
for key in (
|
|
"target_selector_count",
|
|
"source_of_truth_diff_count",
|
|
"check_mode_plan_count",
|
|
"dry_run_evidence_count",
|
|
"rollback_plan_count",
|
|
"post_apply_verifier_count",
|
|
"km_playbook_writeback_count",
|
|
"owner_review_packet_review_ready_count",
|
|
)
|
|
if _int(owner_review.get(key)) > 0
|
|
)
|
|
dry_run_ready_signals = sum(
|
|
1
|
|
for key in (
|
|
"allowlisted_target_selector_count",
|
|
"check_mode_plan_count",
|
|
"dry_run_evidence_ref_count",
|
|
"dry_run_result_ref_count",
|
|
"post_dry_run_verifier_count",
|
|
"rollback_revalidation_count",
|
|
"km_playbook_writeback_ready_count",
|
|
)
|
|
if _int(dry_run.get(key)) > 0
|
|
)
|
|
|
|
return [
|
|
_track(
|
|
track_id="wazuh_detection_response",
|
|
priority="P0",
|
|
label="Wazuh detection and response",
|
|
tool_ids=["wazuh"],
|
|
ready_signal_count=max(
|
|
(1 if registry_ready else 0) + (1 if alert_ready else 0),
|
|
wazuh_verifier_ready_signals,
|
|
),
|
|
required_signal_count=6,
|
|
runtime_closed=(
|
|
_int(
|
|
wazuh_verifier.get(
|
|
"wazuh_fim_vulnerability_alert_runtime_closed_count"
|
|
)
|
|
)
|
|
> 0
|
|
),
|
|
next_executable_action="attach_incident_case_and_active_response_dry_run_receipts_without_runtime_gate",
|
|
required_verifier="wazuh_registry_fim_vulnerability_alert_receipt_post_verifier",
|
|
source_refs=[
|
|
"docs/security/wazuh-managed-host-coverage-gate.snapshot.json",
|
|
"docs/security/iwooos-security-operating-system.snapshot.json",
|
|
"apps/api/src/services/iwooos_wazuh_fim_vulnerability_alert_verifier.py",
|
|
],
|
|
),
|
|
_track(
|
|
track_id="supply_chain_sbom_scan",
|
|
priority="P0",
|
|
label="Supply-chain SBOM and vulnerability scan",
|
|
tool_ids=["trivy", "syft", "grype"],
|
|
ready_signal_count=0,
|
|
required_signal_count=5,
|
|
next_executable_action="attach_sbom_vulnerability_report_and_no_secret_output_guard",
|
|
required_verifier="sbom_vulnerability_artifact_post_verifier",
|
|
source_refs=["docs/security/security-asset-control-ledger.snapshot.json"],
|
|
),
|
|
_track(
|
|
track_id="source_control_scorecard",
|
|
priority="P1",
|
|
label="Source-control hygiene scorecard",
|
|
tool_ids=["openssf_scorecard", "gitea_source_policy"],
|
|
ready_signal_count=0,
|
|
required_signal_count=4,
|
|
next_executable_action="map_branch_protection_dependency_update_and_build_policy_readback",
|
|
required_verifier="source_control_policy_scorecard_verifier",
|
|
source_refs=["docs/evaluations/runtime_surface_inventory_latest"],
|
|
),
|
|
_track(
|
|
track_id="k8s_policy_attestation",
|
|
priority="P1",
|
|
label="Kubernetes policy and image attestation",
|
|
tool_ids=["kyverno", "cosign"],
|
|
ready_signal_count=0,
|
|
required_signal_count=5,
|
|
next_executable_action="stage_policy_check_mode_image_signature_and_exception_register",
|
|
required_verifier="k8s_policy_attestation_post_verifier",
|
|
source_refs=["docs/security/host-service-config-inventory.snapshot.json"],
|
|
),
|
|
_track(
|
|
track_id="runtime_threat_detection",
|
|
priority="P1",
|
|
label="Runtime threat detection",
|
|
tool_ids=["falco"],
|
|
ready_signal_count=0,
|
|
required_signal_count=4,
|
|
next_executable_action="stage_rule_dry_run_event_redaction_and_wazuh_correlation",
|
|
required_verifier="runtime_detection_event_post_verifier",
|
|
source_refs=["docs/security/monitoring-alerting-observability-inventory.snapshot.json"],
|
|
),
|
|
_track(
|
|
track_id="web_api_dast",
|
|
priority="P1",
|
|
label="Web and API DAST",
|
|
tool_ids=["owasp_zap_or_equivalent_dast"],
|
|
ready_signal_count=0,
|
|
required_signal_count=5,
|
|
next_executable_action="prepare_bounded_target_selector_rate_limit_and_baseline_report",
|
|
required_verifier="web_api_dast_scope_and_report_verifier",
|
|
source_refs=["docs/security/ssh-network-access-inventory.snapshot.json"],
|
|
),
|
|
_track(
|
|
track_id="normalized_detection_schema",
|
|
priority="P1",
|
|
label="Normalized detection schema",
|
|
tool_ids=["sigma", "ocsf"],
|
|
ready_signal_count=(1 if alert_ready else 0),
|
|
required_signal_count=4,
|
|
next_executable_action="normalize_wazuh_alertmanager_app_events_into_review_cards",
|
|
required_verifier="sigma_ocsf_event_mapping_regression_verifier",
|
|
source_refs=["docs/security/iwooos-security-operating-system.snapshot.json"],
|
|
),
|
|
_track(
|
|
track_id="ai_agent_controlled_apply",
|
|
priority="P0",
|
|
label="AI Agent controlled apply loop",
|
|
tool_ids=["ai_agent", "mcp", "rag", "km_playbook"],
|
|
ready_signal_count=min(
|
|
controlled_apply_ready_signals
|
|
+ owner_review_ready_signals
|
|
+ dry_run_ready_signals,
|
|
9,
|
|
),
|
|
required_signal_count=9,
|
|
next_executable_action="run_allowlisted_check_mode_with_rollback_post_verifier_and_km_writeback",
|
|
required_verifier="ai_controlled_apply_post_verifier_and_learning_writeback",
|
|
source_refs=[
|
|
"docs/security/wazuh-runtime-controlled-apply-preflight.snapshot.json",
|
|
"docs/security/wazuh-runtime-gate-owner-review-readback.snapshot.json",
|
|
"docs/security/wazuh-allowlisted-check-mode-dry-run.snapshot.json",
|
|
],
|
|
),
|
|
]
|
|
|
|
|
|
def _track(
|
|
*,
|
|
track_id: str,
|
|
priority: str,
|
|
label: str,
|
|
tool_ids: list[str],
|
|
ready_signal_count: int,
|
|
required_signal_count: int,
|
|
runtime_closed: bool = False,
|
|
next_executable_action: str,
|
|
required_verifier: str,
|
|
source_refs: list[str],
|
|
) -> dict[str, Any]:
|
|
ready_count = max(min(ready_signal_count, required_signal_count), 0)
|
|
missing_count = max(required_signal_count - ready_count, 0)
|
|
source_readiness_percent = int(round((ready_count / required_signal_count) * 100)) if required_signal_count else 0
|
|
source_ready = missing_count == 0
|
|
if runtime_closed:
|
|
runtime_closure_state = "runtime_closed"
|
|
elif source_ready:
|
|
runtime_closure_state = "source_ready_runtime_open"
|
|
elif ready_count > 0:
|
|
runtime_closure_state = "partial_source_readiness_runtime_open"
|
|
else:
|
|
runtime_closure_state = "source_missing_runtime_open"
|
|
return {
|
|
"track_id": track_id,
|
|
"priority": priority,
|
|
"label": label,
|
|
"tool_ids": tool_ids,
|
|
"closure_state": runtime_closure_state,
|
|
"closure_percent": 100 if runtime_closed else 0,
|
|
"source_readiness_state": (
|
|
"source_ready" if source_ready else "source_readiness_incomplete"
|
|
),
|
|
"source_readiness_percent": source_readiness_percent,
|
|
"runtime_closure_state": runtime_closure_state,
|
|
"runtime_closed": runtime_closed,
|
|
"ready_signal_count": ready_count,
|
|
"required_signal_count": required_signal_count,
|
|
"missing_signal_count": missing_count,
|
|
"controlled_apply_policy_allowed": True,
|
|
"execution_candidate_ready": source_ready and not runtime_closed,
|
|
"runtime_execution_performed": runtime_closed,
|
|
"owner_review_required": False,
|
|
"critical_break_glass_required": False,
|
|
"secret_value_collection_allowed": False,
|
|
"next_executable_action": next_executable_action,
|
|
"required_verifier": required_verifier,
|
|
"source_refs": source_refs,
|
|
}
|
|
|
|
|
|
def _summary_rollup(
|
|
source_summaries: dict[str, dict[str, Any]],
|
|
tracks: list[dict[str, Any]],
|
|
) -> dict[str, Any]:
|
|
coverage = source_summaries["coverage"]
|
|
security_os = source_summaries["security_os"]
|
|
managed_hosts = source_summaries["managed_hosts"]
|
|
registry = source_summaries["registry"]
|
|
controlled_apply = source_summaries["controlled_apply"]
|
|
owner_review = source_summaries["owner_review"]
|
|
dry_run = source_summaries["dry_run"]
|
|
wazuh_verifier = source_summaries["wazuh_verifier"]
|
|
|
|
expected_hosts = max(
|
|
_int(managed_hosts.get("expected_host_scope_count")),
|
|
_int(registry.get("expected_scope_alias_count")),
|
|
_int(coverage.get("wazuh_expected_host_scope_count")),
|
|
)
|
|
accepted_hosts = max(
|
|
_int(managed_hosts.get("manager_registry_accepted_count")),
|
|
_int(registry.get("manager_registry_accepted_count")),
|
|
_int(coverage.get("wazuh_manager_registry_accepted_count")),
|
|
_int(security_os.get("wazuh_registry_accepted_count")),
|
|
)
|
|
total_required = sum(_int(track.get("required_signal_count")) for track in tracks)
|
|
total_ready = sum(_int(track.get("ready_signal_count")) for track in tracks)
|
|
source_ready_track_count = sum(
|
|
1 for track in tracks if _int(track.get("missing_signal_count")) == 0
|
|
)
|
|
runtime_closed_track_count = sum(
|
|
1 for track in tracks if track.get("runtime_closed") is True
|
|
)
|
|
source_readiness_percent = (
|
|
int(round((total_ready / total_required) * 100))
|
|
if total_required
|
|
else 0
|
|
)
|
|
runtime_closure_percent = (
|
|
int(round((runtime_closed_track_count / len(tracks)) * 100))
|
|
if tracks
|
|
else 0
|
|
)
|
|
|
|
return {
|
|
"source_readback_count": len(source_summaries),
|
|
"tool_track_count": len(tracks),
|
|
"p0_tool_track_count": sum(1 for track in tracks if track.get("priority") == "P0"),
|
|
"source_ready_tool_track_count": source_ready_track_count,
|
|
"closed_tool_track_count": runtime_closed_track_count,
|
|
"partial_tool_track_count": sum(
|
|
1
|
|
for track in tracks
|
|
if _int(track.get("ready_signal_count")) > 0
|
|
and _int(track.get("missing_signal_count")) > 0
|
|
),
|
|
"missing_tool_track_count": sum(
|
|
1 for track in tracks if _int(track.get("ready_signal_count")) == 0
|
|
),
|
|
"total_ready_signal_count": total_ready,
|
|
"total_required_signal_count": total_required,
|
|
"tool_source_readiness_percent": source_readiness_percent,
|
|
"tool_runtime_closure_percent": runtime_closure_percent,
|
|
# Backward-compatible field now follows runtime semantics. Source-only
|
|
# progress is exposed separately and must not inflate closure.
|
|
"tool_closure_percent": runtime_closure_percent,
|
|
"wazuh_expected_host_scope_count": expected_hosts,
|
|
"wazuh_manager_registry_accepted_count": accepted_hosts,
|
|
"wazuh_registry_complete_count": 1 if expected_hosts > 0 and accepted_hosts >= expected_hosts else 0,
|
|
"wazuh_fim_vulnerability_alert_closed_count": _int(
|
|
wazuh_verifier.get("wazuh_fim_vulnerability_alert_closed_count")
|
|
),
|
|
"wazuh_fim_vulnerability_alert_source_verifier_ready_count": _int(
|
|
wazuh_verifier.get(
|
|
"wazuh_fim_vulnerability_alert_source_verifier_ready_count"
|
|
)
|
|
),
|
|
"wazuh_fim_vulnerability_alert_runtime_closed_count": _int(
|
|
wazuh_verifier.get(
|
|
"wazuh_fim_vulnerability_alert_runtime_closed_count"
|
|
)
|
|
),
|
|
"wazuh_fim_vulnerability_alert_verifier_ready_count": _int(
|
|
wazuh_verifier.get("wazuh_fim_vulnerability_alert_verifier_ready_count")
|
|
),
|
|
"wazuh_fim_vulnerability_alert_verifier_ready_signal_count": _int(
|
|
wazuh_verifier.get("verifier_ready_signal_count")
|
|
),
|
|
"alert_receipt_observed_count": _int(
|
|
security_os.get("alert_receipt_observed_count")
|
|
),
|
|
"alert_receipt_accepted_count": _int(
|
|
security_os.get("alert_receipt_accepted_count")
|
|
),
|
|
"alert_receipt_source_status": str(
|
|
security_os.get("alert_receipt_source_status") or "not_connected"
|
|
),
|
|
"controlled_apply_preflight_ready_count": _int(
|
|
controlled_apply.get("controlled_apply_preflight_ready_count")
|
|
),
|
|
"owner_review_packet_accepted_count": _int(
|
|
owner_review.get("owner_review_packet_accepted_count")
|
|
),
|
|
"allowlisted_dry_run_result_ref_count": _int(
|
|
dry_run.get("dry_run_result_ref_count")
|
|
),
|
|
"supply_chain_scan_closed_count": 0,
|
|
"runtime_detection_closed_count": 0,
|
|
"web_api_dast_closed_count": 0,
|
|
"normalized_detection_schema_closed_count": 0,
|
|
"controlled_apply_policy_active_count": 1,
|
|
"controlled_apply_candidate_ready_count": sum(
|
|
1 for track in tracks if track.get("execution_candidate_ready") is True
|
|
),
|
|
"owner_review_required_for_low_medium_high_count": 0,
|
|
"runtime_execution_performed_count": sum(
|
|
1 for track in tracks if track.get("runtime_execution_performed") is True
|
|
),
|
|
"secret_value_collection_allowed_count": 0,
|
|
}
|
|
|
|
|
|
def _next_executable_queue(
|
|
source_summaries: dict[str, dict[str, Any]],
|
|
) -> list[dict[str, Any]]:
|
|
managed_hosts = source_summaries["managed_hosts"]
|
|
registry = source_summaries["registry"]
|
|
wazuh_verifier = source_summaries["wazuh_verifier"]
|
|
controlled_apply = source_summaries["controlled_apply"]
|
|
dry_run = source_summaries["dry_run"]
|
|
expected_hosts = max(
|
|
_int(managed_hosts.get("expected_host_scope_count")),
|
|
_int(registry.get("expected_scope_alias_count")),
|
|
)
|
|
accepted_hosts = max(
|
|
_int(managed_hosts.get("manager_registry_accepted_count")),
|
|
_int(registry.get("manager_registry_accepted_count")),
|
|
)
|
|
source_verifier_ready = (
|
|
_int(
|
|
wazuh_verifier.get(
|
|
"wazuh_fim_vulnerability_alert_source_verifier_ready_count"
|
|
)
|
|
)
|
|
> 0
|
|
)
|
|
runtime_closed = (
|
|
_int(
|
|
wazuh_verifier.get(
|
|
"wazuh_fim_vulnerability_alert_runtime_closed_count"
|
|
)
|
|
)
|
|
> 0
|
|
)
|
|
if runtime_closed:
|
|
registry_gate = "wazuh_detection_response_runtime_closed_monitor_recurrence"
|
|
wazuh_next_action = "monitor_recurrence_and_control_freshness_slo"
|
|
elif source_verifier_ready:
|
|
registry_gate = "wazuh_source_verifier_ready_runtime_closure_open"
|
|
wazuh_next_action = (
|
|
"attach_live_wazuh_event_forensics_incident_case_controlled_response_"
|
|
"and_independent_post_verifier_receipts"
|
|
)
|
|
elif expected_hosts > 0 and accepted_hosts >= expected_hosts:
|
|
registry_gate = "wazuh_registry_complete_move_to_fim_vulnerability_alert"
|
|
wazuh_next_action = "attach_fim_vulnerability_alert_receipt_post_verifier"
|
|
else:
|
|
registry_gate = "complete_wazuh_manager_registry_alias_matrix"
|
|
wazuh_next_action = "complete_wazuh_manager_registry_alias_matrix"
|
|
|
|
return [
|
|
{
|
|
"queue_id": "P0-03",
|
|
"track_id": "wazuh_detection_response",
|
|
"state": registry_gate,
|
|
"next_action": wazuh_next_action,
|
|
"ready_signal_count": _int(
|
|
wazuh_verifier.get("verifier_ready_signal_count")
|
|
),
|
|
"controlled_apply_policy_allowed": True,
|
|
},
|
|
{
|
|
"queue_id": "P0-07",
|
|
"track_id": "supply_chain_sbom_scan",
|
|
"state": "sbom_and_scan_artifacts_missing",
|
|
"next_action": "stage_trivy_syft_grype_check_mode_reports",
|
|
"controlled_apply_policy_allowed": True,
|
|
},
|
|
{
|
|
"queue_id": "P0-08",
|
|
"track_id": "ai_agent_controlled_apply",
|
|
"state": "preflight_ready_for_controlled_policy_check",
|
|
"next_action": "connect_target_selector_diff_check_mode_rollback_post_verifier_km",
|
|
"ready_signal_count": _int(
|
|
controlled_apply.get("controlled_apply_preflight_ready_count")
|
|
)
|
|
+ _int(dry_run.get("dry_run_result_ref_count")),
|
|
"controlled_apply_policy_allowed": True,
|
|
},
|
|
]
|
|
|
|
|
|
def _summary(payload: dict[str, Any]) -> dict[str, Any]:
|
|
summary = payload.get("summary")
|
|
return summary if isinstance(summary, dict) else {}
|
|
|
|
|
|
def _int(value: Any) -> int:
|
|
return value if isinstance(value, int) else 0
|
|
|
|
|
|
def _require_runtime_boundaries(payloads: list[dict[str, Any]]) -> None:
|
|
for payload in payloads:
|
|
summary = _summary(payload)
|
|
for key in _REQUIRED_ZERO_SUMMARY_KEYS:
|
|
if key in summary and _int(summary.get(key)) != 0:
|
|
raise ValueError(f"{payload.get('schema_version')}: summary.{key} must remain 0")
|
|
boundaries = payload.get("boundaries")
|
|
if isinstance(boundaries, dict):
|
|
for key in (
|
|
"secret_value_collection_allowed",
|
|
):
|
|
if key in boundaries and boundaries.get(key) is not False:
|
|
raise ValueError(
|
|
f"{payload.get('schema_version')}: boundaries.{key} must remain false"
|
|
)
|
|
|
|
|
|
def _boundary_markers(summary: dict[str, Any]) -> list[str]:
|
|
return [
|
|
"iwooos_security_tool_closure_readback_visible=true",
|
|
f"iwooos_security_tool_closure_tool_track_count={summary['tool_track_count']}",
|
|
f"iwooos_security_tool_closure_p0_tool_track_count={summary['p0_tool_track_count']}",
|
|
f"iwooos_security_tool_source_readiness_percent={summary['tool_source_readiness_percent']}",
|
|
f"iwooos_security_tool_runtime_closure_percent={summary['tool_runtime_closure_percent']}",
|
|
f"iwooos_security_tool_closure_percent={summary['tool_closure_percent']}",
|
|
f"iwooos_security_tool_closure_wazuh_manager_registry_accepted_count={summary['wazuh_manager_registry_accepted_count']}",
|
|
f"iwooos_security_tool_closure_alert_receipt_accepted_count={summary['alert_receipt_accepted_count']}",
|
|
"iwooos_security_tool_closure_controlled_apply_policy_active=true",
|
|
f"iwooos_security_tool_closure_controlled_apply_candidate_ready_count={summary['controlled_apply_candidate_ready_count']}",
|
|
"owner_review_required_for_low_medium_high=false",
|
|
"runtime_execution_performed=false",
|
|
"secret_value_collection_allowed=false",
|
|
"readback_endpoint_is_executor=false",
|
|
]
|