[ PROMPT_NODE_24294 ]
Secrets Store 设计模式
[ SKILL_DOCUMENTATION ]
# 模式
## 密钥轮换
使用版本化命名实现零停机轮换 (`api_key_v1`, `api_key_v2`):
typescript
interface Env {
PRIMARY_KEY: { get(): Promise };
FALLBACK_KEY?: { get(): Promise };
}
async function fetchWithAuth(url: string, key: string) {
return fetch(url, { headers: { "Authorization": `Bearer ${key}` } });
}
export default {
async fetch(request: Request, env: Env): Promise {
let resp = await fetchWithAuth("https://api.example.com", await env.PRIMARY_KEY.get());
// 轮换期间的备用方案
if (!resp.ok && env.FALLBACK_KEY) {
resp = await fetchWithAuth("https://api.example.com", await env.FALLBACK_KEY.get());
}
return resp;
}
}
工作流: 创建 `api_key_v2` → 添加备用绑定 → 部署 → 切换主密钥 → 部署 → 移除 `v1`
## 使用 KV 进行加密
typescript
interface Env {
CACHE: KVNamespace;
ENCRYPTION_KEY: { get(): Promise };
}
async function encryptValue(value: string, key: string): Promise {
const enc = new TextEncoder();
const keyMaterial = await crypto.subtle.importKey(
"raw", enc.encode(key), { name: "AES-GCM" }, false, ["encrypt"]
);
const iv = crypto.getRandomValues(new Uint8Array(12));
const encrypted = await crypto.subtle.encrypt(
{ name: "AES-GCM", iv }, keyMaterial, enc.encode(value)
);
const combined = new Uint8Array(iv.length + encrypted.byteLength);
combined.set(iv);
combined.set(new Uint8Array(encrypted), iv.length);
return btoa(String.fromCharCode(...combined));
}
export default {
async fetch(request: Request, env: Env): Promise {
const key = await env.ENCRYPTION_KEY.get();
const encrypted = await encryptValue("sensitive-data", key);
await env.CACHE.put("user:123:data", encrypted);
return Response.json({ ok: true });
}
}
## HMAC 签名
typescript
interface Env {
HMAC_SECRET: { get(): Promise };
}
async function signRequest(data: string, secret: string): Promise {
const enc = new TextEncoder();
const key = await crypto.subtle.importKey(
"raw", enc.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]
);
const sig = await crypto.subtle.sign("HMAC", key, enc.encode(data));
return btoa(String.fromCharCode(...new Uint8Array(sig)));
}
export default {
async fetch(request: Request, env: Env): Promise {
const secret = await env.HMAC_SECRET.get();
const payload = await request.text()