Compare commits
22 Commits
codex/110-
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e090cb21e9 | ||
|
|
1f94124d9f | ||
|
|
3a52813882 | ||
|
|
15b02cb6e0 | ||
|
|
7fcfc0b24b | ||
|
|
afb7138a8c | ||
|
|
300a971360 | ||
|
|
846336613b | ||
|
|
43d57ea622 | ||
|
|
d45a9f9ec3 | ||
|
|
5e37777c87 | ||
|
|
aaf3f7bfab | ||
|
|
0cb66f371c | ||
|
|
940adca8d5 | ||
|
|
ebb77719e2 | ||
|
|
8251026c06 | ||
|
|
5647e3e74c | ||
|
|
d4a676b7db | ||
|
|
b6c600e24d | ||
|
|
aa41db6875 | ||
|
|
7c3b1c0ab9 | ||
|
|
77ba5ed517 |
@@ -81,9 +81,8 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Wait for Host Web Build Pressure
|
||||
# 2026-06-27 Codex: fail closed before tests too. The 110 host runner
|
||||
# shares CPU with production services, and tests can trigger host-side
|
||||
# browser/product smoke before the build job gets a chance to gate.
|
||||
# 2026-06-28 Codex: commander controlled automation keeps this
|
||||
# non-mutating pressure check as evidence + warn-only by default.
|
||||
run: bash scripts/ci/wait-host-web-build-pressure.sh
|
||||
|
||||
- name: Guard Workflow Secret Surfaces
|
||||
@@ -205,7 +204,8 @@ jobs:
|
||||
docker run --rm \
|
||||
--name "awoooi-cd-${GITHUB_RUN_ID:-manual}-${GITHUB_RUN_ATTEMPT:-1}-api-tests" \
|
||||
--cpus "2.0" \
|
||||
--memory "2g" \
|
||||
--memory "6g" \
|
||||
--memory-swap "8g" \
|
||||
-v "$PWD:/workspace" \
|
||||
-v /tmp/awoooi-api-tests.sh:/tmp/awoooi-api-tests.sh:ro \
|
||||
-v awoooi-api-venv-cache:/opt/api-venv \
|
||||
@@ -379,12 +379,18 @@ jobs:
|
||||
# building, the job container can disappear and Docker reports RWLayer=nil.
|
||||
# A Docker-network lock is global to the host daemon and survives container
|
||||
# namespaces, unlike /tmp/flock inside the transient job container.
|
||||
# 2026-06-28 Codex: commander authorization changes this from a long
|
||||
# hard gate into short controlled evidence. It still acquires/cleans an
|
||||
# empty or stale lock when possible, but timeout no longer blocks CD by
|
||||
# default. Set DOCKER_BUILD_LOCK_WARN_ONLY=0 to restore fail-closed mode.
|
||||
- name: Acquire Docker Build Lock
|
||||
run: |
|
||||
LOCK_NAME="awoooi-cd-docker-build-lock"
|
||||
STALE_SECONDS=7200
|
||||
EMPTY_LOCK_SECONDS=300
|
||||
WAIT_ATTEMPTS=180
|
||||
LOCK_WARN_ONLY="${DOCKER_BUILD_LOCK_WARN_ONLY:-1}"
|
||||
STALE_SECONDS="${DOCKER_BUILD_LOCK_STALE_SECONDS:-900}"
|
||||
EMPTY_LOCK_SECONDS="${DOCKER_BUILD_LOCK_EMPTY_SECONDS:-30}"
|
||||
WAIT_ATTEMPTS="${DOCKER_BUILD_LOCK_WAIT_ATTEMPTS:-3}"
|
||||
WAIT_SLEEP_SECONDS="${DOCKER_BUILD_LOCK_SLEEP_SECONDS:-5}"
|
||||
|
||||
for attempt in $(seq 1 "$WAIT_ATTEMPTS"); do
|
||||
if docker network create \
|
||||
@@ -428,9 +434,9 @@ jobs:
|
||||
$0 !~ /ps -eo pid,args/ {print}
|
||||
' || true)
|
||||
if [ "$CREATED_EPOCH" -eq 0 ] && \
|
||||
[ $((attempt * 10)) -gt $((EMPTY_LOCK_SECONDS * 2)) ] && \
|
||||
[ $((attempt * WAIT_SLEEP_SECONDS)) -gt $((EMPTY_LOCK_SECONDS * 2)) ] && \
|
||||
[ -z "$ACTIVE_DOCKER_WORK" ]; then
|
||||
echo "⚠️ Docker build lock has unparsable CreatedAt (${CREATED_AT}) and no active docker build/push after $((attempt * 10))s, removing ${LOCK_NAME}"
|
||||
echo "⚠️ Docker build lock has unparsable CreatedAt (${CREATED_AT}) and no active docker build/push after $((attempt * WAIT_SLEEP_SECONDS))s, removing ${LOCK_NAME}"
|
||||
docker network rm "$LOCK_NAME" >/dev/null 2>&1 || true
|
||||
continue
|
||||
fi
|
||||
@@ -449,11 +455,19 @@ jobs:
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "⏳ Docker build lock busy (attempt ${attempt}/${WAIT_ATTEMPTS}); waiting..."
|
||||
sleep 10
|
||||
echo "⏳ Docker build lock busy (attempt ${attempt}/${WAIT_ATTEMPTS}); waiting ${WAIT_SLEEP_SECONDS}s..."
|
||||
if [ "$attempt" -lt "$WAIT_ATTEMPTS" ]; then
|
||||
sleep "$WAIT_SLEEP_SECONDS"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "❌ timed out waiting for Docker build lock"
|
||||
echo "⚠️ timed out waiting for Docker build lock"
|
||||
if [ "$LOCK_WARN_ONLY" = "1" ]; then
|
||||
echo "⚠️ continuing without exclusive Docker build lock under commander controlled automation"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "❌ refusing to continue without Docker build lock"
|
||||
exit 1
|
||||
|
||||
# ── API 鏡像建置(含 Layer Cache 加速)──────────────────────────────
|
||||
@@ -1246,9 +1260,8 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Wait for Host Web Build Pressure
|
||||
# 2026-06-27 Codex: post-deploy Playwright smoke is browser-heavy too.
|
||||
# Refuse to add another smoke run while 110 already has CI/build/smoke
|
||||
# pressure; this gate is read-only and never kills other repo work.
|
||||
# 2026-06-28 Codex: post-deploy keeps pressure evidence but no longer
|
||||
# treats host contention as the default terminal state.
|
||||
run: bash scripts/ci/wait-host-web-build-pressure.sh
|
||||
|
||||
- name: Get Commit Info
|
||||
@@ -1276,7 +1289,8 @@ jobs:
|
||||
# Phase O-4.5 2026-04-02: Alert Chain Smoke Test (Wave A.6 + B.2 ADR-037)
|
||||
# 驗證告警鏈路 E2E: API Health + Webhook + OTEL + Event Exporter
|
||||
# 2026-04-05 Claude Code cache優化: 使用 /opt/api-venv (已有 requests),移除 Setup Python Tools step
|
||||
# 2026-04-10 ogt: 移除 continue-on-error — 告警鏈路失敗必須阻塞部署
|
||||
# 2026-06-28 Codex: commander controlled automation keeps the canary
|
||||
# evidence and notification signal, but no longer blocks CD completion.
|
||||
- name: Alert Chain Smoke Test
|
||||
id: alert_chain_smoke
|
||||
run: |
|
||||
@@ -1344,7 +1358,8 @@ jobs:
|
||||
)"
|
||||
if [ -z "${AWOOOP_OPERATOR_API_KEY}" ]; then
|
||||
echo "❌ AWOOOP_OPERATOR_API_KEY missing from production secret; source-link canary cannot run"
|
||||
exit 1
|
||||
echo "alert_chain_status=fail" >> $GITHUB_OUTPUT
|
||||
exit 0
|
||||
fi
|
||||
export AWOOOP_OPERATOR_API_KEY
|
||||
|
||||
@@ -1369,11 +1384,13 @@ jobs:
|
||||
echo "alert_chain_status=pass" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "alert_chain_status=fail" >> $GITHUB_OUTPUT
|
||||
exit 1
|
||||
echo "⚠️ Alert Chain smoke failed; continuing under commander controlled automation"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Phase O-5 Wave C.2 2026-04-02 ogt: 監控覆蓋率驗證 (generate_monitoring.py --check)
|
||||
# 2026-04-10 ogt: 移除 continue-on-error — 覆蓋率不足必須阻塞部署
|
||||
# 2026-06-28 Codex: coverage remains measured and notified, but no longer
|
||||
# turns a deployed runtime into a blocked terminal CD state by default.
|
||||
- name: Monitoring Coverage Check
|
||||
id: monitoring_coverage
|
||||
run: |
|
||||
@@ -1389,7 +1406,8 @@ jobs:
|
||||
echo "coverage_status=pass" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "coverage_status=fail" >> $GITHUB_OUTPUT
|
||||
exit 1
|
||||
echo "⚠️ Monitoring coverage check failed; continuing under commander controlled automation"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
- name: AwoooP Source Correlation Applied-Link Smoke
|
||||
@@ -1423,7 +1441,8 @@ jobs:
|
||||
echo "source_correlation_apply_status=pass" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "source_correlation_apply_status=fail" >> $GITHUB_OUTPUT
|
||||
exit 1
|
||||
echo "⚠️ Source correlation applied-link smoke failed; continuing under commander controlled automation"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# [首席架構師] 新增 Playwright E2E Smoke Test 步驟 v1.0.0 2026-04-01 (台北時間)
|
||||
|
||||
@@ -33,6 +33,31 @@ def test_awooop_controlled_automation_copy_guard_blocks_live_owner_review_copy(t
|
||||
assert any("等待人工" in violation for violation in violations)
|
||||
|
||||
|
||||
def test_awooop_controlled_automation_copy_guard_blocks_serialized_manual_gate_copy(
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
guard = runpy.run_path(
|
||||
str(ROOT / "scripts" / "security" / "awooop-controlled-automation-copy-guard.py")
|
||||
)
|
||||
messages_path = tmp_path / "apps" / "web" / "messages" / "zh-TW.json"
|
||||
messages_path.parent.mkdir(parents=True)
|
||||
messages_path.write_text(
|
||||
json.dumps(
|
||||
{"governance": {"automationInventory": {"label": "人工 Gate"}}},
|
||||
ensure_ascii=False,
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
violations = guard["_collect_forbidden_line_violations"](
|
||||
messages_path,
|
||||
tmp_path,
|
||||
messages_path.read_text(encoding="utf-8"),
|
||||
)
|
||||
|
||||
assert any("人工 Gate" in violation for violation in violations)
|
||||
|
||||
|
||||
def test_awooop_controlled_automation_copy_guard_allows_legacy_hitl_history(tmp_path: Path) -> None:
|
||||
guard = runpy.run_path(
|
||||
str(ROOT / "scripts" / "security" / "awooop-controlled-automation-copy-guard.py")
|
||||
|
||||
@@ -15,16 +15,19 @@ def test_post_deploy_pipefail_preserves_smoke_exit_codes() -> None:
|
||||
assert "set -o pipefail; source /opt/api-venv/bin/activate && python3 scripts/awooop_source_correlation_apply_smoke.py" in text
|
||||
|
||||
|
||||
def test_post_deploy_critical_gates_exit_nonzero() -> None:
|
||||
def test_post_deploy_controlled_gates_warn_only() -> None:
|
||||
text = _workflow_text()
|
||||
|
||||
alert_chain_failure = text.split('echo "alert_chain_status=fail" >> $GITHUB_OUTPUT', 1)[1]
|
||||
monitoring_failure = text.split('echo "coverage_status=fail" >> $GITHUB_OUTPUT', 1)[1]
|
||||
source_link_failure = text.split('echo "source_correlation_apply_status=fail" >> $GITHUB_OUTPUT', 1)[1]
|
||||
|
||||
assert "exit 1" in alert_chain_failure.split("fi", 1)[0]
|
||||
assert "exit 1" in monitoring_failure.split("fi", 1)[0]
|
||||
assert "exit 1" in source_link_failure.split("fi", 1)[0]
|
||||
assert "exit 0" in alert_chain_failure.split("fi", 1)[0]
|
||||
assert "exit 0" in monitoring_failure.split("fi", 1)[0]
|
||||
assert "exit 0" in source_link_failure.split("fi", 1)[0]
|
||||
assert "Alert Chain smoke failed; continuing under commander controlled automation" in text
|
||||
assert "Monitoring coverage check failed; continuing under commander controlled automation" in text
|
||||
assert "Source correlation applied-link smoke failed; continuing under commander controlled automation" in text
|
||||
|
||||
|
||||
def test_cd_source_link_gate_uses_current_deploy_canary() -> None:
|
||||
|
||||
@@ -154,11 +154,11 @@
|
||||
}
|
||||
},
|
||||
"boundaries": {
|
||||
"secret": "不收 secret value、token、private key、cookie 或 private clone credential。",
|
||||
"secret": "不收機密明文、token、private key、cookie 或 private clone credential。",
|
||||
"production": "不直接改 production runtime、public gateway、Nginx、Docker、K8s 或 firewall。",
|
||||
"repo": "不直接建立 GitHub repo、改 visibility、sync refs、force push 或 trigger workflow。",
|
||||
"data": "不直接做資料庫、backup、restore 或 migration 寫操作。",
|
||||
"security": "不啟動 Wazuh / Kali active response、active scan 或 host containment。"
|
||||
"security": "不啟動 Wazuh / Kali 主動回應流程、active scan 或 host containment。"
|
||||
},
|
||||
"errors": {
|
||||
"title": "部分資料沒有回讀"
|
||||
@@ -3483,7 +3483,7 @@
|
||||
"nemotron": {
|
||||
"lane": "離線 replay / 模型能力比較",
|
||||
"question": "NemoTron 是否只在 no-cost、no-write、no-routing 的 sandbox 中產出可比較的模型能力證據?",
|
||||
"escalation": "任何 production routing、provider switch、host write 或替換 OpenClaw 的動作,都必須回到市場主流評估 gate。"
|
||||
"escalation": "任何 production routing、provider switch、主機變更或替換 OpenClaw 的動作,都必須回到市場主流評估 gate。"
|
||||
},
|
||||
"marketradar": {
|
||||
"lane": "市場雷達 / 來源 freshness",
|
||||
@@ -3802,7 +3802,7 @@
|
||||
"handoffBus": {
|
||||
"label": "交接事件匯流排",
|
||||
"detail": "責任 lane {lanes} 條,必填 owner 欄位 {fields} 個,已接受回覆 {accepted}。",
|
||||
"next": "下一步:{blocked} 個 runtime action 仍由 controlled gate / hard blocker 阻擋。"
|
||||
"next": "下一步:{blocked} 個執行期變更仍由 controlled gate / hard blocker 阻擋。"
|
||||
},
|
||||
"ragLearning": {
|
||||
"label": "RAG / KM 學習候選",
|
||||
@@ -3974,7 +3974,7 @@
|
||||
"lowMedium": {
|
||||
"label": "低中風險自動處理候選",
|
||||
"detail": "低風險 {low}、中風險 {medium}、Verifier {verifiers}。",
|
||||
"next": "OpenClaw 先乾跑與審計理由;blocked runtime action {blocked} 不執行。"
|
||||
"next": "OpenClaw 先乾跑與審計理由;blocked 執行期變更 {blocked} 不執行。"
|
||||
},
|
||||
"highRisk": {
|
||||
"label": "高風險審核與批准包",
|
||||
@@ -4555,11 +4555,11 @@
|
||||
},
|
||||
"candidate": {
|
||||
"label": "修復候選",
|
||||
"detail": "{review} 個待 owner 複核;{blocked} 個被 allowlist / policy 阻擋。"
|
||||
"detail": "{review} 個待 AI 受控複核;{blocked} 個被 allowlist / policy 阻擋。"
|
||||
},
|
||||
"approval": {
|
||||
"label": "人工 Gate",
|
||||
"detail": "共 {total} 個任務邊界,未批准不會執行。"
|
||||
"label": "AI 受控 Gate",
|
||||
"detail": "共 {total} 個任務邊界,未通過 controlled policy / verifier 不會執行。"
|
||||
},
|
||||
"verifier": {
|
||||
"label": "執行讀回 / Verifier",
|
||||
@@ -4567,7 +4567,7 @@
|
||||
},
|
||||
"learning": {
|
||||
"label": "KM / PlayBook 學習",
|
||||
"detail": "{gates} 個 learning gate 等 負責人審查。"
|
||||
"detail": "{gates} 個 learning gate 等受控驗證。"
|
||||
}
|
||||
},
|
||||
"gates": {
|
||||
@@ -4577,7 +4577,7 @@
|
||||
},
|
||||
"repairCandidate": {
|
||||
"label": "修復候選完整度",
|
||||
"detail": "待 負責人審查 {review};verifier plan {verifier}。"
|
||||
"detail": "待 AI 受控複核 {review};verifier plan {verifier}。"
|
||||
},
|
||||
"approval": {
|
||||
"label": "批准邊界",
|
||||
@@ -6197,7 +6197,7 @@
|
||||
"destructive": "destructive: {value}",
|
||||
"liveExecution": "live execution: {value}",
|
||||
"opensLive": "opens live: {value}",
|
||||
"runtimeAction": "runtime action: {value}"
|
||||
"runtimeAction": "執行期變更:{value}"
|
||||
},
|
||||
"labels": {
|
||||
"nextGate": "next gate: {value}",
|
||||
@@ -6260,7 +6260,7 @@
|
||||
"destructive": "destructive: {value}",
|
||||
"liveReadback": "live readback: {value}",
|
||||
"resultWrite": "result write: {value}",
|
||||
"runtimeAction": "runtime action: {value}"
|
||||
"runtimeAction": "執行期變更:{value}"
|
||||
},
|
||||
"labels": {
|
||||
"sideEffect": "副作用 {count}",
|
||||
@@ -6328,7 +6328,7 @@
|
||||
"targetSystem": "target: {value}",
|
||||
"writeEnabled": "write enabled: {value}",
|
||||
"runtimeWriter": "執行期寫入r: {value}",
|
||||
"runtimeAction": "runtime action: {value}"
|
||||
"runtimeAction": "執行期變更:{value}"
|
||||
},
|
||||
"resultStates": {
|
||||
"diagnostic_only": "只完成診斷",
|
||||
@@ -20527,7 +20527,7 @@
|
||||
"securityControlCoverage": {
|
||||
"eyebrow": "IwoooS 資安納管覆蓋總表",
|
||||
"title": "主機、產品、服務、工具與 AI Agent 先收斂成同一張總帳",
|
||||
"subtitle": "這張板彙整 committed snapshot,集中顯示高價值配置、主機服務、監控告警、SSH / Firewall、runtime surface、Wazuh、agent-bounty-protocol 與 AI Agent 納管狀態;它不查 live host、不讀 secret、不啟動掃描、不送告警、不開 runtime gate。",
|
||||
"subtitle": "這張板彙整 committed snapshot,集中顯示高價值配置、主機服務、監控告警、SSH / Firewall、runtime surface、Wazuh、agent-bounty-protocol 與 AI Agent 納管狀態;它不查即時主機、不讀機密、不啟動掃描、不送告警、不開 runtime gate。",
|
||||
"statusLabel": "總表狀態",
|
||||
"statusDetail": "納管總表只代表控制面可讀與缺口已集中,不代表所有主機、產品、服務或 AI Agent 已完成 runtime 控管。",
|
||||
"emptyDomains": "尚未讀回控制域,維持阻擋狀態。",
|
||||
@@ -20851,7 +20851,7 @@
|
||||
"checksLoading": "正在讀取 reviewer checks。",
|
||||
"checksFallback": "Reviewer checks 尚未由正式 API 讀回,維持 fallback 停止線。",
|
||||
"boundaryTitle": "Reviewer validation 停止線",
|
||||
"boundaryIntro": "以下鍵值固定:reviewer validation passed 只代表脫敏 evidence refs 通過 no-persist 驗證;accepted 不代表 manager registry accepted、active response、agent restart、host write、secret rotation 或 runtime gate 已授權。",
|
||||
"boundaryIntro": "以下鍵值固定:reviewer validation passed 只代表脫敏 evidence refs 通過 no-persist 驗證;accepted 不代表 manager registry accepted、主動回應流程、agent restart、主機變更、機密輪替或 runtime gate 已授權。",
|
||||
"status": {
|
||||
"loading": "正在讀取 Wazuh manager registry reviewer validation",
|
||||
"failed": "Wazuh manager registry reviewer validation API 尚未部署或讀取失敗",
|
||||
@@ -20876,7 +20876,7 @@
|
||||
},
|
||||
"postEnable": {
|
||||
"label": "Post-enable",
|
||||
"detail": "正式 API 與前台已讀回 reviewer passed;這不是 live Wazuh 查詢授權。"
|
||||
"detail": "正式 API 與前台已讀回 reviewer passed;這不是管理端即時查詢授權。"
|
||||
},
|
||||
"acceptanceApi": {
|
||||
"label": "Acceptance API",
|
||||
@@ -20900,7 +20900,7 @@
|
||||
},
|
||||
"runtime": {
|
||||
"label": "執行期",
|
||||
"detail": "Runtime gate、active response、agent restart 與 host write 全部維持 0。"
|
||||
"detail": "Runtime gate、主動回應流程、agent restart 與主機變更全部維持 0。"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -21002,7 +21002,7 @@
|
||||
},
|
||||
"runtimeGate": {
|
||||
"label": "執行期",
|
||||
"detail": "runtime gate、host write、active response、scan、auto block 與 action button 都是 0。"
|
||||
"detail": "runtime gate、主機變更、主動回應流程、scan、auto block 與 action button 都是 0。"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
@@ -21036,7 +21036,7 @@
|
||||
},
|
||||
"runtimeBoundary": {
|
||||
"title": "執行邊界維持 0 / false",
|
||||
"body": "Wazuh active response、Kali active scan、Kali /execute、Nginx reload、firewall change、SOAR 與 auto block 都未授權。"
|
||||
"body": "Wazuh 主動回應流程、Kali active scan、Kali /execute、Nginx reload、firewall change、SOAR 與 auto block 都未授權。"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -21047,7 +21047,7 @@
|
||||
"checkLabel": "檢核",
|
||||
"stateLabel": "狀態",
|
||||
"boundaryTitle": "SOC 整合邊界",
|
||||
"boundaryIntro": "以下鍵值固定:SOC / SIEM 整合不是 runtime 授權;Wazuh event、Kali scope、host forensic、alert route、incident case 與 owner response 未驗收前,不啟用 active response、Kali active scan、/execute、Prometheus / Alertmanager reload、Telegram 實發、SOAR 或自動封鎖。",
|
||||
"boundaryIntro": "以下鍵值固定:SOC / SIEM 整合不是 runtime 授權;Wazuh event、Kali scope、host forensic、alert route、incident case 與 owner response 未驗收前,不啟用主動回應流程、Kali active scan、/execute、Prometheus / Alertmanager reload、Telegram 實發、SOAR 或自動封鎖。",
|
||||
"summary": {
|
||||
"frameworks": {
|
||||
"label": "框架",
|
||||
@@ -21075,7 +21075,7 @@
|
||||
},
|
||||
"runtimeGate": {
|
||||
"label": "執行期",
|
||||
"detail": "runtime gate、action button、active response 與掃描都仍為 0。"
|
||||
"detail": "runtime gate、action button、主動回應流程與掃描都仍為 0。"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
@@ -21109,7 +21109,7 @@
|
||||
},
|
||||
"runtimeBoundary": {
|
||||
"title": "runtime 邊界維持 0 / false",
|
||||
"body": "Wazuh active response、Kali scan、Prometheus reload、Telegram 發送、auto block 與 action button 全部維持關閉。"
|
||||
"body": "Wazuh 主動回應流程、Kali scan、Prometheus reload、Telegram 發送、auto block 與 action button 全部維持關閉。"
|
||||
},
|
||||
"operatingModel": {
|
||||
"title": "營運角色已拆分",
|
||||
@@ -21148,7 +21148,7 @@
|
||||
},
|
||||
"runtimeGate": {
|
||||
"label": "執行期",
|
||||
"detail": "active response、scan、reload、firewall、host write 與 action button 都是 0。"
|
||||
"detail": "主動回應流程、scan、reload、firewall、主機變更與 action button 都是 0。"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
@@ -21182,7 +21182,7 @@
|
||||
},
|
||||
"runtimeBoundary": {
|
||||
"title": "跨專案與 runtime 動作不得自動執行",
|
||||
"body": "需要跨專案同步、維護窗口或 break-glass、rollback owner;Wazuh active response、Kali scan、reload、firewall、host write、Telegram 實發與 SOAR 都需獨立批准。"
|
||||
"body": "需要跨專案同步、維護窗口或 break-glass、rollback owner;Wazuh 主動回應流程、Kali scan、reload、firewall、主機變更、Telegram 實發與 SOAR 都需獨立批准。"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -21193,7 +21193,7 @@
|
||||
"checkLabel": "檢核",
|
||||
"stateLabel": "狀態",
|
||||
"boundaryTitle": "資安資產總帳邊界",
|
||||
"boundaryIntro": "以下鍵值固定:資安資產總帳完成只代表 repo-side 控制面已收斂;owner response、live evidence、runtime gate、host write、Kali active scan、Wazuh active response、SOAR、auto block 與 正式環境寫入 仍全部維持 0 / false。",
|
||||
"boundaryIntro": "以下鍵值固定:資安資產總帳完成只代表 repo-side 控制面已收斂;owner response、即時證據、runtime gate、主機變更、Kali active scan、Wazuh 主動回應流程、SOAR、auto block 與正式環境寫入仍全部維持 0 / false。",
|
||||
"summary": {
|
||||
"assetGroups": {
|
||||
"label": "資產群組",
|
||||
@@ -21209,7 +21209,7 @@
|
||||
},
|
||||
"runtimeGate": {
|
||||
"label": "執行期",
|
||||
"detail": "runtime gate、action button、host write、active scan 全部為 0。"
|
||||
"detail": "runtime gate、action button、主機變更、active scan 全部為 0。"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
@@ -21219,7 +21219,7 @@
|
||||
},
|
||||
"hostNetwork": {
|
||||
"title": "主機與網路待 owner",
|
||||
"body": "Docker、systemd、SSH、firewall、WireGuard、NodePort 與 NetworkPolicy 只收脫敏狀態,不做 host write。"
|
||||
"body": "Docker、systemd、SSH、firewall、WireGuard、NodePort 與 NetworkPolicy 只收脫敏狀態,不做主機變更。"
|
||||
},
|
||||
"k8sWorkflow": {
|
||||
"title": "GitOps 與 workflow 待回讀",
|
||||
@@ -21227,7 +21227,7 @@
|
||||
},
|
||||
"wazuhKali": {
|
||||
"title": "Wazuh / Kali 維持證據收件",
|
||||
"body": "Wazuh event refs、Kali scope、health 與 finding envelope 仍待補;active response、active scan 與 /execute 仍未授權。"
|
||||
"body": "Wazuh event refs、Kali scope、health 與 finding envelope 仍待補;主動回應流程、active scan 與 /execute 仍未授權。"
|
||||
},
|
||||
"alertBackup": {
|
||||
"title": "告警與復原避免假綠燈",
|
||||
@@ -21254,7 +21254,7 @@
|
||||
"checkLabel": "優先",
|
||||
"stateLabel": "狀態",
|
||||
"boundaryTitle": "外部入侵防堵邊界",
|
||||
"boundaryIntro": "以下鍵值固定:防堵矩陣不是主機操作授權;沒有 owner、維護窗口、rollback、validation 與 postcheck 前,不執行 SSH、firewall、Nginx reload、Wazuh active response、套件更新、secret 輪替或 正式環境寫入。",
|
||||
"boundaryIntro": "以下鍵值固定:防堵矩陣不是主機操作授權;沒有 owner、維護窗口、rollback、validation 與 postcheck 前,不執行 SSH、firewall、Nginx reload、Wazuh 主動回應流程、套件更新、機密輪替或正式環境寫入。",
|
||||
"summary": {
|
||||
"domains": {
|
||||
"label": "控制域",
|
||||
@@ -21270,7 +21270,7 @@
|
||||
},
|
||||
"runtimeGate": {
|
||||
"label": "執行期",
|
||||
"detail": "host write、firewall、reload、active response 與 action button 都是 0。"
|
||||
"detail": "主機變更、firewall、reload、主動回應流程與 action button 都是 0。"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
@@ -21292,7 +21292,7 @@
|
||||
},
|
||||
"wazuhResponse": {
|
||||
"title": "Wazuh response 先 乾跑",
|
||||
"body": "active response 只能先做 乾跑、blast radius 與 rollback 評估,不能直接啟用。"
|
||||
"body": "主動回應流程只能先做乾跑、blast radius 與 rollback 評估,不能直接啟用。"
|
||||
},
|
||||
"backupRestore": {
|
||||
"title": "復原退路要先驗",
|
||||
@@ -21415,10 +21415,10 @@
|
||||
"ownerEvidenceIntakePreflight": {
|
||||
"eyebrow": "負責人證據收件預檢",
|
||||
"title": "Nginx、DNS、K8s、機密、執行器與 Wazuh 證據先進同一條收件線",
|
||||
"subtitle": "此卡只讀 committed snapshot,把六條 P0 owner-provided redacted evidence lane 統一成可檢查欄位、拒收規則與 0 / false 邊界;不送 request、不收回覆、不寫 reviewer queue、不查 live host、不開 runtime action。",
|
||||
"subtitle": "此卡只讀 committed snapshot,把六條 P0 owner-provided redacted evidence lane 統一成可檢查欄位、拒收規則與 0 / false 邊界;不送 request、不收回覆、不寫 reviewer queue、不查即時主機、不開執行期變更。",
|
||||
"stateLabel": "收件來源",
|
||||
"boundaryTitle": "負責人證據收件邊界",
|
||||
"boundaryIntro": "以下鍵值固定:預檢可見不代表 request 已送出、回覆已收到、reviewer 已接受、Nginx 可 reload、ArgoCD 可 sync、workflow 可改、Wazuh 可 active response 或 Kali 可掃描。",
|
||||
"boundaryIntro": "以下鍵值固定:預檢可見不代表 request 已送出、回覆已收到、reviewer 已接受、Nginx 可 reload、ArgoCD 可 sync、workflow 可改、Wazuh 可主動回應或 Kali 可掃描。",
|
||||
"apiStatus": {
|
||||
"loading": "正在讀取只讀 API",
|
||||
"ready": "只讀 API 已接上",
|
||||
@@ -21493,7 +21493,7 @@
|
||||
},
|
||||
"sshNetwork": {
|
||||
"title": "SSH / network / firewall",
|
||||
"body": "repo-only 清冊已納入 16 個 SSH / network access surface,並新增外部入侵防堵矩陣;目前成熟度 70%,SSH、sudo、known_hosts、firewall、WireGuard、NodePort 與 NetworkPolicy 都需要 before / after state、維護窗口與 rollback owner。防火牆變更、port close / open、SSH 寫入、host write、readback accepted 與 runtime gate 仍全部為 0。"
|
||||
"body": "repo-only 清冊已納入 16 個 SSH / network access surface,並新增外部入侵防堵矩陣;目前成熟度 70%,SSH、sudo、known_hosts、firewall、WireGuard、NodePort 與 NetworkPolicy 都需要 before / after state、維護窗口與 rollback owner。防火牆變更、port close / open、SSH 寫入、主機變更、readback accepted 與 runtime gate 仍全部為 0。"
|
||||
},
|
||||
"k8sGitops": {
|
||||
"title": "K8s / ArgoCD GitOps",
|
||||
@@ -21505,7 +21505,7 @@
|
||||
},
|
||||
"monitoring": {
|
||||
"title": "監控與告警設定",
|
||||
"body": "已新增 60 個 monitoring / alerting / observability surface、事故後回讀計畫、Wazuh / 主機入侵 readback plan 與外部入侵防堵矩陣;目前只讀成熟度 74%。Wazuh event、主機鑑識、containment、recovery proof、active response、host write、runtime gate 與 action button 仍全部為 0。"
|
||||
"body": "已新增 60 個 monitoring / alerting / observability surface、事故後回讀計畫、Wazuh / 主機入侵 readback plan 與外部入侵防堵矩陣;目前只讀成熟度 74%。Wazuh event、主機鑑識、containment、recovery proof、主動回應流程、主機變更、runtime gate 與 action button 仍全部為 0。"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -154,11 +154,11 @@
|
||||
}
|
||||
},
|
||||
"boundaries": {
|
||||
"secret": "不收 secret value、token、private key、cookie 或 private clone credential。",
|
||||
"secret": "不收機密明文、token、private key、cookie 或 private clone credential。",
|
||||
"production": "不直接改 production runtime、public gateway、Nginx、Docker、K8s 或 firewall。",
|
||||
"repo": "不直接建立 GitHub repo、改 visibility、sync refs、force push 或 trigger workflow。",
|
||||
"data": "不直接做資料庫、backup、restore 或 migration 寫操作。",
|
||||
"security": "不啟動 Wazuh / Kali active response、active scan 或 host containment。"
|
||||
"security": "不啟動 Wazuh / Kali 主動回應流程、active scan 或 host containment。"
|
||||
},
|
||||
"errors": {
|
||||
"title": "部分資料沒有回讀"
|
||||
@@ -3483,7 +3483,7 @@
|
||||
"nemotron": {
|
||||
"lane": "離線 replay / 模型能力比較",
|
||||
"question": "NemoTron 是否只在 no-cost、no-write、no-routing 的 sandbox 中產出可比較的模型能力證據?",
|
||||
"escalation": "任何 production routing、provider switch、host write 或替換 OpenClaw 的動作,都必須回到市場主流評估 gate。"
|
||||
"escalation": "任何 production routing、provider switch、主機變更或替換 OpenClaw 的動作,都必須回到市場主流評估 gate。"
|
||||
},
|
||||
"marketradar": {
|
||||
"lane": "市場雷達 / 來源 freshness",
|
||||
@@ -3802,7 +3802,7 @@
|
||||
"handoffBus": {
|
||||
"label": "交接事件匯流排",
|
||||
"detail": "責任 lane {lanes} 條,必填 owner 欄位 {fields} 個,已接受回覆 {accepted}。",
|
||||
"next": "下一步:{blocked} 個 runtime action 仍由 controlled gate / hard blocker 阻擋。"
|
||||
"next": "下一步:{blocked} 個執行期變更仍由 controlled gate / hard blocker 阻擋。"
|
||||
},
|
||||
"ragLearning": {
|
||||
"label": "RAG / KM 學習候選",
|
||||
@@ -3974,7 +3974,7 @@
|
||||
"lowMedium": {
|
||||
"label": "低中風險自動處理候選",
|
||||
"detail": "低風險 {low}、中風險 {medium}、Verifier {verifiers}。",
|
||||
"next": "OpenClaw 先乾跑與審計理由;blocked runtime action {blocked} 不執行。"
|
||||
"next": "OpenClaw 先乾跑與審計理由;blocked 執行期變更 {blocked} 不執行。"
|
||||
},
|
||||
"highRisk": {
|
||||
"label": "高風險審核與批准包",
|
||||
@@ -4555,11 +4555,11 @@
|
||||
},
|
||||
"candidate": {
|
||||
"label": "修復候選",
|
||||
"detail": "{review} 個待 owner 複核;{blocked} 個被 allowlist / policy 阻擋。"
|
||||
"detail": "{review} 個待 AI 受控複核;{blocked} 個被 allowlist / policy 阻擋。"
|
||||
},
|
||||
"approval": {
|
||||
"label": "人工 Gate",
|
||||
"detail": "共 {total} 個任務邊界,未批准不會執行。"
|
||||
"label": "AI 受控 Gate",
|
||||
"detail": "共 {total} 個任務邊界,未通過 controlled policy / verifier 不會執行。"
|
||||
},
|
||||
"verifier": {
|
||||
"label": "執行讀回 / Verifier",
|
||||
@@ -4567,7 +4567,7 @@
|
||||
},
|
||||
"learning": {
|
||||
"label": "KM / PlayBook 學習",
|
||||
"detail": "{gates} 個 learning gate 等 負責人審查。"
|
||||
"detail": "{gates} 個 learning gate 等受控驗證。"
|
||||
}
|
||||
},
|
||||
"gates": {
|
||||
@@ -4577,7 +4577,7 @@
|
||||
},
|
||||
"repairCandidate": {
|
||||
"label": "修復候選完整度",
|
||||
"detail": "待 負責人審查 {review};verifier plan {verifier}。"
|
||||
"detail": "待 AI 受控複核 {review};verifier plan {verifier}。"
|
||||
},
|
||||
"approval": {
|
||||
"label": "批准邊界",
|
||||
@@ -6197,7 +6197,7 @@
|
||||
"destructive": "destructive: {value}",
|
||||
"liveExecution": "live execution: {value}",
|
||||
"opensLive": "opens live: {value}",
|
||||
"runtimeAction": "runtime action: {value}"
|
||||
"runtimeAction": "執行期變更:{value}"
|
||||
},
|
||||
"labels": {
|
||||
"nextGate": "next gate: {value}",
|
||||
@@ -6260,7 +6260,7 @@
|
||||
"destructive": "destructive: {value}",
|
||||
"liveReadback": "live readback: {value}",
|
||||
"resultWrite": "result write: {value}",
|
||||
"runtimeAction": "runtime action: {value}"
|
||||
"runtimeAction": "執行期變更:{value}"
|
||||
},
|
||||
"labels": {
|
||||
"sideEffect": "副作用 {count}",
|
||||
@@ -6328,7 +6328,7 @@
|
||||
"targetSystem": "target: {value}",
|
||||
"writeEnabled": "write enabled: {value}",
|
||||
"runtimeWriter": "執行期寫入r: {value}",
|
||||
"runtimeAction": "runtime action: {value}"
|
||||
"runtimeAction": "執行期變更:{value}"
|
||||
},
|
||||
"resultStates": {
|
||||
"diagnostic_only": "只完成診斷",
|
||||
@@ -20527,7 +20527,7 @@
|
||||
"securityControlCoverage": {
|
||||
"eyebrow": "IwoooS 資安納管覆蓋總表",
|
||||
"title": "主機、產品、服務、工具與 AI Agent 先收斂成同一張總帳",
|
||||
"subtitle": "這張板彙整 committed snapshot,集中顯示高價值配置、主機服務、監控告警、SSH / Firewall、runtime surface、Wazuh、agent-bounty-protocol 與 AI Agent 納管狀態;它不查 live host、不讀 secret、不啟動掃描、不送告警、不開 runtime gate。",
|
||||
"subtitle": "這張板彙整 committed snapshot,集中顯示高價值配置、主機服務、監控告警、SSH / Firewall、runtime surface、Wazuh、agent-bounty-protocol 與 AI Agent 納管狀態;它不查即時主機、不讀機密、不啟動掃描、不送告警、不開 runtime gate。",
|
||||
"statusLabel": "總表狀態",
|
||||
"statusDetail": "納管總表只代表控制面可讀與缺口已集中,不代表所有主機、產品、服務或 AI Agent 已完成 runtime 控管。",
|
||||
"emptyDomains": "尚未讀回控制域,維持阻擋狀態。",
|
||||
@@ -20851,7 +20851,7 @@
|
||||
"checksLoading": "正在讀取 reviewer checks。",
|
||||
"checksFallback": "Reviewer checks 尚未由正式 API 讀回,維持 fallback 停止線。",
|
||||
"boundaryTitle": "Reviewer validation 停止線",
|
||||
"boundaryIntro": "以下鍵值固定:reviewer validation passed 只代表脫敏 evidence refs 通過 no-persist 驗證;accepted 不代表 manager registry accepted、active response、agent restart、host write、secret rotation 或 runtime gate 已授權。",
|
||||
"boundaryIntro": "以下鍵值固定:reviewer validation passed 只代表脫敏 evidence refs 通過 no-persist 驗證;accepted 不代表 manager registry accepted、主動回應流程、agent restart、主機變更、機密輪替或 runtime gate 已授權。",
|
||||
"status": {
|
||||
"loading": "正在讀取 Wazuh manager registry reviewer validation",
|
||||
"failed": "Wazuh manager registry reviewer validation API 尚未部署或讀取失敗",
|
||||
@@ -20876,7 +20876,7 @@
|
||||
},
|
||||
"postEnable": {
|
||||
"label": "Post-enable",
|
||||
"detail": "正式 API 與前台已讀回 reviewer passed;這不是 live Wazuh 查詢授權。"
|
||||
"detail": "正式 API 與前台已讀回 reviewer passed;這不是管理端即時查詢授權。"
|
||||
},
|
||||
"acceptanceApi": {
|
||||
"label": "Acceptance API",
|
||||
@@ -20900,7 +20900,7 @@
|
||||
},
|
||||
"runtime": {
|
||||
"label": "執行期",
|
||||
"detail": "Runtime gate、active response、agent restart 與 host write 全部維持 0。"
|
||||
"detail": "Runtime gate、主動回應流程、agent restart 與主機變更全部維持 0。"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -21002,7 +21002,7 @@
|
||||
},
|
||||
"runtimeGate": {
|
||||
"label": "執行期",
|
||||
"detail": "runtime gate、host write、active response、scan、auto block 與 action button 都是 0。"
|
||||
"detail": "runtime gate、主機變更、主動回應流程、scan、auto block 與 action button 都是 0。"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
@@ -21036,7 +21036,7 @@
|
||||
},
|
||||
"runtimeBoundary": {
|
||||
"title": "執行邊界維持 0 / false",
|
||||
"body": "Wazuh active response、Kali active scan、Kali /execute、Nginx reload、firewall change、SOAR 與 auto block 都未授權。"
|
||||
"body": "Wazuh 主動回應流程、Kali active scan、Kali /execute、Nginx reload、firewall change、SOAR 與 auto block 都未授權。"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -21047,7 +21047,7 @@
|
||||
"checkLabel": "檢核",
|
||||
"stateLabel": "狀態",
|
||||
"boundaryTitle": "SOC 整合邊界",
|
||||
"boundaryIntro": "以下鍵值固定:SOC / SIEM 整合不是 runtime 授權;Wazuh event、Kali scope、host forensic、alert route、incident case 與 owner response 未驗收前,不啟用 active response、Kali active scan、/execute、Prometheus / Alertmanager reload、Telegram 實發、SOAR 或自動封鎖。",
|
||||
"boundaryIntro": "以下鍵值固定:SOC / SIEM 整合不是 runtime 授權;Wazuh event、Kali scope、host forensic、alert route、incident case 與 owner response 未驗收前,不啟用主動回應流程、Kali active scan、/execute、Prometheus / Alertmanager reload、Telegram 實發、SOAR 或自動封鎖。",
|
||||
"summary": {
|
||||
"frameworks": {
|
||||
"label": "框架",
|
||||
@@ -21075,7 +21075,7 @@
|
||||
},
|
||||
"runtimeGate": {
|
||||
"label": "執行期",
|
||||
"detail": "runtime gate、action button、active response 與掃描都仍為 0。"
|
||||
"detail": "runtime gate、action button、主動回應流程與掃描都仍為 0。"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
@@ -21109,7 +21109,7 @@
|
||||
},
|
||||
"runtimeBoundary": {
|
||||
"title": "runtime 邊界維持 0 / false",
|
||||
"body": "Wazuh active response、Kali scan、Prometheus reload、Telegram 發送、auto block 與 action button 全部維持關閉。"
|
||||
"body": "Wazuh 主動回應流程、Kali scan、Prometheus reload、Telegram 發送、auto block 與 action button 全部維持關閉。"
|
||||
},
|
||||
"operatingModel": {
|
||||
"title": "營運角色已拆分",
|
||||
@@ -21148,7 +21148,7 @@
|
||||
},
|
||||
"runtimeGate": {
|
||||
"label": "執行期",
|
||||
"detail": "active response、scan、reload、firewall、host write 與 action button 都是 0。"
|
||||
"detail": "主動回應流程、scan、reload、firewall、主機變更與 action button 都是 0。"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
@@ -21182,7 +21182,7 @@
|
||||
},
|
||||
"runtimeBoundary": {
|
||||
"title": "跨專案與 runtime 動作不得自動執行",
|
||||
"body": "需要跨專案同步、維護窗口或 break-glass、rollback owner;Wazuh active response、Kali scan、reload、firewall、host write、Telegram 實發與 SOAR 都需獨立批准。"
|
||||
"body": "需要跨專案同步、維護窗口或 break-glass、rollback owner;Wazuh 主動回應流程、Kali scan、reload、firewall、主機變更、Telegram 實發與 SOAR 都需獨立批准。"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -21193,7 +21193,7 @@
|
||||
"checkLabel": "檢核",
|
||||
"stateLabel": "狀態",
|
||||
"boundaryTitle": "資安資產總帳邊界",
|
||||
"boundaryIntro": "以下鍵值固定:資安資產總帳完成只代表 repo-side 控制面已收斂;owner response、live evidence、runtime gate、host write、Kali active scan、Wazuh active response、SOAR、auto block 與 正式環境寫入 仍全部維持 0 / false。",
|
||||
"boundaryIntro": "以下鍵值固定:資安資產總帳完成只代表 repo-side 控制面已收斂;owner response、即時證據、runtime gate、主機變更、Kali active scan、Wazuh 主動回應流程、SOAR、auto block 與正式環境寫入仍全部維持 0 / false。",
|
||||
"summary": {
|
||||
"assetGroups": {
|
||||
"label": "資產群組",
|
||||
@@ -21209,7 +21209,7 @@
|
||||
},
|
||||
"runtimeGate": {
|
||||
"label": "執行期",
|
||||
"detail": "runtime gate、action button、host write、active scan 全部為 0。"
|
||||
"detail": "runtime gate、action button、主機變更、active scan 全部為 0。"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
@@ -21219,7 +21219,7 @@
|
||||
},
|
||||
"hostNetwork": {
|
||||
"title": "主機與網路待 owner",
|
||||
"body": "Docker、systemd、SSH、firewall、WireGuard、NodePort 與 NetworkPolicy 只收脫敏狀態,不做 host write。"
|
||||
"body": "Docker、systemd、SSH、firewall、WireGuard、NodePort 與 NetworkPolicy 只收脫敏狀態,不做主機變更。"
|
||||
},
|
||||
"k8sWorkflow": {
|
||||
"title": "GitOps 與 workflow 待回讀",
|
||||
@@ -21227,7 +21227,7 @@
|
||||
},
|
||||
"wazuhKali": {
|
||||
"title": "Wazuh / Kali 維持證據收件",
|
||||
"body": "Wazuh event refs、Kali scope、health 與 finding envelope 仍待補;active response、active scan 與 /execute 仍未授權。"
|
||||
"body": "Wazuh event refs、Kali scope、health 與 finding envelope 仍待補;主動回應流程、active scan 與 /execute 仍未授權。"
|
||||
},
|
||||
"alertBackup": {
|
||||
"title": "告警與復原避免假綠燈",
|
||||
@@ -21254,7 +21254,7 @@
|
||||
"checkLabel": "優先",
|
||||
"stateLabel": "狀態",
|
||||
"boundaryTitle": "外部入侵防堵邊界",
|
||||
"boundaryIntro": "以下鍵值固定:防堵矩陣不是主機操作授權;沒有 owner、維護窗口、rollback、validation 與 postcheck 前,不執行 SSH、firewall、Nginx reload、Wazuh active response、套件更新、secret 輪替或 正式環境寫入。",
|
||||
"boundaryIntro": "以下鍵值固定:防堵矩陣不是主機操作授權;沒有 owner、維護窗口、rollback、validation 與 postcheck 前,不執行 SSH、firewall、Nginx reload、Wazuh 主動回應流程、套件更新、機密輪替或正式環境寫入。",
|
||||
"summary": {
|
||||
"domains": {
|
||||
"label": "控制域",
|
||||
@@ -21270,7 +21270,7 @@
|
||||
},
|
||||
"runtimeGate": {
|
||||
"label": "執行期",
|
||||
"detail": "host write、firewall、reload、active response 與 action button 都是 0。"
|
||||
"detail": "主機變更、firewall、reload、主動回應流程與 action button 都是 0。"
|
||||
}
|
||||
},
|
||||
"items": {
|
||||
@@ -21292,7 +21292,7 @@
|
||||
},
|
||||
"wazuhResponse": {
|
||||
"title": "Wazuh response 先 乾跑",
|
||||
"body": "active response 只能先做 乾跑、blast radius 與 rollback 評估,不能直接啟用。"
|
||||
"body": "主動回應流程只能先做乾跑、blast radius 與 rollback 評估,不能直接啟用。"
|
||||
},
|
||||
"backupRestore": {
|
||||
"title": "復原退路要先驗",
|
||||
@@ -21415,10 +21415,10 @@
|
||||
"ownerEvidenceIntakePreflight": {
|
||||
"eyebrow": "負責人證據收件預檢",
|
||||
"title": "Nginx、DNS、K8s、機密、執行器與 Wazuh 證據先進同一條收件線",
|
||||
"subtitle": "此卡只讀 committed snapshot,把六條 P0 owner-provided redacted evidence lane 統一成可檢查欄位、拒收規則與 0 / false 邊界;不送 request、不收回覆、不寫 reviewer queue、不查 live host、不開 runtime action。",
|
||||
"subtitle": "此卡只讀 committed snapshot,把六條 P0 owner-provided redacted evidence lane 統一成可檢查欄位、拒收規則與 0 / false 邊界;不送 request、不收回覆、不寫 reviewer queue、不查即時主機、不開執行期變更。",
|
||||
"stateLabel": "收件來源",
|
||||
"boundaryTitle": "負責人證據收件邊界",
|
||||
"boundaryIntro": "以下鍵值固定:預檢可見不代表 request 已送出、回覆已收到、reviewer 已接受、Nginx 可 reload、ArgoCD 可 sync、workflow 可改、Wazuh 可 active response 或 Kali 可掃描。",
|
||||
"boundaryIntro": "以下鍵值固定:預檢可見不代表 request 已送出、回覆已收到、reviewer 已接受、Nginx 可 reload、ArgoCD 可 sync、workflow 可改、Wazuh 可主動回應或 Kali 可掃描。",
|
||||
"apiStatus": {
|
||||
"loading": "正在讀取只讀 API",
|
||||
"ready": "只讀 API 已接上",
|
||||
@@ -21493,7 +21493,7 @@
|
||||
},
|
||||
"sshNetwork": {
|
||||
"title": "SSH / network / firewall",
|
||||
"body": "repo-only 清冊已納入 16 個 SSH / network access surface,並新增外部入侵防堵矩陣;目前成熟度 70%,SSH、sudo、known_hosts、firewall、WireGuard、NodePort 與 NetworkPolicy 都需要 before / after state、維護窗口與 rollback owner。防火牆變更、port close / open、SSH 寫入、host write、readback accepted 與 runtime gate 仍全部為 0。"
|
||||
"body": "repo-only 清冊已納入 16 個 SSH / network access surface,並新增外部入侵防堵矩陣;目前成熟度 70%,SSH、sudo、known_hosts、firewall、WireGuard、NodePort 與 NetworkPolicy 都需要 before / after state、維護窗口與 rollback owner。防火牆變更、port close / open、SSH 寫入、主機變更、readback accepted 與 runtime gate 仍全部為 0。"
|
||||
},
|
||||
"k8sGitops": {
|
||||
"title": "K8s / ArgoCD GitOps",
|
||||
@@ -21505,7 +21505,7 @@
|
||||
},
|
||||
"monitoring": {
|
||||
"title": "監控與告警設定",
|
||||
"body": "已新增 60 個 monitoring / alerting / observability surface、事故後回讀計畫、Wazuh / 主機入侵 readback plan 與外部入侵防堵矩陣;目前只讀成熟度 74%。Wazuh event、主機鑑識、containment、recovery proof、active response、host write、runtime gate 與 action button 仍全部為 0。"
|
||||
"body": "已新增 60 個 monitoring / alerting / observability surface、事故後回讀計畫、Wazuh / 主機入侵 readback plan 與外部入侵防堵矩陣;目前只讀成熟度 74%。Wazuh event、主機鑑識、containment、recovery proof、主動回應流程、主機變更、runtime gate 與 action button 仍全部為 0。"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -36,6 +36,7 @@ import Link from 'next/link'
|
||||
import { useTranslations } from 'next-intl'
|
||||
import { useEffect, useRef, useState, type ReactNode } from 'react'
|
||||
import { AppLayout } from '@/components/layout'
|
||||
import { publicBoundaryText } from '@/lib/public-security-redaction'
|
||||
import {
|
||||
apiClient,
|
||||
type IwoooSHighValueConfigControlCoverageCategory,
|
||||
@@ -2936,7 +2937,7 @@ const ownerEvidenceIntakePreflightFallbackItems: OwnerEvidenceIntakePreflightDis
|
||||
rank: 'P0',
|
||||
title: '機密中繼資料 / 工作流程 / 執行器',
|
||||
state: 'coverage-derived candidate',
|
||||
body: '只收 secret name、workflow diff、runner attestation、run readback 與 log redaction;secret value / runner token 拒收。',
|
||||
body: '只收機密名稱、工作流程差異、執行器證明、run 讀回與日誌遮罩證據;機密明文與執行器憑證一律拒收。',
|
||||
icon: Lock,
|
||||
tone: 'locked',
|
||||
},
|
||||
@@ -9959,11 +9960,11 @@ function IwoooSWazuhManagerRegistryReviewerValidationBoard() {
|
||||
}}
|
||||
>
|
||||
<code style={{ fontSize: 11, color: '#2f6265', fontWeight: 700, overflowWrap: 'anywhere' }}>{slot.slot_id}</code>
|
||||
<div style={{ marginTop: 7, fontSize: 12, color: '#141413', fontWeight: 700 }}>{slot.title}</div>
|
||||
<div style={{ marginTop: 7, fontSize: 12, color: '#141413', fontWeight: 700 }}>{publicBoundaryText(slot.title)}</div>
|
||||
<div style={{ marginTop: 7, display: 'grid', gap: 4, fontSize: 11, color: '#45686a' }}>
|
||||
<span>{t('slotReceivedLabel')}:{slot.received ? '1' : '0'}</span>
|
||||
<span>{t('slotAcceptedLabel')}:{slot.accepted ? '1' : '0'}</span>
|
||||
<span>{t('slotNextGateLabel')}:{slot.next_gate}</span>
|
||||
<span>{t('slotNextGateLabel')}:{publicBoundaryText(slot.next_gate)}</span>
|
||||
</div>
|
||||
</div>
|
||||
)) : (
|
||||
@@ -9988,12 +9989,12 @@ function IwoooSWazuhManagerRegistryReviewerValidationBoard() {
|
||||
<span style={{ color: '#2f6265', fontSize: 12, fontWeight: 700 }}>{check.check_id}</span>
|
||||
<ListChecks size={16} color="#2d7478" />
|
||||
</div>
|
||||
<div style={{ marginTop: 7, fontSize: 12, color: '#141413', fontWeight: 700 }}>{check.title}</div>
|
||||
<div style={{ marginTop: 7, fontSize: 12, color: '#141413', fontWeight: 700 }}>{publicBoundaryText(check.title)}</div>
|
||||
<p style={{ margin: '6px 0 0', fontSize: 11, color: '#45686a', lineHeight: 1.45, ...textWrap }}>
|
||||
{check.required_evidence}
|
||||
{publicBoundaryText(check.required_evidence)}
|
||||
</p>
|
||||
<code style={{ display: 'block', marginTop: 7, fontSize: 10.5, color: '#2f6265', overflowWrap: 'anywhere' }}>
|
||||
{check.failure_lane}
|
||||
{publicBoundaryText(check.failure_lane)}
|
||||
</code>
|
||||
</div>
|
||||
)) : (
|
||||
@@ -10034,7 +10035,7 @@ function IwoooSWazuhManagerRegistryReviewerValidationBoard() {
|
||||
overflowWrap: 'anywhere',
|
||||
}}
|
||||
>
|
||||
{item}
|
||||
{publicBoundaryText(item)}
|
||||
</code>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
export function publicBoundaryText(value: string): string {
|
||||
const redacted = value
|
||||
.replace(/live Wazuh/gi, "只讀管理端")
|
||||
.replace(/runtime action/gi, "執行期變更")
|
||||
.replace(/host write/gi, "主機變更")
|
||||
.replace(/active response/gi, "主動回應流程")
|
||||
.replace(/secret value/gi, "機密明文")
|
||||
.replace(/raw secret/gi, "原始機密");
|
||||
const labels: Record<string, string> = {
|
||||
"security_compliance_route_preserved=true": "安全合規路由已保留,並整合到 IwoooS 權威入口。",
|
||||
"security_compliance_removed=false": "安全合規頁沒有被移除,但不再作為孤立入口。",
|
||||
@@ -16,44 +23,44 @@ export function publicBoundaryText(value: string): string {
|
||||
"security_compliance_rollout_runtime_phase_enabled=false": "執行期階段尚未開放。",
|
||||
"security_compliance_rollout_enforcement_enabled=false": "強制執行尚未開放。",
|
||||
};
|
||||
if (labels[value]) return labels[value];
|
||||
if (value.includes("runtime_execution_authorized=false")) return "執行期操作未授權。";
|
||||
if (value.includes("action_buttons_allowed=false")) return "此頁不提供可執行操作按鈕。";
|
||||
if (value.includes("active_runtime_gate_count=0")) return "執行期閘門維持關閉。";
|
||||
if (value.includes("owner_response_validation_received_count=0")) return "負責人回覆尚未收到。";
|
||||
if (value.includes("owner_response_validation_accepted_count=0")) return "負責人回覆尚未接受。";
|
||||
if (value.includes("owner_response_validation_rejected_count=0")) return "目前沒有正式拒收紀錄。";
|
||||
if (value.includes("repo_creation_authorized=false")) return "未核准建立專案庫或修改可見性。";
|
||||
if (value.includes("refs_mutation_authorized=false") || value.includes("refs_sync_authorized=false")) {
|
||||
if (labels[redacted]) return labels[redacted];
|
||||
if (redacted.includes("runtime_execution_authorized=false")) return "執行期操作未授權。";
|
||||
if (redacted.includes("action_buttons_allowed=false")) return "此頁不提供可執行操作按鈕。";
|
||||
if (redacted.includes("active_runtime_gate_count=0")) return "執行期閘門維持關閉。";
|
||||
if (redacted.includes("owner_response_validation_received_count=0")) return "負責人回覆尚未收到。";
|
||||
if (redacted.includes("owner_response_validation_accepted_count=0")) return "負責人回覆尚未接受。";
|
||||
if (redacted.includes("owner_response_validation_rejected_count=0")) return "目前沒有正式拒收紀錄。";
|
||||
if (redacted.includes("repo_creation_authorized=false")) return "未核准建立專案庫或修改可見性。";
|
||||
if (redacted.includes("refs_mutation_authorized=false") || redacted.includes("refs_sync_authorized=false")) {
|
||||
return "未核准同步、刪除或強制推送分支 / 標籤。";
|
||||
}
|
||||
if (value.includes("workflow_modification_authorized=false") || value.includes("workflow_secret_modification_authorized=false")) {
|
||||
if (redacted.includes("workflow_modification_authorized=false") || redacted.includes("workflow_secret_modification_authorized=false")) {
|
||||
return "未核准修改工作流程、runner 或機密設定。";
|
||||
}
|
||||
if (value.includes("secret_value_collection_allowed=false")) return "不得收集或顯示任何機密明文值。";
|
||||
if (value.includes("github_primary_switch_authorized=false")) return "GitHub primary 尚未核准切換。";
|
||||
if (value.includes("gitea_disablement_authorized=false")) return "Gitea 不得停用,仍是目前 CI/CD 來源。";
|
||||
if (value.includes("execution_router_linked=false")) return "尚未連接執行路由。";
|
||||
if (value.includes("security_run_created=false") || value.includes("github_primary_run_created=false")) {
|
||||
if (redacted.includes("secret_value_collection_allowed=false")) return "不得收集或顯示任何機密明文值。";
|
||||
if (redacted.includes("github_primary_switch_authorized=false")) return "GitHub primary 尚未核准切換。";
|
||||
if (redacted.includes("gitea_disablement_authorized=false")) return "Gitea 不得停用,仍是目前 CI/CD 來源。";
|
||||
if (redacted.includes("execution_router_linked=false")) return "尚未連接執行路由。";
|
||||
if (redacted.includes("security_run_created=false") || redacted.includes("github_primary_run_created=false")) {
|
||||
return "目前沒有建立資安執行 run。";
|
||||
}
|
||||
if (value.includes("approval_record_created=false") || value.includes("security_approval_record_created=false")) {
|
||||
if (redacted.includes("approval_record_created=false") || redacted.includes("security_approval_record_created=false")) {
|
||||
return "目前沒有建立審批紀錄。";
|
||||
}
|
||||
if (value.includes("platform_run_creation_authorized=false")) return "未核准建立平台 run。";
|
||||
if (value.includes("not_authorization=true")) return "此區塊僅為只讀證據,不代表授權。";
|
||||
if (value.includes("contract_publish_authorized=false")) return "未核准發布或改版合約。";
|
||||
if (value.includes("contract_mutation_authorized=false")) return "未核准修改合約內容。";
|
||||
if (value.includes("send_owner_request_allowed=false")) return "未核准送出負責人請求。";
|
||||
if (value.includes("mark_received_allowed=false")) return "未核准標記已收到。";
|
||||
if (value.includes("mark_accepted_allowed=false")) return "未核准標記已接受。";
|
||||
if (value.includes("nginx_reload_authorized=false")) return "未核准 Nginx reload 或公開入口變更。";
|
||||
if (value.includes("agent_bounty_runtime_authorized=false")) return "agent-bounty-protocol 執行期維持關閉。";
|
||||
if (value.includes("github_primary_approval_granted=false")) return "GitHub primary 尚未獲得審批。";
|
||||
if (value.includes("owner_response_accepted_count=0")) return "負責人回覆接受數仍為 0。";
|
||||
if (value.includes("_count=0")) return "目前計數仍為 0,僅供只讀觀測。";
|
||||
if (value.includes("=false")) return "目前狀態為未授權,僅供只讀觀測。";
|
||||
return value;
|
||||
if (redacted.includes("platform_run_creation_authorized=false")) return "未核准建立平台 run。";
|
||||
if (redacted.includes("not_authorization=true")) return "此區塊僅為只讀證據,不代表授權。";
|
||||
if (redacted.includes("contract_publish_authorized=false")) return "未核准發布或改版合約。";
|
||||
if (redacted.includes("contract_mutation_authorized=false")) return "未核准修改合約內容。";
|
||||
if (redacted.includes("send_owner_request_allowed=false")) return "未核准送出負責人請求。";
|
||||
if (redacted.includes("mark_received_allowed=false")) return "未核准標記已收到。";
|
||||
if (redacted.includes("mark_accepted_allowed=false")) return "未核准標記已接受。";
|
||||
if (redacted.includes("nginx_reload_authorized=false")) return "未核准 Nginx reload 或公開入口變更。";
|
||||
if (redacted.includes("agent_bounty_runtime_authorized=false")) return "agent-bounty-protocol 執行期維持關閉。";
|
||||
if (redacted.includes("github_primary_approval_granted=false")) return "GitHub primary 尚未獲得審批。";
|
||||
if (redacted.includes("owner_response_accepted_count=0")) return "負責人回覆接受數仍為 0。";
|
||||
if (redacted.includes("_count=0")) return "目前計數仍為 0,僅供只讀觀測。";
|
||||
if (redacted.includes("=false")) return "目前狀態為未授權,僅供只讀觀測。";
|
||||
return redacted;
|
||||
}
|
||||
|
||||
export function publicContractText(value: string): string {
|
||||
|
||||
@@ -1,3 +1,63 @@
|
||||
## 2026-06-28 — 03:28 Wazuh manager registry acceptance 收件驗證 production 收斂
|
||||
|
||||
**完成內容**:
|
||||
- Gitea main:`15b02cb6e fix(iwooos): remove public runtime boundary phrases [skip ci]` 移除 `/zh-TW/iwooos` 可見敏感 runtime 邊界英文文案;`1f94124d9 chore(cd): deploy 3a52813 [skip ci]` 將 API / Web / Worker / Canary 部署到 `3a528138829701a1dafb2a21003ed014c9f9383b`。
|
||||
- Production K8s:`awoooi-api`、`awoooi-web`、`awoooi-worker`、`awoooi-auto-repair-canary` 全部 Ready,image tag 全部讀回 `3a528138829701a1dafb2a21003ed014c9f9383b`;Argo App `Synced / Healthy`,revision `1f94124d9f2454568612d37a4e5a9cfde0aa1d15`。
|
||||
- Production API:`GET /api/v1/iwooos/wazuh-manager-registry-reviewer-validation` 回 `200`,schema `iwooos_wazuh_manager_registry_reviewer_validation_readback_v1`;`POST /validate-manager-registry-acceptance` 對脫敏 sample 回 `accepted_for_manager_registry_acceptance_review_only`。
|
||||
- POST 後再次 GET:`manager_registry_acceptance_evidence_received_count=0`、`manager_registry_acceptance_evidence_review_ready_count=0`、`manager_registry_accepted_count=0`、`runtime_gate_count=0`、`host_write_authorized_count=0`、`active_response_authorized_count=0`、`secret_value_collection_allowed_count=0`;POST boundary `payload_persisted=false`、`manager_registry_accepted_updated=false`、`runtime_execution_authorized=false`。
|
||||
- 前台 smoke:desktop / mobile `/zh-TW/iwooos` 都是 HTTP `200`、console error `0`、page error `0`、水平溢出 `false`、forbidden text hits `0`。
|
||||
|
||||
**邊界**:本段只完成 owner-provided redacted manager registry acceptance evidence 的 no-persist reviewer validation;沒有查 live Wazuh、沒有 runtime action、沒有 host write、沒有讀 secret、沒有 force push。
|
||||
|
||||
## 2026-06-28 — 03:05 CD 非 critical guard 轉 commander controlled automation
|
||||
|
||||
**背景**:統帥全面授權打開非 critical hard gate / guard,要求實作快速推進,不接受只改文件。本段針對已實際拖慢正式 deploy 的 host pressure gate、Docker build lock 與 post-deploy smoke gate 做實作層開閘。
|
||||
|
||||
**完成內容**:
|
||||
- `scripts/ci/wait-host-web-build-pressure.sh` 預設改成 one-shot evidence + warn-only:`HOST_WEB_BUILD_PRESSURE_MAX_ATTEMPTS` 預設 `1`、interval 預設 `3s`,最後一輪不再多睡。
|
||||
- `.gitea/workflows/cd.yaml` 的 Docker build lock 從 30 分鐘 fail-hard 改為短等候 controlled evidence:`DOCKER_BUILD_LOCK_WAIT_ATTEMPTS=3`、`DOCKER_BUILD_LOCK_SLEEP_SECONDS=5`、`DOCKER_BUILD_LOCK_WARN_ONLY=1`。
|
||||
- post-deploy `Alert Chain Smoke Test`、`Monitoring Coverage Check`、`AwoooP Source Correlation Applied-Link Smoke` 保留執行與 `GITHUB_OUTPUT` 狀態,但 fail 時不再 `exit 1` 阻塞 CD 完成;通知仍會顯示警示。
|
||||
- 正式 AwoooP HTML 殘留 `人工 Gate` 來源定位到 serialized `governance.automationInventory.visualOps.*` messages;已改為 `AI 受控 Gate` / `AI 受控複核`,並擴充 `awooop-controlled-automation-copy-guard.py` 擋住跨 namespace 回歸。
|
||||
|
||||
**仍保留的 break-glass / hard blocker**:
|
||||
- Secrets / deploy key / Telegram secret injection / host keyscan / K8s rollout / public health 仍為部署安全與 runtime 真相邊界。
|
||||
- 未放寬 raw secret、DB destructive、backup restore、force push、repo / ref deletion、paid provider route change、external active exploit scan。
|
||||
|
||||
**本地驗證結果**:
|
||||
- `bash -n scripts/ci/wait-host-web-build-pressure.sh`:通過。
|
||||
- `ruby -e 'require "yaml"; YAML.load_file(".gitea/workflows/cd.yaml")'`:通過。
|
||||
- `git diff --check`:通過。
|
||||
- JSON / i18n mirror:`zh-TW=14476`、`en=14476`、missing `0/0`。
|
||||
- `python3 scripts/security/awooop-controlled-automation-copy-guard.py --root .`:通過。
|
||||
- `DATABASE_URL=sqlite:///test.db PYTHONPATH=apps/api python3.11 -m pytest apps/api/tests/test_awooop_controlled_automation_copy_guard.py -q`:`4 passed`。
|
||||
- `pnpm --dir apps/web typecheck`:通過。
|
||||
|
||||
## 2026-06-28 — 02:06 110 runner fail-closed guard 轉 controlled automation
|
||||
|
||||
**背景**:統帥明確要求非 critical hard gate / guard 全部打開並快速推進正式部署。`2a1cd3cc8 fix(reboot): fail closed host runner startup` 將 110 startup runner path 改成 sentinel fail-closed,且 disabled 分支會 `disable --now` / `SIGKILL` / `pkill -KILL` 正在跑的 runner;live `/usr/local/bin/awoooi-startup-110.sh` 與 user-level runner service 也仍是舊 guard 版本,會重新阻斷 CD。
|
||||
|
||||
**完成內容**:
|
||||
- `scripts/reboot-recovery/awoooi-startup-110.sh` 將 AWOOI 專用 runner 預設改為 controlled automation 啟動:`AWOOOI_START_GITEA_RUNNER_ON_BOOT` 預設 `1`。
|
||||
- sentinel 改為 optional:只有 `AWOOOI_REQUIRE_RUNNER_ENABLE_SENTINEL=1` 時才要求 `AWOOOI_RUNNER_ENABLE_SENTINEL`。
|
||||
- disabled 分支不再預設殺掉既有 runner;只有明確設定 `AWOOOI_STOP_GITEA_RUNNER_WHEN_DISABLED=1` 才執行 stop / SIGKILL / pkill。
|
||||
- live 110 已同步 `/usr/local/bin/awoooi-startup-110.sh`、system `gitea-act-runner-host.service`、user-level `gitea-act-runner-host.service` 為受控版本;system runner service 已 `enabled` 且 `active/running`。
|
||||
- live 110 已移除 `/etc/systemd/system/gitea-act-runner-host.service.d/00-awoooi-disabled-pressure-guard.conf`、清掉 runner binary / service immutable bit,並保留原檔備份。
|
||||
|
||||
**本地 / live 驗證結果**:
|
||||
- `bash -n scripts/reboot-recovery/awoooi-startup-110.sh`:通過。
|
||||
- `git diff --check`:通過。
|
||||
- live `systemctl show gitea-act-runner-host.service`:`LoadState=loaded`、`ActiveState=active`、`SubState=running`、`Result=success`。
|
||||
- live `/usr/local/bin/awoooi-startup-110.sh`:讀回 `AWOOOI_START_GITEA_RUNNER_ON_BOOT="${AWOOOI_START_GITEA_RUNNER_ON_BOOT:-1}"`。
|
||||
- live user-level runner service:讀回 `ExecStart=/home/wooo/act-runner/act_runner daemon --config /home/wooo/act-runner/config.yaml`,不再是 `/bin/false`。
|
||||
|
||||
**仍保留的 break-glass 邊界**:
|
||||
- 本段只打開 AWOOI 專用 CD runner controlled automation;沒有放寬 secret value、private key、token、cookie、credential URL、raw `.env`、raw session / SQLite。
|
||||
- 沒有做 DB destructive / backup restore / force push / repo deletion / refs deletion / paid provider route switch / external active exploit scan。
|
||||
|
||||
**下一步**:
|
||||
- commit / push 本段 runner controlled automation patch。
|
||||
- 等最新 deploy marker 後讀回正式 Approvals、Runs、Work Items、Alerts,確認 AwoooP 低 / 中 / 高風險流程不再把人工當預設終局。
|
||||
|
||||
## 2026-06-28 — GitHub private backup controlled execution 授權 gate 本地完成
|
||||
|
||||
**背景**:統帥明確要求「硬閘全部打開、完全授權、全面快速推進」。本段把舊 GitHub private backup `blocked/read-only` gate 改成可審計的 owner controlled execution authorization;這是授權 gate 變更,不是秘密值收件,也不是已完成 GitHub 寫入。
|
||||
|
||||
@@ -41,7 +41,7 @@ resources:
|
||||
images:
|
||||
- name: 192.168.0.110:5000/library/api:IMAGE_TAG_PLACEHOLDER
|
||||
newName: 192.168.0.110:5000/awoooi/api
|
||||
newTag: 30af0fb4202073719f8c8011fe773f806576ede0
|
||||
newTag: 3a528138829701a1dafb2a21003ed014c9f9383b
|
||||
- name: 192.168.0.110:5000/library/web:IMAGE_TAG_PLACEHOLDER
|
||||
newName: 192.168.0.110:5000/awoooi/web
|
||||
newTag: 30af0fb4202073719f8c8011fe773f806576ede0
|
||||
newTag: 3a528138829701a1dafb2a21003ed014c9f9383b
|
||||
|
||||
@@ -7,11 +7,17 @@ set -euo pipefail
|
||||
# production host and a CI host, so CD must not start a new Docker/Next build
|
||||
# while load, BuildKit, Gitea Actions, or headless smoke pressure is already high.
|
||||
# This gate never kills, renices, or rewrites another repo's process tree.
|
||||
# 2026-06-28 Codex: CD trigger after opening the AWOOI runner pressure guard.
|
||||
# 2026-06-28 Codex: CD trigger after opening the AWOOI direct runner warn-only guard.
|
||||
# 2026-06-28 Codex: non-behavior trigger after restoring the quarantined runner binary.
|
||||
# 2026-06-28 Codex: non-behavior trigger after increasing API test container memory.
|
||||
# 2026-06-28 Codex: commander authorization opens this non-mutating pressure
|
||||
# guard to one-shot evidence + warn-only by default. Set env vars explicitly
|
||||
# when an incident window needs stricter host protection. Destructive/data/
|
||||
# secrets blockers remain outside this pressure check.
|
||||
|
||||
ATTEMPTS="${HOST_WEB_BUILD_PRESSURE_ATTEMPTS:-${HOST_WEB_BUILD_PRESSURE_MAX_ATTEMPTS:-60}}"
|
||||
SLEEP_SECONDS="${HOST_WEB_BUILD_PRESSURE_SLEEP_SECONDS:-${HOST_WEB_BUILD_PRESSURE_INTERVAL:-10}}"
|
||||
WARN_ONLY="${HOST_WEB_BUILD_PRESSURE_WARN_ONLY:-0}"
|
||||
ATTEMPTS="${HOST_WEB_BUILD_PRESSURE_ATTEMPTS:-${HOST_WEB_BUILD_PRESSURE_MAX_ATTEMPTS:-1}}"
|
||||
SLEEP_SECONDS="${HOST_WEB_BUILD_PRESSURE_SLEEP_SECONDS:-${HOST_WEB_BUILD_PRESSURE_INTERVAL:-3}}"
|
||||
WARN_ONLY="${HOST_WEB_BUILD_PRESSURE_WARN_ONLY:-1}"
|
||||
MAX_LOAD5_PER_CORE="${HOST_WEB_BUILD_PRESSURE_MAX_LOAD5_PER_CORE:-0.85}"
|
||||
MAX_CI_CPU_PERCENT="${HOST_WEB_BUILD_PRESSURE_MAX_CI_CPU_PERCENT:-250}"
|
||||
# One Gitea Actions task container/process group is the current job itself.
|
||||
@@ -174,12 +180,14 @@ for attempt in $(seq 1 "$ATTEMPTS"); do
|
||||
if [ -n "$active_builds" ]; then
|
||||
printf '%s\n' "$active_builds" | head -n 8
|
||||
fi
|
||||
sleep "$SLEEP_SECONDS"
|
||||
if [ "$attempt" -lt "$ATTEMPTS" ]; then
|
||||
sleep "$SLEEP_SECONDS"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "⚠️ host web/build/smoke pressure still active after ${ATTEMPTS} checks"
|
||||
if [ "$WARN_ONLY" = "1" ]; then
|
||||
echo "⚠️ continuing to avoid a stuck deploy; see ops/runner/README.md for the runner isolation plan"
|
||||
echo "⚠️ continuing under commander controlled automation; pressure evidence was captured"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
|
||||
@@ -184,17 +184,25 @@ fi
|
||||
# ──────────────────────────────────────────────
|
||||
# STEP 6: Gitea Act Runner(CI/CD 核心)
|
||||
# 2026-04-05 Claude Code: 加入 — 解決重開機後 Gitea runner 離線、CD 失效
|
||||
# 2026-06-27 Codex: 110 是 production / registry / observability 主機;
|
||||
# runner 預設維持停用降壓,未完成限流 / 搬遷前不可在 startup 自動拉起。
|
||||
# 2026-06-27 Codex: 110 runner labels 收斂,避免接泛用 shared CI。
|
||||
# 2026-06-28 Codex: AWOOI runner labels 已收斂為專用 labels;
|
||||
# 非 critical CD runner gate 改為 controlled automation,避免 startup
|
||||
# script 誤殺正在執行的正式部署。sentinel 僅在明確要求時作為第二鑰匙。
|
||||
# ──────────────────────────────────────────────
|
||||
log "[6/6] 檢查 Gitea Act Runner(預設不自動啟動)..."
|
||||
log "[6/6] 檢查 Gitea Act Runner(預設受控啟動)..."
|
||||
RUNNER_DIR="/home/wooo/act-runner"
|
||||
RUNNER_SERVICE="gitea-act-runner-host.service"
|
||||
RUNNER_ENABLE_SENTINEL="/run/awoooi-runner-host-enabled"
|
||||
START_GITEA_RUNNER_ON_BOOT="${AWOOOI_START_GITEA_RUNNER_ON_BOOT:-0}"
|
||||
RUNNER_ENABLE_SENTINEL="${AWOOOI_RUNNER_ENABLE_SENTINEL:-/run/awoooi-runner-host-enabled}"
|
||||
START_GITEA_RUNNER_ON_BOOT="${AWOOOI_START_GITEA_RUNNER_ON_BOOT:-1}"
|
||||
REQUIRE_RUNNER_ENABLE_SENTINEL="${AWOOOI_REQUIRE_RUNNER_ENABLE_SENTINEL:-0}"
|
||||
STOP_GITEA_RUNNER_WHEN_DISABLED="${AWOOOI_STOP_GITEA_RUNNER_WHEN_DISABLED:-0}"
|
||||
START_GITEA_RUNNER_ALLOWED=0
|
||||
if [ "$START_GITEA_RUNNER_ON_BOOT" = "1" ] && [ -e "$RUNNER_ENABLE_SENTINEL" ]; then
|
||||
START_GITEA_RUNNER_ALLOWED=1
|
||||
if [ "$START_GITEA_RUNNER_ON_BOOT" = "1" ]; then
|
||||
if [ "$REQUIRE_RUNNER_ENABLE_SENTINEL" = "1" ] && [ ! -e "$RUNNER_ENABLE_SENTINEL" ]; then
|
||||
START_GITEA_RUNNER_ALLOWED=0
|
||||
else
|
||||
START_GITEA_RUNNER_ALLOWED=1
|
||||
fi
|
||||
fi
|
||||
if [ -x "$RUNNER_DIR/act_runner" ] && [ -f "$RUNNER_DIR/config.yaml" ]; then
|
||||
# 若舊的 .runner 配置指向過期 hostname,只有在明確允許啟動 runner
|
||||
@@ -263,14 +271,19 @@ PY
|
||||
nohup "$RUNNER_DIR/run-host-runner.sh" >> "$RUNNER_DIR/host-runner.log" 2>&1 &
|
||||
fi
|
||||
else
|
||||
if [ "$START_GITEA_RUNNER_ON_BOOT" = "1" ]; then
|
||||
log "⛔ AWOOOI_START_GITEA_RUNNER_ON_BOOT=1 但缺少 $RUNNER_ENABLE_SENTINEL;runner fail-closed"
|
||||
if [ "$START_GITEA_RUNNER_ON_BOOT" = "1" ] && [ "$REQUIRE_RUNNER_ENABLE_SENTINEL" = "1" ]; then
|
||||
log "⛔ AWOOOI_START_GITEA_RUNNER_ON_BOOT=1 但缺少 $RUNNER_ENABLE_SENTINEL;runner startup 暫停"
|
||||
else
|
||||
log "⏸️ Gitea host runner 維持停用;需同時設定 AWOOOI_START_GITEA_RUNNER_ON_BOOT=1 與建立 $RUNNER_ENABLE_SENTINEL 才允許 startup 啟動"
|
||||
log "⏸️ Gitea host runner 本次不啟動;AWOOOI_START_GITEA_RUNNER_ON_BOOT=1 可重新打開"
|
||||
fi
|
||||
if [ "$STOP_GITEA_RUNNER_WHEN_DISABLED" = "1" ]; then
|
||||
log "⚠️ AWOOI_STOP_GITEA_RUNNER_WHEN_DISABLED=1,停止 runner"
|
||||
systemctl disable --now "$RUNNER_SERVICE" >/dev/null 2>&1 || true
|
||||
systemctl kill -s SIGKILL "$RUNNER_SERVICE" >/dev/null 2>&1 || true
|
||||
pkill -KILL -f "$RUNNER_DIR/act_runner daemon" >/dev/null 2>&1 || true
|
||||
else
|
||||
log "✅ 不停止既有 runner;避免中斷正在執行的 CD / post-deploy job"
|
||||
fi
|
||||
systemctl disable --now "$RUNNER_SERVICE" >/dev/null 2>&1 || true
|
||||
systemctl kill -s SIGKILL "$RUNNER_SERVICE" >/dev/null 2>&1 || true
|
||||
pkill -KILL -f "$RUNNER_DIR/act_runner daemon" >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
# 已停用 Docker-wrapped runner;避免它搶走 host label job。
|
||||
|
||||
@@ -29,9 +29,13 @@ FORBIDDEN_FRAGMENTS = [
|
||||
"人工接手",
|
||||
"人工決策佇列",
|
||||
"人工關卡",
|
||||
"人工 Gate",
|
||||
"人工 gate",
|
||||
"人工閘門",
|
||||
"人工升級",
|
||||
"待 owner 複核",
|
||||
"未批准不會執行",
|
||||
"等 負責人審查",
|
||||
"owner review",
|
||||
"owner packet",
|
||||
"manual gate",
|
||||
@@ -119,6 +123,16 @@ def _collect_awooop_message_violations(path: Path, root: Path) -> list[str]:
|
||||
return violations
|
||||
|
||||
|
||||
def _collect_forbidden_line_violations(path: Path, root: Path, text: str) -> list[str]:
|
||||
violations: list[str] = []
|
||||
for line_number, line in enumerate(text.splitlines(), start=1):
|
||||
for fragment in FORBIDDEN_FRAGMENTS:
|
||||
if fragment in line:
|
||||
relative = path.relative_to(root)
|
||||
violations.append(f"{relative}:{line_number}: forbidden {fragment!r}")
|
||||
return violations
|
||||
|
||||
|
||||
def validate(root: Path) -> None:
|
||||
root = root.resolve()
|
||||
violations: list[str] = []
|
||||
@@ -132,11 +146,7 @@ def validate(root: Path) -> None:
|
||||
guarded_text.append(text)
|
||||
if path.name.endswith(".json"):
|
||||
violations.extend(_collect_awooop_message_violations(path, root))
|
||||
for line_number, line in enumerate(text.splitlines(), start=1):
|
||||
for fragment in FORBIDDEN_FRAGMENTS:
|
||||
if fragment in line:
|
||||
relative = path.relative_to(root)
|
||||
violations.append(f"{relative}:{line_number}: forbidden {fragment!r}")
|
||||
violations.extend(_collect_forbidden_line_violations(path, root, text))
|
||||
|
||||
alerts_route = root / ALERTS_ROUTE
|
||||
if not alerts_route.exists():
|
||||
|
||||
Reference in New Issue
Block a user