feat(credentials): T6 讀取/注入接新家 + T7 雙讀 fallback (credential-store-migration 方案 A)
D19「擁有目錄不擁有內容物」遷移的讀取斷點。密文住 cypher per-script secrets、 D1 只存 secret_ref、auth worker 讀不到 cypher 的 secrets → cypher 先取值塞 payload。 WASM 端(T7 fallback 骨架,零行為改變可獨立部署驗): - auth_static_key/main.go + auth_service_account/main.go:Input 加 resolved_secrets, 解密處改「有 resolved 就用、沒有才 fallback 舊 kv_get+crypto_decrypt」。default 等於舊碼。 - tinygo build 兩支通過,copy 到 .component-builds/*/component.wasm。 TS 端(T6 主路徑): - auth-dispatcher.ts 新增 resolveSecretsFromNewHome:查 D1 拿 secret_ref → secret_get(env[ref], T4) 取明文 → 組 map(取不到的 name 缺席,不放空字串) → 更新 last_used_at。tryAuthDispatch + resolveCredentialRefs 都塞 resolved_secrets。 - rule 02 §2.2 對齊:只查 ref/取值/塞字串,不解密不展開模板不組 JWT。 驗證:cypher-executor + cli tsc exit 0;vitest 41/42(新增 auth-dispatcher.test.ts 6 案例全過, 剩 1 pre-existing 無關失敗)。待 leo21c 部署驗 WASM 端到端(不由本任務部署,acr update 硬綁 GitHub codeload=mistakes #23)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -50,6 +50,11 @@ type Input struct {
|
||||
// Names:resolve_credentials action 用——要解密的 credential 名稱清單
|
||||
// (用戶在 workflow node.data 寫 {{credential.NAME}} 時,graph-executor 收集後傳入)。
|
||||
Names []string `json:"names,omitempty"`
|
||||
// ResolvedSecrets:credential-store 遷移 T6/T7 方案 A(D19)——cypher-executor 已從
|
||||
// 自己的 per-script secrets(新家)用 secret_get(D1 ref) 取到的明文,key = credential name。
|
||||
// 有值就優先用,沒有才 fallback 舊路徑(kv_get {api_key}:cred:{name} + crypto_decrypt),
|
||||
// 這個 fallback 就是雙讀(T7)。default(此欄空/nil)行為完全等於遷移前的舊碼。
|
||||
ResolvedSecrets map[string]string `json:"resolved_secrets,omitempty"`
|
||||
}
|
||||
|
||||
type SecretRequirement struct {
|
||||
@@ -143,6 +148,15 @@ func main() {
|
||||
if req.Optional {
|
||||
continue
|
||||
}
|
||||
|
||||
// T6 方案 A:cypher 已從新家(per-script secrets)取到明文就直接用,不走 KV。
|
||||
// input.ResolvedSecrets 為 nil 時此 map 讀取回 ("", false),行為與遷移前一致。
|
||||
if v, ok := input.ResolvedSecrets[req.Key]; ok {
|
||||
secrets[req.Key] = v
|
||||
continue
|
||||
}
|
||||
|
||||
// T7 雙讀 fallback:新家沒給 → 走舊路徑 kv_get + crypto_decrypt。
|
||||
kvKey := input.APIKey + ":cred:" + req.Key
|
||||
encJSON, s := kvGet(kvKey)
|
||||
if s == 2 {
|
||||
@@ -220,6 +234,14 @@ func handleResolveCredentials(input Input) {
|
||||
if name == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
// T6 方案 A:cypher 已從新家取到明文就直接用(同 authenticate 分支)。
|
||||
if v, ok := input.ResolvedSecrets[name]; ok {
|
||||
credentials[name] = v
|
||||
continue
|
||||
}
|
||||
|
||||
// T7 雙讀 fallback:新家沒給 → 舊路徑 kv_get + crypto_decrypt。
|
||||
kvKey := input.APIKey + ":cred:" + name
|
||||
encJSON, s := kvGet(kvKey)
|
||||
if s == 2 {
|
||||
|
||||
Reference in New Issue
Block a user