feat(web): add IwoooS host evidence readiness
This commit is contained in:
@@ -1319,6 +1319,48 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostEvidenceReadiness": {
|
||||
"title": "Host Evidence Readiness",
|
||||
"subtitle": "Lists the evidence required before host scans, updates, SSH changes, or runtime blocking can proceed. These items are waiting for collection and do not mean approval.",
|
||||
"evidenceLabel": "Required evidence",
|
||||
"items": {
|
||||
"scopeBoundary": {
|
||||
"title": "Scope boundary",
|
||||
"body": "Confirms allowed targets, exclusions, scan depth, and rate limits for 112, 168, and 111.",
|
||||
"evidence": "requires redacted scan scope approval; received=0, accepted=0"
|
||||
},
|
||||
"ownerDecision": {
|
||||
"title": "Owner decision record",
|
||||
"body": "Every host action needs human control; IwoooS visibility or AwoooP queue status cannot replace a decision.",
|
||||
"evidence": "requires accepted decision record; active runtime gates=0"
|
||||
},
|
||||
"credentialHandling": {
|
||||
"title": "Credential handling",
|
||||
"body": "Credentialed scans require defined credential source, storage boundary, redaction, and rejection rules.",
|
||||
"evidence": "credential material collection is forbidden; credentialed scan=false"
|
||||
},
|
||||
"maintenanceWindow": {
|
||||
"title": "Maintenance window",
|
||||
"body": "Kali updates, host tuning, or SSH changes need a maintenance window to avoid disrupting development and product flow.",
|
||||
"evidence": "requires window, impact scope, notification, and recovery criteria"
|
||||
},
|
||||
"rollbackPlan": {
|
||||
"title": "Rollback plan",
|
||||
"body": "Every host change needs a recovery path covering packages, settings, services, and toolchain versions.",
|
||||
"evidence": "requires rollback owner, steps, and validation method"
|
||||
},
|
||||
"validationMetrics": {
|
||||
"title": "Validation metrics",
|
||||
"body": "Host actions need post-check metrics to confirm scanners, monitoring, services, and user flows did not regress.",
|
||||
"evidence": "requires post-check metrics and failure lane"
|
||||
},
|
||||
"redactedIngestion": {
|
||||
"title": "Redacted ingestion",
|
||||
"body": "Host findings or scan results may only enter mirror as redacted summaries, not raw runtime input.",
|
||||
"evidence": "requires redacted payload acceptance; payloads_ingested=false"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nextGate": {
|
||||
"title": "Next High-level Gate",
|
||||
"body": "S4.9 Gitea owner attestation response is the recommended next owner evidence. Headline progress should only increase after owner responses, redacted payload ingestion, active runtime gates, or GitHub primary readiness actually change."
|
||||
|
||||
@@ -1320,6 +1320,48 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"hostEvidenceReadiness": {
|
||||
"title": "主機 Evidence Readiness",
|
||||
"subtitle": "列出主機掃描、更新、SSH 變更或 runtime blocking 前必須補齊的 evidence。這些項目目前都只是待收件,不代表已批准。",
|
||||
"evidenceLabel": "需要 Evidence",
|
||||
"items": {
|
||||
"scopeBoundary": {
|
||||
"title": "Scope boundary",
|
||||
"body": "確認 112、168、111 的允許目標、排除範圍、掃描深度與速率限制。",
|
||||
"evidence": "需要脫敏 scan scope approval;received=0、accepted=0"
|
||||
},
|
||||
"ownerDecision": {
|
||||
"title": "Owner decision record",
|
||||
"body": "每個主機動作都需要人控決策,不能用 IwoooS 可見狀態或 AwoooP queue 取代。",
|
||||
"evidence": "需要 accepted decision record;目前 active runtime gates=0"
|
||||
},
|
||||
"credentialHandling": {
|
||||
"title": "Credential handling",
|
||||
"body": "帶憑證掃描前要先定義憑證來源、保存邊界、遮蔽方式與拒收規則。",
|
||||
"evidence": "禁止收集憑證明文;目前 credentialed scan=false"
|
||||
},
|
||||
"maintenanceWindow": {
|
||||
"title": "Maintenance window",
|
||||
"body": "Kali 更新、主機調校或 SSH 變更都需要維護窗口,避免影響開發與產品流程。",
|
||||
"evidence": "需要窗口、影響範圍、通知與回復標準"
|
||||
},
|
||||
"rollbackPlan": {
|
||||
"title": "Rollback plan",
|
||||
"body": "任何主機變更都要能回復,包含套件、設定、服務與工具鏈版本。",
|
||||
"evidence": "需要 rollback owner、步驟與驗證方式"
|
||||
},
|
||||
"validationMetrics": {
|
||||
"title": "Validation metrics",
|
||||
"body": "主機動作後要有驗證指標,確認掃描器、監控、服務與使用者流程沒有退化。",
|
||||
"evidence": "需要 post-check 指標與失敗處理 lane"
|
||||
},
|
||||
"redactedIngestion": {
|
||||
"title": "Redacted ingestion",
|
||||
"body": "主機 finding 或掃描結果只能以脫敏摘要進入 mirror,不能直接把 raw payload 當 runtime input。",
|
||||
"evidence": "需要 redacted payload acceptance;payloads_ingested=false"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nextGate": {
|
||||
"title": "下一個高層 Gate",
|
||||
"body": "S4.9 Gitea owner attestation response 是目前建議先收的 owner evidence。任何 headline 提升都要等 owner response、redacted payload ingestion、active runtime gate 或 GitHub primary readiness 有真實變化。"
|
||||
|
||||
@@ -88,6 +88,13 @@ type HostActionGateItem = {
|
||||
tone: 'steady' | 'warn' | 'locked'
|
||||
}
|
||||
|
||||
type HostEvidenceReadinessItem = {
|
||||
key: string
|
||||
gate: string
|
||||
icon: typeof ShieldCheck
|
||||
tone: 'steady' | 'warn' | 'locked'
|
||||
}
|
||||
|
||||
const postureMetrics: PostureMetric[] = [
|
||||
{ key: 'overall', value: '58%', tone: 'warn' },
|
||||
{ key: 'framework', value: '80-85%', tone: 'steady' },
|
||||
@@ -199,6 +206,16 @@ const hostActionGateItems: HostActionGateItem[] = [
|
||||
{ key: 'runtimeBlocking', gate: 'S3.4', icon: ShieldCheck, tone: 'locked' },
|
||||
]
|
||||
|
||||
const hostEvidenceReadinessItems: HostEvidenceReadinessItem[] = [
|
||||
{ key: 'scopeBoundary', gate: 'S1.6', icon: Radar, tone: 'warn' },
|
||||
{ key: 'ownerDecision', gate: 'S3.1', icon: ClipboardCheck, tone: 'warn' },
|
||||
{ key: 'credentialHandling', gate: 'S1.6', icon: Lock, tone: 'locked' },
|
||||
{ key: 'maintenanceWindow', gate: 'S3.4', icon: Clock3, tone: 'warn' },
|
||||
{ key: 'rollbackPlan', gate: 'S3.4', icon: FileWarning, tone: 'warn' },
|
||||
{ key: 'validationMetrics', gate: 'S3.4', icon: CheckCircle2, tone: 'warn' },
|
||||
{ key: 'redactedIngestion', gate: 'S1.6', icon: ShieldCheck, tone: 'locked' },
|
||||
]
|
||||
|
||||
const evidenceItems = [
|
||||
'iwooos-posture-projection.snapshot.json',
|
||||
'security-rollout-policy.snapshot.json',
|
||||
@@ -501,6 +518,34 @@ function HostActionGateCard({ item, index }: { item: HostActionGateItem; index:
|
||||
)
|
||||
}
|
||||
|
||||
function HostEvidenceReadinessCard({ item, index }: { item: HostEvidenceReadinessItem; index: number }) {
|
||||
const t = useTranslations('iwooos.hostEvidenceReadiness')
|
||||
const Icon = item.icon
|
||||
return (
|
||||
<div style={{ ...band, minHeight: 184, padding: 16 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
|
||||
<Icon size={18} color={toneColors[item.tone]} />
|
||||
<span style={{ fontSize: 11, color: '#87867f' }}>{item.gate}</span>
|
||||
</div>
|
||||
<span style={{ fontSize: 11, color: '#9b978b' }}>{String(index + 1).padStart(2, '0')}</span>
|
||||
</div>
|
||||
<h2 style={{ fontSize: 14, margin: '12px 0 6px', color: '#141413' }}>
|
||||
{t(`items.${item.key}.title` as never)}
|
||||
</h2>
|
||||
<p style={{ fontSize: 12, lineHeight: 1.55, color: '#6f6d66', margin: 0 }}>
|
||||
{t(`items.${item.key}.body` as never)}
|
||||
</p>
|
||||
<div style={{ marginTop: 10, display: 'grid', gap: 5 }}>
|
||||
<div style={{ fontSize: 11, color: '#87867f' }}>{t('evidenceLabel')}</div>
|
||||
<div style={{ fontSize: 11, color: toneColors[item.tone], lineHeight: 1.45 }}>
|
||||
{t(`items.${item.key}.evidence` as never)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function IwoooSPage({ params }: { params: { locale: string } }) {
|
||||
const t = useTranslations('iwooos')
|
||||
|
||||
@@ -613,6 +658,26 @@ export default function IwoooSPage({ params }: { params: { locale: string } }) {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section style={{ marginBottom: 14 }}>
|
||||
<div style={{ marginBottom: 14 }}>
|
||||
<h2 style={{ fontSize: 16, margin: 0 }}>{t('hostEvidenceReadiness.title')}</h2>
|
||||
<p style={{ fontSize: 12, color: '#6f6d66', margin: '6px 0 0', lineHeight: 1.55 }}>
|
||||
{t('hostEvidenceReadiness.subtitle')}
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(auto-fit, minmax(210px, 1fr))',
|
||||
gap: 12,
|
||||
}}
|
||||
>
|
||||
{hostEvidenceReadinessItems.map((item, index) => (
|
||||
<HostEvidenceReadinessCard key={item.key} item={item} index={index} />
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section
|
||||
style={{
|
||||
display: 'grid',
|
||||
|
||||
Reference in New Issue
Block a user