fix(agent): auto-authorize noncritical alert control
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m38s
CD Pipeline / build-and-deploy (push) Successful in 6m58s
CD Pipeline / post-deploy-checks (push) Successful in 1m42s

This commit is contained in:
ogt
2026-07-11 11:46:38 +08:00
parent 044c8c732a
commit d3fa6feef4
10 changed files with 542 additions and 97 deletions

View File

@@ -4,9 +4,8 @@ Trust Engine - 風險判定與 Multi-Sig 簽核邏輯
CISO-101: 信任引擎核心實作
風險等級與簽核需求:
- LOW: 0 人,自動放行 (如 scale up)
- MEDIUM: 需 1 人簽核 (如 delete pod)
- CRITICAL: 需 2 人 Multi-Sig 雙重簽核 (如 DROP TABLE)
- LOW/MEDIUM/HIGH: 0 人,進入受控自動執行
- CRITICAL: 1 人 break-glass (如 DROP TABLE / host reboot / secret read)
Features:
- 自動風險分類
@@ -42,6 +41,37 @@ CRITICAL_KEYWORDS = [
"format",
"wipe",
"purge all",
"destructive migration",
"restore database",
"restore backup",
"remote delete",
"retention delete",
"retention prune",
"host reboot",
"reboot host",
"node drain",
"firewall cutover",
"dns cutover",
"credentialed exploit",
"active scan",
"paid provider",
"cost limit",
"switch production provider",
"replace production model",
"replace agent runtime",
"force push",
"delete repo",
"delete ref",
"change repo visibility",
"raw runtime secret volume",
"kubectl get secret",
"kubectl describe secret",
"read secret",
"dump secret",
"export token",
"read token",
"private key",
"authorization header",
]
MEDIUM_KEYWORDS = [
@@ -69,9 +99,10 @@ LOW_KEYWORDS = [
# =============================================================================
SIGNATURE_REQUIREMENTS: dict[RiskLevel, int] = {
RiskLevel.LOW: 0, # 自動放行
RiskLevel.MEDIUM: 1, # 單人簽核
RiskLevel.CRITICAL: 1, # 2026-04-02 ogt: 統帥決策 — 只需 1 層審核Multi-Sig 停用
RiskLevel.LOW: 0,
RiskLevel.MEDIUM: 0,
RiskLevel.HIGH: 0,
RiskLevel.CRITICAL: 1,
}
@@ -162,10 +193,6 @@ def classify_risk(
Returns:
最終風險等級
"""
# 如果明確指定,直接使用
if explicit_level is not None:
return explicit_level
# 從動作分類
action_risk = classify_risk_by_action(action)
@@ -175,11 +202,12 @@ def classify_risk(
blast_risk = classify_risk_by_blast_radius(blast_radius)
# 取較高風險等級
risk_order = [RiskLevel.LOW, RiskLevel.MEDIUM, RiskLevel.CRITICAL]
risk_order = [RiskLevel.LOW, RiskLevel.MEDIUM, RiskLevel.HIGH, RiskLevel.CRITICAL]
action_idx = risk_order.index(action_risk)
blast_idx = risk_order.index(blast_risk)
explicit_idx = risk_order.index(explicit_level) if explicit_level is not None else 0
return risk_order[max(action_idx, blast_idx)]
return risk_order[max(action_idx, blast_idx, explicit_idx)]
# =============================================================================
@@ -220,7 +248,7 @@ class TrustEngine:
建立新的授權請求
自動根據風險等級設定所需簽核數
LOW 風險自動批准
LOW/MEDIUM/HIGH 風險由 current owner policy 自動批准
"""
# 分類風險
risk_level = classify_risk(
@@ -245,8 +273,8 @@ class TrustEngine:
required_signatures=required_sigs,
)
# LOW 風險自動批准
if risk_level == RiskLevel.LOW:
# Non-critical requests enter controlled automation without a human gate.
if required_sigs == 0:
approval.status = ApprovalStatus.APPROVED
approval.resolved_at = datetime.now(UTC)
if self._on_approved: