fix(iwooos): close Wazuh SOC runtime slice
Some checks failed
CD Pipeline / select-latest-carrier (push) Successful in 48s
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m22s
CD Pipeline / revalidate-deploy-carrier (push) Successful in 36s
CD Pipeline / build-and-deploy (push) Has been cancelled
CD Pipeline / revalidate-post-deploy-carrier (push) Has been cancelled
CD Pipeline / post-deploy-checks (push) Has been cancelled

This commit is contained in:
Your Name
2026-07-22 14:32:51 +08:00
parent 52ad145847
commit 1144ddee7d
15 changed files with 1683 additions and 87 deletions

View File

@@ -57,6 +57,17 @@ type Copy = {
forbiddenSources: string;
imagePolicy: string;
publicTls: string;
wazuhSlice: string;
protectedAssets: string;
ownerTelemetry: string;
identityLink: string;
incident: string;
verifier: string;
recipientReceipt: string;
remainingGaps: string;
delivered: string;
closed: string;
open: string;
certificates: string;
tlsEvidence: string;
tlsHealthy: string;
@@ -113,6 +124,17 @@ const COPY: Record<"zh" | "en", Copy> = {
forbiddenSources: "禁用來源",
imagePolicy: "映像政策",
publicTls: "Public TLS",
wazuhSlice: "Wazuh AI SOC 同 run",
protectedAssets: "受保護資產",
ownerTelemetry: "Owner / 遙測",
identityLink: "Identity 串接",
incident: "事件處置",
verifier: "獨立驗證",
recipientReceipt: "Telegram 收據",
remainingGaps: "剩餘缺口",
delivered: "已送達",
closed: "已閉環",
open: "未閉環",
certificates: "憑證資產",
tlsEvidence: "Live 驗證",
tlsHealthy: "健康憑證",
@@ -167,6 +189,17 @@ const COPY: Record<"zh" | "en", Copy> = {
forbiddenSources: "Forbidden sources",
imagePolicy: "Image policy",
publicTls: "Public TLS",
wazuhSlice: "Wazuh AI SOC same run",
protectedAssets: "Protected assets",
ownerTelemetry: "Owner / telemetry",
identityLink: "Identity link",
incident: "Incident",
verifier: "Independent verify",
recipientReceipt: "Telegram receipt",
remainingGaps: "Remaining gaps",
delivered: "DELIVERED",
closed: "CLOSED",
open: "OPEN",
certificates: "Certificates",
tlsEvidence: "Live evidence",
tlsHealthy: "Healthy certs",
@@ -290,12 +323,14 @@ function TruthCell({
icon: Icon,
tone = "neutral",
wideOnMobile = false,
title,
}: {
label: string;
value: string | number;
icon: typeof ShieldCheck;
tone?: "neutral" | "healthy" | "critical";
wideOnMobile?: boolean;
title?: string;
}) {
return (
<div
@@ -303,6 +338,8 @@ function TruthCell({
"flex min-w-0 items-center gap-2 bg-white px-3 py-2.5",
wideOnMobile && "last:col-span-2 lg:last:col-span-1",
)}
title={title}
aria-label={title}
>
<Icon
className={cn(
@@ -400,6 +437,128 @@ function CertificateTruthStrip({
);
}
function WazuhSocTruthStrip({
copy,
payload,
}: {
copy: Copy;
payload: SecurityAssetControlPlanePayload | null;
}) {
const wazuh = payload?.wazuh_soc_slice;
const assetCount = wazuh?.canonical_asset_count ?? 0;
const ownerAndTelemetryReady = Boolean(
wazuh &&
wazuh.owner_verified_asset_count === assetCount &&
wazuh.telemetry_covered_asset_count === assetCount &&
assetCount > 0,
);
const identityReady = Boolean(
wazuh && wazuh.identity_kind_count === wazuh.required_identity_kind_count,
);
const receiptVisible =
wazuh?.recipient_receipt_status === "recipient_visible";
const verifierRef = wazuh?.verifier_receipt_ref ?? "";
const recipientMessageRef = wazuh?.recipient_provider_message_ref ?? "";
return (
<div className="border-t border-[#d8d3c7] bg-[#f6f4ee] px-3 py-2">
<div className="mb-1.5 flex min-w-0 flex-wrap items-center justify-between gap-x-3 gap-y-1 text-[10px] font-semibold text-[#4f4d47]">
<div className="flex min-w-0 flex-wrap items-center gap-1.5">
<Radar className="h-3.5 w-3.5 shrink-0" aria-hidden="true" />
<span>{copy.wazuhSlice}</span>
<span className="max-w-full break-all font-mono text-[#17602a]">
{wazuh?.protected_asset_ref ?? wazuh?.canonical_asset_ref ?? "--"}
</span>
<span aria-hidden="true"></span>
<span className="max-w-full break-all font-mono text-[#17602a]">
{wazuh?.incident_ref ?? "--"}
</span>
</div>
<span
className="font-mono text-[#9f2f25]"
title={wazuh?.remaining_gap_codes.join(", ")}
>
{copy.remainingGaps} {wazuh?.remaining_gap_codes.length ?? "--"}
</span>
</div>
<div
className="grid grid-cols-2 gap-px bg-[#d8d3c7] sm:grid-cols-3 lg:grid-cols-6"
data-testid="security-wazuh-soc-truth"
>
<TruthCell
label={copy.protectedAssets}
value={wazuh ? `${wazuh.protected_asset_count}/${assetCount}` : "--"}
icon={ShieldCheck}
title={
wazuh?.protected_asset_ref
? `${copy.protectedAssets}: ${wazuh.protected_asset_ref}`
: undefined
}
tone={
(wazuh?.protected_asset_count ?? 0) > 0 ? "healthy" : "critical"
}
/>
<TruthCell
label={copy.ownerTelemetry}
value={
wazuh
? `${wazuh.owner_verified_asset_count}/${assetCount} · ${wazuh.telemetry_covered_asset_count}/${assetCount}`
: "--"
}
icon={Activity}
tone={ownerAndTelemetryReady ? "healthy" : "critical"}
/>
<TruthCell
label={copy.identityLink}
value={
wazuh
? `${wazuh.identity_kind_count}/${wazuh.required_identity_kind_count}`
: "--"
}
icon={Boxes}
tone={identityReady ? "healthy" : "critical"}
/>
<TruthCell
label={copy.incident}
value={
wazuh
? `${wazuh.same_run_closed ? copy.closed : copy.open} · ${wazuh.same_run_present_stage_count}/${wazuh.same_run_required_stage_count}`
: "--"
}
icon={wazuh?.same_run_closed ? CheckCircle2 : TriangleAlert}
tone={wazuh?.same_run_closed ? "healthy" : "critical"}
/>
<TruthCell
label={copy.verifier}
value={
wazuh?.verifier_status === "passed"
? `${copy.success} · ${verifierRef.slice(0, 8)}`
: copy.failed
}
icon={CheckCircle2}
tone={wazuh?.verifier_status === "passed" ? "healthy" : "critical"}
title={verifierRef ? `${copy.verifier}: ${verifierRef}` : undefined}
/>
<TruthCell
label={copy.recipientReceipt}
value={
receiptVisible
? `${copy.delivered} · #${recipientMessageRef}`
: copy.notEvidenced
}
icon={receiptVisible ? CheckCircle2 : ShieldAlert}
tone={receiptVisible ? "healthy" : "critical"}
title={
receiptVisible
? `${copy.recipientReceipt}: ${wazuh?.recipient_receipt_ref ?? "--"} / #${recipientMessageRef}`
: undefined
}
/>
</div>
</div>
);
}
function StageStrip({
title,
stages,
@@ -627,6 +786,10 @@ export function SecurityAssetControlPlaneCockpit({
</div>
) : null}
{view === "command" ? (
<WazuhSocTruthStrip copy={copy} payload={payload} />
) : null}
{view === "command" ? (
<div
className="grid grid-cols-3 gap-px border-t border-[#d8d3c7] bg-[#d8d3c7] lg:grid-cols-5"

View File

@@ -14,8 +14,8 @@ function payload(): SecurityAssetControlPlanePayload {
status: "ready",
source_status: "live_database_aggregate",
summary: {
source_count: 10,
ready_source_count: 10,
source_count: 12,
ready_source_count: 12,
unavailable_source_count: 0,
managed_asset_count: 24,
expected_asset_type_count: 28,
@@ -87,6 +87,43 @@ function payload(): SecurityAssetControlPlanePayload {
},
],
},
wazuh_soc_slice: {
schema_version: "iwooos_wazuh_ai_soc_slice_v1",
status: "same_run_closed_recipient_visible",
canonical_asset_count: 1,
canonical_asset_ref: "service:wazuh-manager",
protected_asset_count: 1,
protected_asset_ref: "service:wazuh-manager",
asset_graph_joined: true,
owner_resolved_asset_count: 1,
owner_verified_asset_count: 1,
telemetry_covered_asset_count: 1,
identity_kind_count: 5,
required_identity_kind_count: 5,
identity_kinds: ["manager", "agent", "host", "service", "event"],
incident_ref: "IWZ-POSTURE-2026072205",
incident_status: "resolved",
verifier_status: "passed",
verifier_receipt_ref: "verifier-wazuh-2205",
recipient_receipt_status: "recipient_visible",
recipient_receipt_ref: "telegram-wazuh-2205",
recipient_provider_message_ref: "2205",
same_run_present_stage_count: 18,
same_run_required_stage_count: 18,
same_run_closed: true,
critical_break_glass_required: true,
remaining_gap_codes: [
"wazuh_critical_ingress_break_glass_pending",
"global_wazuh_asset_coverage_not_proven",
],
domain_controlled_percent: 70,
domain_evidence_count: 7,
domain_gap_code: "wazuh_bounded_slice_closed_global_coverage_open",
coverage_overlay_applied_count: 2,
raw_identity_returned: false,
raw_event_payload_returned: false,
secret_value_read: false,
},
siem: { pipeline: [] },
ai_automation: {
stages: [],
@@ -184,6 +221,7 @@ function payload(): SecurityAssetControlPlanePayload {
live_scan_triggered: false,
runtime_action_triggered: false,
completion_requires_same_run_receipts: true,
wazuh_slice_is_global_coverage_claim: false,
},
};
}
@@ -219,6 +257,15 @@ describe("security asset control plane projection", () => {
false,
);
const unsafeWazuhIdentity = {
...safe,
wazuh_soc_slice: {
...safe.wazuh_soc_slice,
raw_identity_returned: true,
},
};
expect(isSecurityAssetControlPlanePayload(unsafeWazuhIdentity)).toBe(false);
const unsafeDiscovery = {
...safe,
discovery: {

View File

@@ -121,6 +121,44 @@ export type SecurityControlPlaneCertificateInventory = {
private_key_material_read: false;
};
export type SecurityWazuhSocSlice = {
schema_version: "iwooos_wazuh_ai_soc_slice_v1";
status: "same_run_closed_recipient_visible" | "partial" | "not_evidenced";
canonical_asset_count: number;
canonical_asset_ref: "service:wazuh-manager" | null;
protected_asset_count: number;
protected_asset_ref: "service:wazuh-manager" | null;
asset_graph_joined: boolean;
owner_resolved_asset_count: number;
owner_verified_asset_count: number;
telemetry_covered_asset_count: number;
identity_kind_count: number;
required_identity_kind_count: number;
identity_kinds: Array<"manager" | "agent" | "host" | "service" | "event">;
incident_ref: string | null;
incident_status: "resolved" | "open";
verifier_status: "passed" | "missing";
verifier_receipt_ref: string | null;
recipient_receipt_status:
| "recipient_visible"
| "suppressed_unchanged"
| "missing";
recipient_receipt_ref: string | null;
recipient_provider_message_ref: string | null;
same_run_present_stage_count: number;
same_run_required_stage_count: number;
same_run_closed: boolean;
critical_break_glass_required: boolean;
remaining_gap_codes: string[];
domain_controlled_percent: number;
domain_evidence_count: number;
domain_gap_code: string;
coverage_overlay_applied_count: number;
raw_identity_returned: false;
raw_event_payload_returned: false;
secret_value_read: false;
};
export type SecurityStrictRuntimeCompletion = {
schema_version: "ai_agent_strict_runtime_completion_v2";
runtime_contract_schema_version: "ai_automation_runtime_completion_contract_v2";
@@ -184,6 +222,7 @@ export type SecurityAssetControlPlanePayload = {
completion_percent: number;
}>;
};
wazuh_soc_slice: SecurityWazuhSocSlice;
siem: {
pipeline: SecurityControlPlaneStage[];
incident_total_24h?: number;
@@ -232,6 +271,7 @@ export type SecurityAssetControlPlanePayload = {
live_scan_triggered: boolean;
runtime_action_triggered: boolean;
completion_requires_same_run_receipts: boolean;
wazuh_slice_is_global_coverage_claim: false;
};
};
@@ -270,6 +310,98 @@ export function isSecurityAssetControlPlanePayload(
}
if (!isRecord(value.siem) || !Array.isArray(value.siem.pipeline))
return false;
const wazuh = value.wazuh_soc_slice;
const wazuhIdentityKinds = new Set([
"manager",
"agent",
"host",
"service",
"event",
]);
if (
!isRecord(wazuh) ||
wazuh.schema_version !== "iwooos_wazuh_ai_soc_slice_v1" ||
!["same_run_closed_recipient_visible", "partial", "not_evidenced"].includes(
String(wazuh.status),
) ||
typeof wazuh.canonical_asset_count !== "number" ||
!(
wazuh.canonical_asset_ref === null ||
wazuh.canonical_asset_ref === "service:wazuh-manager"
) ||
typeof wazuh.protected_asset_count !== "number" ||
!(
wazuh.protected_asset_ref === null ||
wazuh.protected_asset_ref === "service:wazuh-manager"
) ||
typeof wazuh.asset_graph_joined !== "boolean" ||
typeof wazuh.owner_resolved_asset_count !== "number" ||
typeof wazuh.owner_verified_asset_count !== "number" ||
typeof wazuh.telemetry_covered_asset_count !== "number" ||
typeof wazuh.identity_kind_count !== "number" ||
typeof wazuh.required_identity_kind_count !== "number" ||
!Array.isArray(wazuh.identity_kinds) ||
!wazuh.identity_kinds.every(
(identityKind) =>
typeof identityKind === "string" &&
wazuhIdentityKinds.has(identityKind),
) ||
new Set(wazuh.identity_kinds).size !== wazuh.identity_kinds.length ||
wazuh.identity_kind_count !== wazuh.identity_kinds.length ||
wazuh.required_identity_kind_count !== 5 ||
!(wazuh.incident_ref === null || typeof wazuh.incident_ref === "string") ||
!["resolved", "open"].includes(String(wazuh.incident_status)) ||
!["passed", "missing"].includes(String(wazuh.verifier_status)) ||
!(
wazuh.verifier_receipt_ref === null ||
typeof wazuh.verifier_receipt_ref === "string"
) ||
!["recipient_visible", "suppressed_unchanged", "missing"].includes(
String(wazuh.recipient_receipt_status),
) ||
!(
wazuh.recipient_receipt_ref === null ||
typeof wazuh.recipient_receipt_ref === "string"
) ||
!(
wazuh.recipient_provider_message_ref === null ||
typeof wazuh.recipient_provider_message_ref === "string"
) ||
typeof wazuh.same_run_present_stage_count !== "number" ||
wazuh.same_run_required_stage_count !== 18 ||
typeof wazuh.same_run_closed !== "boolean" ||
typeof wazuh.critical_break_glass_required !== "boolean" ||
!Array.isArray(wazuh.remaining_gap_codes) ||
!wazuh.remaining_gap_codes.every(
(gapCode) => typeof gapCode === "string",
) ||
typeof wazuh.domain_controlled_percent !== "number" ||
wazuh.domain_controlled_percent < 0 ||
wazuh.domain_controlled_percent > 70 ||
typeof wazuh.domain_evidence_count !== "number" ||
typeof wazuh.domain_gap_code !== "string" ||
typeof wazuh.coverage_overlay_applied_count !== "number" ||
wazuh.raw_identity_returned !== false ||
wazuh.raw_event_payload_returned !== false ||
wazuh.secret_value_read !== false ||
wazuh.protected_asset_count > wazuh.canonical_asset_count ||
(wazuh.asset_graph_joined &&
wazuh.canonical_asset_ref !== "service:wazuh-manager") ||
(wazuh.protected_asset_count === 1 &&
wazuh.protected_asset_ref !== wazuh.canonical_asset_ref) ||
(wazuh.status === "same_run_closed_recipient_visible" &&
(!wazuh.same_run_closed ||
!wazuh.asset_graph_joined ||
wazuh.same_run_present_stage_count !== 18 ||
wazuh.incident_status !== "resolved" ||
wazuh.verifier_status !== "passed" ||
!wazuh.verifier_receipt_ref ||
wazuh.recipient_receipt_status !== "recipient_visible" ||
!wazuh.recipient_receipt_ref ||
!wazuh.recipient_provider_message_ref))
) {
return false;
}
if (
!isRecord(value.ai_automation) ||
!Array.isArray(value.ai_automation.stages)
@@ -371,7 +503,8 @@ export function isSecurityAssetControlPlanePayload(
value.boundaries.raw_discovery_error_returned === false &&
value.boundaries.secret_value_collection_allowed === false &&
value.boundaries.live_scan_triggered === false &&
value.boundaries.runtime_action_triggered === false
value.boundaries.runtime_action_triggered === false &&
value.boundaries.wazuh_slice_is_global_coverage_claim === false
);
}