arcrun — AI workflow execution engine (clean history)
Self-hosted 開源:WASM 零件 + recipe + cypher-executor,跑在你自己的 Cloudflare。 此為重建的乾淨歷史起點(移除曾誤 commit 的 GCP SA 金鑰,舊歷史保留在 richblack/arcrun 與本地 backup 分支)。含: - acr init --self-hosted installer(建 KV/R2 + codeload 拉預編譯 wasm + wrangler deploy + seed recipe) - recipe push 把關(資料外流提醒 + 打通檢查) - 19 個正當零件預編譯 wasm(claude_api/km_writer/kbdb_upsert_block 排除:違反 DECISIONS §1) - CLI / cypher-executor / registry / 完整 SDD Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
# Design: 資料外流警示(Data Exfiltration Warning)
|
||||
|
||||
> 2026-05-30。實作 requirements.md。**本 design 需 richblack review 後才動 code。**
|
||||
> 觸發策略(richblack 定):**只在「資料變成可被外部呼叫」時問**(暴露面),不管「我去打別人 API」(出站,高頻低風險)。
|
||||
|
||||
---
|
||||
|
||||
## 0. 核心定義:什麼是「資料變成可被外部呼叫」
|
||||
|
||||
警示的觸發點 = 一個動作**讓某份資料 / 能力變成「別人能呼叫得到」**。這是真正的裸奔動作。
|
||||
**不觸發**:「我自己的 workflow 去打別人的 API」(出站)——那是我主動用別人服務,不是把我的東西開放出去。
|
||||
|
||||
### 哪些動作屬於「變成可被外部呼叫」(要警示)
|
||||
| 動作 | 為何是暴露 |
|
||||
|---|---|
|
||||
| 部署 webhook trigger(`acr push` workflow → 可被 POST 觸發) | workflow 變成一個對外可呼叫的 endpoint。誰打它就能跑它、拿它的輸出 |
|
||||
| recipe 貢獻到公共庫(未來飛輪項) | recipe(含 endpoint 設定)變成全生態可見可用 |
|
||||
| 把 workflow / recipe 的可見性改為 public(若未來有此欄位) | 同上 |
|
||||
|
||||
### 哪些動作**不**觸發(避免盲目按 yes)
|
||||
- `acr run`(本機跑,不暴露)
|
||||
- `acr recipe push`(存私人 KV,綁 api_key,只有自己 + 自己的 workflow 用——**不是**對外暴露)
|
||||
- ⚠️ 待 design review 確認:recipe push 現況是私人的,**不暴露**。除非未來加「公共」旗標才觸發。
|
||||
- workflow 裡「打別人 API」的 http 節點(出站,不暴露我的資料給別人呼叫)
|
||||
- 查詢類、creds push(上傳加密 credential 是保護不是暴露)
|
||||
|
||||
### 灰色地帶(design review 要定)
|
||||
- **webhook trigger 現況**:要 `X-Arcrun-API-Key`(owner 的 key)才能打 → 嚴格說「只有我能打」,不算對全世界暴露。
|
||||
但:(a) key 一旦外流就全開;(b) 用戶可能不知道「部署 webhook = 開了一個 endpoint」。
|
||||
→ **是否警示 webhook 部署?** 傾向「是」,因為用戶可能不知情它變成 endpoint,且這是「把 workflow 變 API」的那一步(richblack 最早的風險點)。
|
||||
|
||||
## 1. 兩道防線
|
||||
|
||||
### 1a. hook(防在前,AI 動手當下)
|
||||
AI 在本機寫「會變成可被外部呼叫的東西」前,hook 警告 + 要人類確認。可偵測的訊號:
|
||||
- 寫 workflow YAML 含 webhook trigger / 對外觸發設定。
|
||||
- 跑 `acr push`(部署 webhook)、未來的 recipe 公共貢獻指令。
|
||||
- pre-bash / pre-write hook 偵測這些 → 輸出警示「這會把 X 變成可被外部呼叫,需人類確認」。
|
||||
- **誠實限制**:hook 偵測的是「動作形態」(部署 webhook),不是「資料是否敏感」(機器判不準)。
|
||||
|
||||
### 1b. API 層(防在後,真的暴露前)
|
||||
暴露動作打到 server(webhook 部署 endpoint / 未來公共貢獻 endpoint)時,server 要求帶
|
||||
「人類已確認暴露」的明示旗標,沒帶 → 拒絕 + 提示。與 component-gatekeeping 的 human_confirmation 同模式:
|
||||
```ts
|
||||
exposure_confirmation?: {
|
||||
confirmed_by_human: true;
|
||||
understood_exposure: string; // 人類說明「我知道這會把什麼開放給誰」
|
||||
confirmed_at: string;
|
||||
}
|
||||
```
|
||||
缺 → 拒絕,訊息:「部署 webhook = 開一個對外可呼叫的 endpoint。確認你知道這會暴露 [workflow 名]
|
||||
的能力/輸出?用 `acr push --confirm-exposure` 並說明。」
|
||||
|
||||
### 為何兩道都要
|
||||
- 只有 hook:AI 可繞過 CLI 直接打 server API → API 層補。
|
||||
- 只有 API 層:AI 已經寫好暴露的東西才在送出時被擋,浪費 + 用戶較晚看到 → hook 提前。
|
||||
- 同 component-gatekeeping 的雙層精神。
|
||||
|
||||
## 2. 警示要讓人看得懂(R1)
|
||||
|
||||
不是「確認嗎 Y/N」,是說清楚風險:
|
||||
```
|
||||
⚠️ 這個動作會把 workflow "contacts_lookup" 變成可被外部呼叫的 endpoint:
|
||||
https://cypher.arcrun.dev/webhooks/named/contacts_lookup/trigger
|
||||
|
||||
任何持有觸發憑證的人都能呼叫它、取得它的輸出。
|
||||
這個 workflow 讀取:[盤出 workflow 用到的資料源,若可得]
|
||||
需要保護(要求呼叫者認證)嗎?目前的觸發認證是:[現況]
|
||||
|
||||
確認部署?(需人類明示)
|
||||
```
|
||||
- 「workflow 讀取什麼資料源」:盡力從 workflow 定義盤(用了哪些 recipe / endpoint),盤不出就標「無法自動判斷,請自行確認」。誠實。
|
||||
|
||||
## 3. known-destinations / 不重複問(R4 避免盲目按 yes)
|
||||
|
||||
觸發策略已經很窄(只暴露動作),但同一個 workflow 重複部署不該每次問。
|
||||
- 首次部署某 workflow 為 webhook → 問。人類確認後記住(該 workflow 標記 exposure-confirmed)。
|
||||
- 之後同 workflow 更新 → 不重問(除非暴露面變大,如新增對外觸發)。
|
||||
- 記在哪:workflow metadata(WEBHOOKS KV 的 record 加 `exposure_confirmed_at`)。
|
||||
|
||||
## 4. 與既有一致(R5)
|
||||
- 同 component-gatekeeping:AI 不可替人類決定有外洩風險的動作;誠實限制(AI 能偽造 confirmed_by_human,靠軌跡可審 + mindset)。
|
||||
- 同「arcrun 不做授權判斷」:不判斷「該不該暴露」,只「攔下來讓人類明示同意」。不禁止暴露,要明示同意。
|
||||
|
||||
## 5. 範圍邊界
|
||||
- **動**:webhook 部署路徑(webhooks-named.ts)的 exposure_confirmation + CLI `acr push --confirm-exposure` 互動 + hook。
|
||||
- **不動**:用戶 API 入站保護機制(發 key/權限/限流,另列 BACKLOG);recipe 私人 push(不暴露,不擋);出站 http 節點(不擋)。
|
||||
- recipe 公共貢獻路徑未實作 → 本系統只要求它**未來**內建 exposure 閘門(記進那條 BACKLOG 項)。
|
||||
|
||||
## 6. 決議(richblack 2026-05-30 design review)
|
||||
|
||||
- **Q1 → recipe push 也警示,公私一視同仁。** 不是因為 recipe 本身暴露,而是統一原則「凡有資料去向/暴露面的動作都警示」。用戶可選「以後不要警示」(記偏好)。理由見 §7 同意 log。
|
||||
- **Q2 → webhook 部署要警示,但角度是「提醒 + 提供保護」不是「擋」。** 用不用認證是用戶決定(如美國氣象 API 本就無 key 公開)。我們警示時**順便提醒「可用 arcrun 提供的保護措施」**(接「用戶 API 保護機制」資安優勢,BACKLOG 待決策)。首次問、記住(§3)。
|
||||
- **Q3 → hook 偵測 `acr push` 指令**(簡單版,pre-bash 攔指令)。
|
||||
|
||||
## 7. 同意 = 法律憑證(richblack 2026-05-30,重要)
|
||||
|
||||
每次人類同意「暴露/送資料」的動作,**留 log(誰、何時、同意了什麼)**。這不只是「軌跡可審」,是**法律保護**:
|
||||
|
||||
- 真發生資料外洩 / 糾紛時,有「用戶在 [時間] 明示知情同意把 [什麼] 暴露給 [誰]」的證據 → 避免訴訟風險(責任在明示同意的用戶,不在 arcrun)。
|
||||
- 「以後不要警示」這個選擇**本身也要 log**(用戶在 [時間] 選擇了不再對 [X] 警示 = 他知道風險並接受)。
|
||||
- 同意 log 存放:與動作關聯(webhook record / recipe record 的 `exposure_consent: { confirmed_by, understood, confirmed_at, suppress_future }`)。
|
||||
- 誠實限制同前:AI 能偽造 confirmed_by_human。但**法律意義上,憑證存在 + 可審 = 用戶有機會知情**,這道防線的價值是法律歸責不是技術防偽。
|
||||
|
||||
→ 這把 §1b 的 `exposure_confirmation` 升級為**帶法律意義的同意憑證**,所有暴露/送資料動作(recipe push / webhook 部署)共用此機制。
|
||||
|
||||
## 8. 警示是「保護措施的入口」(不只是攔)
|
||||
|
||||
警示訊息除了說明風險,**主動提供 arcrun 的保護措施**(產品價值,非只防呆):
|
||||
```
|
||||
⚠️ 這個動作會把 [X] 開放/送出。
|
||||
arcrun 可以幫你保護它:
|
||||
- 要求呼叫者帶 API Key(你發給特定對象)
|
||||
- 設定權限 / 限流
|
||||
一個動作就能加上。要加保護嗎?還是確認公開(如公開資料 API)?
|
||||
```
|
||||
(具體保護機制是 BACKLOG「用戶 API 保護機制」待決策項——本系統先在警示處**提示它存在**,實作後接上。)
|
||||
Reference in New Issue
Block a user