退休 CREDENTIALS_KV:所有 auth 零件改讀新家(Workers Secrets),不再抓 KV #14
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
0. 原則(leo 定案,D19「擁有目錄,不擁有內容物」)
credentials表(只存secret_ref指標 + metadata,無密文)。CREDENTIALS_KV。 自管ENCRYPTION_KEY自加密路(AES-GCM 密文存 KV)要廢(D19)。system-dev/docs/3-specs/arcrun/credential-primitives-wasm/credential-store-migration.md(T1.5–T9 已完成,T10 廢 ENCRYPTION_KEY 待此 PR)。本 issue 亦補齊 T6 對 oauth2 的漏網(T6 當時只改了 static_key / service_account)。rule 02 §2.1 本就列credential-injector.ts應刪。1. 現況已完成(雲端這輪核實,不必重做)
telegram_bot_token/notion_token/gitea_token)已在新家、namespaceleo(D1 目錄 + Workers Secrets)。ak_舊 KV 密文已刪(leo 名下CREDENTIALS_KV的{api_key}:cred:*已清空)。notify_leo成功送出 Telegram(因 leo 的 credential 從沒進過 KV,能送出=auth_static_key確實從新家secret_get(Workers Secrets)解出、沒讀 KV)。static_key 鏈已證新家可用。auth_static_key/main.go、auth_service_account/main.go已有ResolvedSecrets(cypher 先從新家取值塞 payload,WASM 優先用它,kv_get(cred:)僅 fallback)。2. 完整消費者盤點(具體到檔案行號,實作照這張表清)
2a. cypher-executor TS(純 config/TS,不需 TinyGo,可先做)
cypher-executor/src/actions/credential-injector.ts(全檔;KV 讀:82/:212、AES 解密decryptCredential、BUILTIN_CREDENTIALS_MAP、interpolateTemplate)cypher-executor/src/graph-executor.ts:4(import)、:291/295/298(injectCredentialsfallback)cypher-executor/src/routes/auth.ts:243-248(Googlerefresh_token寫 KV)、:322-327(GitHubaccess_token寫 KV)CREDENTIALS_KV(供 auth_oauth2 讀)CREDENTIALS_KV.put;連帶清aesEncrypt(移除後全檔無其他用途,generateApiKey保留=api-key 身份用途)cypher-executor/src/routes/credentials.ts:274(DELETElegacy-kvfallback)、:319-375(POST /credentials/migrate-to-workers-secrets端點,:336KV.list、:348KV.get)+import { createArcrunHostFunctions }(僅此端點用)MigrateResultinterface +createArcrunHostFunctionsimport;DELETE 改為「D1 有secret_ref→ 刪 Workers Secret + D1 row;無 → idempotent success(不再 fallback 刪 KV)」cypher-executor/src/lib/wasi-shim.ts:16(ArcrunHostEnv.CREDENTIALS_KV型別 +:13註解)、:666-679(routedKvGet的cred:路由 →:676)、:685-693(routedKvPut的oauth2:路由 →:689)CREDENTIALS_KV型別;routedKvGet只留auth_recipe: → RECIPES(保留,3 個 auth WASM 都靠它讀 recipe);routedKvPut的 oauth2 快取路由移除(見 §3 快取新家待定)。crypto_decrypt/aesGcmDecrypt(:699-710,用 ENCRYPTION_KEY)之去留見 §4cypher-executor/src/types.ts:32(CREDENTIALS_KV: KVNamespace)cypher-executor/src/routes/recipes.ts:4392b. WASM 零件 main.go(需 TinyGo 重編,本 PR 核心)
3 個 auth 零件的
.component-builds/auth_*/src/index.ts:18都import '../../../cypher-executor/src/lib/wasi-shim'(共用同一份 shim)→ 動 shim 就一起動,故必須整包協調。registry/components/auth_oauth2/main.goResolvedSecrets(T6 漏網)。硬靠kvGet(apiKey+":cred:"+refresh_token)+cryptoDecrypt讀 refresh_token(:290-307);且oauth2:前綴 KV 做 access_token 快取:讀:184-185/:236-240、寫kvPut:366-371ResolvedSecrets消費(比照 static_key)讓 refresh_token 走新家;access_token 快取改用不抓 CREDENTIALS_KV的新家(架構待定,見 §3)registry/components/auth_static_key/main.goResolvedSecrets已有(:53-57,:154,:239);kv_get(cred:)+cryptoDecryptfallback 仍在(:160-161,:245-246,解密:177,:262)kv_get(cred:)自解密 fallback(新家已是唯一真相源,ak_KV 已刪,不再需要雙讀錨點)registry/components/auth_service_account/main.goResolvedSecrets已有(:65-69,:190);kv_get(cred:)+cryptoDecryptfallback 仍在(:194-195,解密:210)2c. 4 顆 wrangler.toml 移除
binding = "CREDENTIALS_KV"(純 config,讓 namespace 可刪的關鍵)cypher-executor/wrangler.toml:22-24(ide7f4320f88d343f187e35e3543dd74c9).component-builds/auth_static_key/wrangler.toml:15-17.component-builds/auth_service_account/wrangler.toml:15-17.component-builds/auth_oauth2/wrangler.toml:14-16cypher-executor/wrangler.test.toml:19-21一併)3. 待定架構點(實作前需 leo/總管拍板):oauth2 access_token 快取放哪?
現況 auth_oauth2 用
CREDENTIALS_KV的oauth2:{service}:access_token/:expires_at(帶 TTL)快取換來的短效 token。這不是自加密 credential,是 runtime 快取,但寄生在同一顆 KV。退休 KV 後選項:建議 (a) 或 (c)。此點定案前 auth_oauth2 的 main.go 改動無法收尾。
4. ENCRYPTION_KEY 去留(誠實結論,別誤刪)
credential-injector.ts的decryptCredential(隨刪檔消失)、auth.ts的aesEncrypt(隨移除消失)、wasi-shim.ts的crypto_decrypt/aesGcmDecrypt(3 auth WASM 移除kv_get(cred:)fallback 後即無來源餵密文 → 該 host function 變 dormant;若同時移除 auth WASM 的//go:wasmimport u6u crypto_decrypt就可連 host fn 一起拿掉)。wasi-shim.ts:764-788createPlatformCryptoHostFunctions的 HMAC/AES(api-key 產生用)、auth.ts:52generateApiKey。→ ENCRYPTION_KEY secret 本身不可刪(api-key 身份還在用)。只能說「credential 面用途已清零」。5. 驗收(誠實禁假綠,mindset §7)
grep -rn CREDENTIALS_KV全 repo 零命中(含 registry WASM 源、cypher src、4+1 wrangler.toml、tests)。cd cypher-executor && npx tsc --noEmit過(含 tests,共用 shim 的 auth workers build 亦過)。tinygo build -target=wasi過 + copy 進.component-builds/*/component.wasm。notify_leolive 實測)。6. 邊界 / 不要做
secret_ref+ metadata)。acr updatecodeload 陷阱)。總管訂正(leo 定案,取代 issue 內 ENCRYPTION_KEY 段)
1. ENCRYPTION_KEY 可整把刪,不是「因 api-key 身份不可刪」。
generateApiKey(HMAC-of-email) //register/ api-key 發放全是死 SaaS 碼——ENCRYPTION_KEY 的「api-key 身份」用途不存在。auth.ts的generateApiKey、registerrouter、/register路徑、OAuth 用generateApiKey組 KV key 的 3 處)一併刪除。2. auth_oauth2 的 access_token 快取(leo 定):放短效快取即可。
3. 大原則(leo):長效資料(credential 目錄、recipe、triplet)一律 KBDB/新家,不得為閃避 KBDB 而塞 KV;KV 只留短效/暫存。
08-01 複核:◐ 半通——自管加密已廢、injector 已刪,但 CREDENTIALS_KV binding 未退休,保留
已完成(main 源碼實查):
cypher-executor/src/actions/credential-injector.ts已整檔刪除(git ls-tree gitea/main cypher-executor/src/actions/已無此檔)=盤點表 2a 第一列完成20c7610「移除已廢棄的自管加密金鑰機制(credential 全面託管 CF Workers Secrets)」=D19 核心已落地8d8b01d「credential-primitives-wasm 封存進 archive(T10 完成,卷已結案)」⇒ SDD 側 T10(廢 ENCRYPTION_KEY)已銷帳仍殘留(本 issue 保留的理由)——
CREDENTIALS_KV在 main 仍有 9 處引用:⇒ 本 issue 標題「所有 auth 零件改讀新家,不再抓 KV」尚未達成:
wasi-shim的kv_get(cred:)fallback 路徑還在,binding 也還掛著。建議收尾範圍(縮小後的剩餘工):拆
wasi-shim的cred:/oauth2:KV 路徑 → 清credentials.ts:286的 legacy fallback → 移types.ts與各 wrangler.toml 的 binding → 重部署 → leo dashboard 刪 namespace(人閘)。與 #16/#17 同屬 KV 退休戰,建議三張一起排。[總管·票務複驗 2026-08-09 晚] 仍然成立——用今天真的出貨到用戶手上的那顆 worker 反證,不是讀原始碼推測。
2026-08-09 出貨的
arcrun-rag1.4.29(bundle manifest,source: Arcrun@19c82df),裡面
arcrun-cypher-executor這顆 worker 宣告它必須綁這些 KV 才跑得起來:對照這四張票要退休的東西:
#14退休CREDENTIALS_KV→ 還在 requires 裡#16RECIPESKV → KBDB → 還在#17WEBHOOKSKV 退休 → 還在#2credential KV → D1 + Secrets Store → KV 那頭沒拆⇒ 四張全部仍存在,而且不是「程式碼裡還有殘跡」這種軟證據——
是今天新裝的用戶會被要求綁這些 KV,它們活在出貨路徑上。
📌 我把狀態標成
s/backlog(已驗過、確定要做、還沒排進任何 sprint)。這是保守的預設值,不是我對優先序的判斷——這個 repo 的 37 張票原本一張標籤都沒有,
等於在看板上不存在。要往上排的請直接改標,不必回頭問我。