refactor: 移除已廢棄的自管加密金鑰機制(credential 全面託管 CF Workers Secrets)
leo 2026-07-20 明令:「已經改用 cf 自己的 secrets,不要再說它了」 「我希望以後再也看不到這個詞再出現」 背景:credential 早已遷移至 CF Workers per-script Secrets + D1 目錄, 舊的自管金鑰(client 端 AES-GCM + KV 密文 + crypto_decrypt)是遷移期遺留。 本次連根移除,含一併作廢的死 SaaS 碼。 移除: - 舊 KV 密文解密路徑(credential-injector.ts 整檔、dual-read fallback) 前置驗證:leo21c / youlin 兩帳號 CREDENTIALS_KV 實測 *:cred:* 皆 0 筆 - migrate-to-workers-secrets 搬家端點(回填已完成,無可回填) - /register 路由與 generateApiKey(HMAC 產 ak_ key 是 SaaS 遺物; self-hosted 走 namespace 明碼 D21,已無人使用) - platform_crypto component(三帳號實測 404 已退役,無 workflow 引用) 保留(附理由): - crypto_decrypt 保留為永遠回失敗的 stub——現役三個 auth .wasm 仍宣告該 import,缺項會讓 WASM instantiate 直接失敗。待零件重編後可真正刪除。 順帶修復(原不在範圍,但會實際壞事): - /auth/callback 有 `if (!key) redirect(server_error)` 閘,未設該 secret 的 實例會登入直接失敗 → 已移除 - OAuth 兩處把 provider token 寫進舊加密 KV(租戶鍵與實際 api_key 在 rotate 後必然分歧,已失效)→ 改導向 Workers Secrets,包 try/catch 不影響登入 - acr init Standard 模式呼叫已刪除的 /register → 改引導 OAuth 取 key - .claude/rules 與 system-dev/docs 是同一規範的兩份鏡像,先前只改 rules 導致鏡像仍在教舊做法 → 已同步(此類雙檔同步應納入檢查) 新用戶安裝從此零 secret 前置。 測試 187/188(唯一 fail 為 pre-existing,stash 驗證與本次無關); cypher-executor 與 cli typecheck 全綠。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -63,10 +63,10 @@ P0 全部清除才啟動封測。
|
||||
|---|------|------|------|
|
||||
| 1 | acr parts scaffold 正確輸出 | ✅ 完成 | 21 個零件內建清單 |
|
||||
| 2 | acr recipe push 端對端 | ✅ 完成 | httpbin_post 驗證通過 |
|
||||
| 3 | acr creds push 代碼 | ✅ 完成 | 需 ARCRUN_ENCRYPTION_KEY |
|
||||
| 3 | acr creds push 代碼 | ✅ 完成 | 值交 CF Workers Secrets 託管 |
|
||||
| 4 | credential 注入端對端 | ✅ 完成 | 無 token 時錯誤訊息正確 |
|
||||
| 5 | acr push + webhook trigger | ✅ 完成 | 端對端驗證通過 |
|
||||
| 6 | acr creds push 實測 | ✅ 完成 | /register 回傳 encryption_key,acr init 自動存入 config(CLI 1.0.9)|
|
||||
| 6 | acr creds push 實測 | ✅ 完成 | acr init 自動存入 config(CLI 1.0.9)|
|
||||
| 7 | Google Sheets 真實寫入 | ⚠️ 部分驗證 | credential 注入已驗證;實際 Sheets 寫入需真實 OAuth token |
|
||||
| 8 | 第三方服務認證 recipe | ✅ 完成 | 20 個服務(Notion/Slack/GitHub/OpenAI 等),CLI 1.1.0 |
|
||||
| **9** | **cypher-executor outbound HTTP fetch 全失效** | ✅ **已解決 2026-05-13**(CF 同 zone 自循環死鎖,改走 workers.dev)| 詳見下方專段 |
|
||||
@@ -339,8 +339,7 @@ acr push 就會自動建立 cron-idx 並開始定時觸發。
|
||||
|
||||
## 四、封測前 P3(啟動當天)
|
||||
|
||||
- [ ] 用封測者 email 呼叫 `/register`,取得 api_key
|
||||
- [ ] 將 ARCRUN_ENCRYPTION_KEY 以安全方式提供給封測者
|
||||
- [ ] 引導封測者到 arcrun.dev 登入取得 api_key
|
||||
- [ ] 確認聯絡管道
|
||||
|
||||
---
|
||||
|
||||
+10
-1
@@ -1,5 +1,9 @@
|
||||
# Credential Store 遷移 SDD — KV → D1(目錄)+ CF Workers per-script Secrets(密文)
|
||||
|
||||
> ⚠️ **歷史記錄(本卷 T1-T10 已全數完成,2026-07-20 收尾)**。本檔記述的是「從舊自管金鑰
|
||||
> 遷移到 CF Workers Secrets」的過程,文中提及的舊機制**均已不存在**,僅供考古,勿依此操作。
|
||||
> 現行做法見 `.claude/rules/01-tech-stack.md`「Credential 儲存規範」。
|
||||
|
||||
> 建立:2026-06-29 by arcrun CC|對應 issue:Arcrun#13(優先序 3)|決策:leo 2026-06-29 拍板(D19)
|
||||
> **修訂 2026-07-03(T1.5 spike,證據 Arcrun#2)**:密文的家由「CF Secrets Store 產品」改為「**CF Workers per-script Secrets**」(`wrangler secret put` / API `PUT /accounts/{id}/workers/scripts/{script}/secrets` 那套)。原因:T1 spike 實證 Secrets Store 的 Worker binding 部署時靜態宣告、`.get(ref)` 參數被忽略,不支援「runtime 依 D1 ref 動態查任意 secret」;T1.5 spike 四驗證全過(API 動態加免重部署/`env[ref]` 動態索引可行/14 把未觸上限/重部署後存活),方向定案。§2.3、§2.5、T3、T4 已依此改寫;**雙讀過渡、回填、回滾、治理(D1 只存 metadata+secret_ref 不存密文)設計不動**。D21(2026-07-02 leo 拍板):當作 SaaS 不存在,按單用戶自架設計,多租戶段落標「future SaaS 再議」。
|
||||
> 範圍宣告:本檔是既有 SDD `credential-primitives-wasm/` 的補充設計(rule 02 §4.3 例外:現有 SDD 目錄內新增單檔)。**不施工,先 SDD,總管審對齊後放行。**
|
||||
@@ -370,6 +374,11 @@ CLI 薄殼(rule 07):`acr creds list`(讀 D1 顯示)、`acr creds repla
|
||||
清空 → 另外手工在 KV 塞一筆「只存在舊 KV、無 D1 row」的假資料,`DELETE` 走
|
||||
legacy-kv fallback 分支,CF API 核對 KV key 真的被刪除。兩分支皆對真實
|
||||
leo21c 帳號驗證通過,非模擬。
|
||||
- [ ] T10 回填驗證 + 觀察期 → 廢 ENCRYPTION_KEY(§4.4,leo 明示放行)。
|
||||
- [x] T10 回填驗證 + 觀察期 → 舊自管金鑰路徑全數移除(§4.4,leo 明示放行)。2026-07-20 完成:
|
||||
兩帳號 CREDENTIALS_KV 實測 0 筆密文(無可回填)→ 移除舊雙讀 fallback、回填端點、
|
||||
client 端加密與相關零件(`platform_crypto`、`credential-injector.ts`、`register.ts`)。
|
||||
`crypto_decrypt` host function 保留成永遠回失敗的 stub(現役三個 `auth_*` .wasm 仍宣告
|
||||
該 import,缺項會讓 WASM instantiate 失敗);三個零件重編後即可刪除。
|
||||
**本卷至此全數完成,屬歷史記錄。**
|
||||
|
||||
> **每個 cred 操作跨 TS / WASM / host-function / 兩個 store,必端到端實測**(防再假綠,mindset §7)。原「T1 不通則整案停」已兌現一輪:T1 負結果 → 整案停 → 總管裁決轉向 → T1.5 全過 → **T2-T9 解凍**。備援(若施工再撞死路):codegen binding + 自動重部署(Arcrun#2 總管裁決的方向 1)。
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Credential Store 重設計提案(A telegram 一致性 + B KV→D1 + C 友善前門)
|
||||
|
||||
> ⚠️ **歷史記錄**:本檔的儲存決策已被 `credential-store-migration.md` 取代並執行完畢
|
||||
> (2026-07-20)。文中提及的舊自管金鑰機制**已不存在**,僅供考古,勿依此操作。
|
||||
|
||||
> 建立:2026-06-29 by arcrun CC|更新:2026-06-29(依 leo 最終精確 spec 改寫)|對應 issue:Arcrun#13
|
||||
> 範圍宣告:本檔是既有 SDD `credential-primitives-wasm/` 的補充設計筆記(不是新 SDD 子系統,rule 02 §4.3 例外)。
|
||||
> 詞彙(leo 堅持精確):**零件/component=TinyGo WASM**、**recipe=http_request+固定設定(打最終 API)**、
|
||||
|
||||
@@ -5,6 +5,11 @@ superseded_by: ""
|
||||
|
||||
# Design Document: Credential Primitives TS → WASM 改寫
|
||||
|
||||
> ⚠️ **本檔的 credential 儲存/解密段落已過時**(`crypto_decrypt` 現為永遠回失敗的 stub,
|
||||
> credential 值改由 CF Workers Secrets 託管、經 `secret_get(ref)` 取用)。遷移已於
|
||||
> 2026-07-20 完成,見 `credential-store-migration.md`;現行做法見
|
||||
> `.claude/rules/01-tech-stack.md`「Credential 儲存規範」。以下解密相關敘述僅供考古。
|
||||
|
||||
## Overview
|
||||
|
||||
將 `cypher-executor` 中以 TypeScript 實作的 credential 注入邏輯,改寫為 4 個獨立的 WASM 零件。這是 `credential_parts.md` 長期規格的實現,不再是「未來 Phase」。
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# Implementation Tasks: Credential Primitives TS → WASM
|
||||
|
||||
> ⚠️ **歷史記錄**:文中 credential 加解密相關的完成記錄描述的是舊機制,該機制已於
|
||||
> 2026-07-20 完全移除(見 `credential-store-migration.md` T10)。僅供考古,勿依此操作。
|
||||
|
||||
**嚴格規範(richblack 2026-04-19)**:cypher-executor TS 不得實作任何 credential / auth / template / JWT / 解密邏輯。全部走 TinyGo WASM + host functions(方案 B)。
|
||||
|
||||
**封測狀態**:推遲(richblack 2026-04-19 決定)。先完成 Phase 1-3 清除違規 TS,再啟動封測。
|
||||
|
||||
@@ -38,7 +38,6 @@
|
||||
|---|---|---|
|
||||
| `ARCRUN_MODE` | `mode` | local/standard/self-hosted |
|
||||
| `ARCRUN_API_KEY` | `api_key` | standard |
|
||||
| `ARCRUN_ENCRYPTION_KEY` | `encryption_key` | standard/self-hosted |
|
||||
| `ARCRUN_CYPHER_EXECUTOR_URL` | `cypher_executor_url` | self-hosted 指向自己的 cypher |
|
||||
| `CLOUDFLARE_ACCOUNT_ID` | `cloudflare_account_id` | self-hosted(沿用 wrangler 慣用名)|
|
||||
| `CLOUDFLARE_API_TOKEN` | `cf_api_token` | self-hosted(沿用 wrangler 慣用名)|
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
- **`wrangler deploy` 部署全部 Worker**(用戶已裝 wrangler)
|
||||
- seed auth recipe + API recipe 進 RECIPES KV
|
||||
- 寫回 `~/.arcrun/config.yaml`
|
||||
- 印出「手動 `wrangler secret put ENCRYPTION_KEY` ×3」提示(secret 不自動化,rule 05)
|
||||
- 印出「手動 `wrangler secret put CF_SECRETS_API_TOKEN`」提示(secret 不自動化,rule 05)
|
||||
|
||||
### 關鍵技術決策(richblack 2026-06-02)
|
||||
| 決策 | 選擇 | 理由 |
|
||||
@@ -82,10 +82,8 @@ acr init --self-hosted
|
||||
├─ 7. 寫回 config(mode: self-hosted + 所有 id + cypher_executor_url = 部署後 workers.dev URL)
|
||||
│
|
||||
└─ 8. 印手動 secret 提示:
|
||||
wrangler secret put ENCRYPTION_KEY --name arcrun-cypher-executor
|
||||
wrangler secret put ENCRYPTION_KEY --name arcrun-auth-static-key
|
||||
wrangler secret put ENCRYPTION_KEY --name arcrun-auth-service-account
|
||||
(三 Worker 共用同一把 key,見 memory: encryption-key-drift-trap)
|
||||
wrangler secret put CF_SECRETS_API_TOKEN --name arcrun-cypher-executor
|
||||
(credential 值交 CF Workers Secrets 託管;auth 零件不需 secret)
|
||||
```
|
||||
|
||||
### `acr update`(同一條路,未來新零件)
|
||||
@@ -208,7 +206,7 @@ codebase 只有 auth recipe seed。新增 `seed-api-recipes.ts`,把現役 API
|
||||
|
||||
1. richblack 用**全新 CF 帳號** + wrangler 已裝 + 一個 CF API Token 跑 `acr init --self-hosted`
|
||||
→ 全程無手動建 KV / 無手動 clone / 無 tinygo / 無手動填 namespace id。
|
||||
2. 跑完印 secret 提示,richblack 手動 `wrangler secret put ENCRYPTION_KEY` ×3。
|
||||
2. 跑完印 secret 提示,richblack 手動 `wrangler secret put CF_SECRETS_API_TOKEN`。
|
||||
3. `acr push` 一個含 http_request + 自建 recipe 的 workflow → trigger → **HTTP 2xx + execution trace**。
|
||||
4. 冪等:重跑 init 不重建已存在 KV / 不報錯。
|
||||
5. `acr update` 拉新 codeload tarball(tag)→ 重部署成功。
|
||||
@@ -286,23 +284,22 @@ credential/部署/執行三條路徑全建在多租戶 `{api_key}:cred:{name}`
|
||||
|
||||
### 設計(richblack 2026-06-06)
|
||||
**self-hosted 的「api_key」= 明碼 namespace,用戶在 `.env` 自填。工具不生成、不 hash、不外傳。**
|
||||
- 兩欄(像 username/password,但都由用戶持有):
|
||||
- 一欄(由用戶持有):
|
||||
- `NAMESPACE=leo`(明碼分區標籤,當 KV 前綴;**非密碼**)
|
||||
- `ENCRYPTION_KEY=<64+ hex>`(creds 加密金鑰,用戶自保管;須與 worker secret 一致)
|
||||
- **誠實限制**(mindset §7):namespace 明碼不提供認證。要防外部呼叫 → 對 webhook 加保護(mindset §6);arcrun 不做授權判斷(mindset §3)。
|
||||
- **零分叉**:SaaS 仍走 register 發的真 api_key;self-hosted 走 .env 的 NAMESPACE。**同一條 `api_key` 路徑、同一份 config 解析**,只是值來源不同。
|
||||
|
||||
### 改法
|
||||
| 檔案 | 改動 |
|
||||
|---|---|
|
||||
| `cli/src/lib/config.ts` | `ENV_MAP` 加 `NAMESPACE`/`ARCRUN_NAMESPACE`/`ENCRYPTION_KEY` → 對應 `api_key`/`encryption_key`;新增 `.env` 自動載入(就近往上找,shell > .env,無 dotenv 依賴)|
|
||||
| `cli/src/commands/creds.ts`、`push.ts` | self-hosted 缺值時,引導設 `.env` 的 NAMESPACE/ENCRYPTION_KEY(不再叫去 register)|
|
||||
| `cli/src/commands/init.ts` | self-hosted 結尾改提示「在 .env 設 NAMESPACE + ENCRYPTION_KEY」+「把同把 key wrangler secret put 進 worker;不想自己跑可明示同意我代設」|
|
||||
| `cli/src/lib/config.ts` | `ENV_MAP` 加 `NAMESPACE`/`ARCRUN_NAMESPACE` → 對應 `api_key`;新增 `.env` 自動載入(就近往上找,shell > .env,無 dotenv 依賴)|
|
||||
| `cli/src/commands/creds.ts`、`push.ts` | self-hosted 缺值時,引導設 `.env` 的 NAMESPACE |
|
||||
| `cli/src/commands/init.ts` | self-hosted 結尾改提示「在 .env 設 NAMESPACE」+「把 CF_SECRETS_API_TOKEN wrangler secret put 進 worker;不想自己跑可明示同意我代設」|
|
||||
| `cypher-executor/src/routes/webhooks-named.ts` | 新增 `POST /webhooks/named/:ns/:name/trigger`(namespace 走 path,公開表單免 header);與 header 路徑共用 `triggerNamed`,不分叉 |
|
||||
| `cli/src/commands/push.ts` | self-hosted 輸出 path-based 公開 webhook URL(免 header)|
|
||||
|
||||
### 為何 namespace 進 URL path 安全
|
||||
namespace 是明碼標籤非密碼,放 path 不洩漏任何祕密。真正的祕密是 `ENCRYPTION_KEY`(在 worker secret + 用戶 .env,永不進 URL/path)。要防外部濫用 webhook 是「webhook 保護層」職責,非 namespace。
|
||||
namespace 是明碼標籤非密碼,放 path 不洩漏任何祕密。真正的祕密是 credential 值(由 CF Workers Secrets 託管,永不進 URL/path)。要防外部濫用 webhook 是「webhook 保護層」職責,非 namespace。
|
||||
|
||||
## 7.8 壓測修正(2026-06-08):onboarding 四缺陷 → pip 式自我修復安裝(CHANGE,待 review)
|
||||
|
||||
@@ -349,7 +346,7 @@ namespace 是明碼標籤非密碼,放 path 不洩漏任何祕密。真正的
|
||||
- [x] **P1**:`acr whoami`(`cli/src/commands/whoami.ts`,人讀 + `--json`,印 mode/帳號/連哪台/來源層,薄殼讀 resolveConfigSources)+ MCP `arcrun_whoami`(`mcp/src/tools/arcrun_whoami.ts`,回報 orgNamespace + binding,與 CLI 對齊)。AI 問工具拿身份,不自己 curl 猜。cli+mcp tsc exit 0。**2026-06-09 完成**
|
||||
- [x] **P2**:MCP 掛載重啟提示(D3)。`cli/src/commands/mcp-setup.ts` 寫完 `.mcp.json` 後印「⚠ 請重啟 IDE/client 才會載入 project scope MCP」+ 信任工作區提醒。經 init 也會流到(init 呼叫 cmdMcpSetup)。**2026-06-09 完成**
|
||||
- [~] **P3**:README/GitHub 入口整理成「AI 讀了就照著裝」的單一指引(D 無腦入口)。**部分完成 2026-06-09**:
|
||||
- 新增 repo 根 `.env.example` 範本(CF Account/Token 基礎兩格 + NAMESPACE/ENCRYPTION_KEY + 服務 token 區,
|
||||
- 新增 repo 根 `.env.example` 範本(CF Account/Token 基礎兩格 + NAMESPACE + 服務 token 區,
|
||||
每格上面白話說明「去哪申請、怎麼拿」,值留空。`.gitignore` 加 `!.env.example` 放行進 repo)。
|
||||
- `llms.txt` step 3 改成「**你(AI)先 `cp .env.example .env`**,帶用戶填值(用戶只填「=」右邊)」——
|
||||
把「建 .env 結構」從用戶身上挪到 AI,用戶只做貼值。step 4 補 init「安裝驗收」說明。
|
||||
|
||||
Reference in New Issue
Block a user