⚠️ 待更新·2026-08-29核验 · 更新时间待核验 · 本文信息可能已过期,请以官方文档为准
更新时间:2026-08-29 · 核验状态:待更新 · 官方溯源待补
背景
应用直连每家模型时,Key 散落在配置文件、CI 变量、容器 env 里。一旦泄漏就要全量替换、滚动重启;不同团队成员各自拿 Key 又难以审计。把密钥全部收口到网关,客户端只见一个 APISHARE_TOKEN,所有上游 Key 的轮换、撤销、配额切分都在网关内部完成。
核心设计
- 双层 token:外层是发给客户端的
APISHARE_TOKEN(长期、可吊销);内层是上游 Provider Key(短期、可轮换)。两层解耦,内层换 Key 不影响客户端。
- Key 池与轮换:每个 Provider 维护多把 Key 组成池,按 hash 分桶;轮换时灰度切 10% 流量到新 Key,观察 5xx/429 比例再决定全量切换。
- 最小权限:为每个上游 Key 标注
scope(只读模型 / 调用 / 计费查询),客户端 token 也带 scope,网关两层校验。
- 审计日志:记录每次取 Key 的事件:时间、客户端 ID、Provider、Key hash(不入明文)。
- 金库后端:Key 落地前用 KMS 加密,运行时按需解密进内存;禁止落盘明文。
代码示例
import hashlib, time
class KeyVault:
def __init__(self, kms):
self.kms = kms
# provider -> list of encrypted key blobs
self.pool = {"groq": [...], "deepseek": [...]}
# rolling index for round-robin
self.idx = 0
def get(self, provider: str, client_id: str) -> str:
keys = self.pool[provider]
chosen = keys[self.idx % len(keys)]
self.idx += 1
plaintext = self.kms.decrypt(chosen)
self._audit(client_id, provider, plaintext)
return plaintext
def _audit(self, client_id, provider, key):
h = hashlib.sha256(key.encode()).hexdigest()[:12]
print(f"[audit] {time.time()} client={client_id} "
f"provider={provider} key={h}")
轮换安全边界
密钥轮换最大的风险是"轮换错对象"——把好 Key 撤了留下坏 Key,或新 Key 没生效就全量切换导致 0 流量。安全边界做法:每次只换一把 Key,把流量按 1% → 10% → 50% → 100% 四阶段灰度切换,每阶段持续 1 小时观察 401 比例;异常立刻回滚。同时维护"主备双池",新 Key 在备池验证 24 小时才提升为主池,杜绝"新 Key 即坏 Key"。
最佳实践
- 轮换周期:免费 Key 建议 30 天轮换,付费 Key 90 天;触发条件还包括异常 401 比例超阈值。
- 零信任:即使内部团队成员也只拿客户端 token,看不到上游 Key 明文。
- 降级方案:KMS 故障时,内存里仍能解密已加载 Key,但要禁止新 Key 入池,避免错 Key 进来。
- 漏泄响应:发现 Key 泄露后 5 分钟内必须完成撤销 + 新 Key 上线,有自动化脚本预案。
密钥集中不是把鸡蛋放一个篮子,而是把篮子换成一个有金库的房间。
⚠️ Pending Update · 2026-08-29 Verification · Content may be outdated, please refer to official docs
Updated: 2026-08-29 · Status: Pending Verification
Background
When applications talk directly to model providers, keys are scattered across config files, CI variables, and container envs. A single leak means a full rotation plus rolling restart, and different team members holding their own keys makes auditing painful. Funneling every key into the gateway changes the picture: clients see only one APISHARE_TOKEN, and rotation, revocation, and quota slicing all happen inside the gateway.
Core Design
- Two-layer tokens: the outer layer is the
APISHARE_TOKEN issued to clients (long-lived, revocable); the inner layer is the upstream provider key (short-lived, rotatable). The two are decoupled, so rotating the inner layer never disturbs clients.
- Key pool and rotation: each provider maintains a pool of keys bucketed by hash. Rotation shifts 10% of traffic to the new key first, watches 5xx/429 ratios, then decides on full cutover.
- Least privilege: each upstream key carries a
scope (read-models / invoke / billing-query); the client token also carries a scope, and the gateway enforces both layers.
- Audit log: every key fetch is logged with timestamp, client ID, provider, and a key hash (never plaintext).
- Vault backend: keys are KMS-encrypted at rest, decrypted into memory on demand; plaintext never touches disk.
Code Example
import hashlib, time
class KeyVault:
def __init__(self, kms):
self.kms = kms
# provider -> list of encrypted key blobs
self.pool = {"groq": [...], "deepseek": [...]}
# rolling index for round-robin
self.idx = 0
def get(self, provider: str, client_id: str) -> str:
keys = self.pool[provider]
chosen = keys[self.idx % len(keys)]
self.idx += 1
plaintext = self.kms.decrypt(chosen)
self._audit(client_id, provider, plaintext)
return plaintext
def _audit(self, client_id, provider, key):
h = hashlib.sha256(key.encode()).hexdigest()[:12]
print(f"[audit] {time.time()} client={client_id} "
f"provider={provider} key={h}")
Rotation Safety Boundary
The biggest risk in key rotation is "rotating the wrong one" — revoking a healthy key while leaving a bad one, or pushing a new key live before it activates, dropping traffic to zero. Safe boundary practice: rotate one key at a time, ramp traffic in four stages — 1%, 10%, 50%, 100% — each lasting an hour, watching the 401 ratio; rollback on anomaly. Maintain a "primary + standby" pool: a new key validates in the standby pool for 24 hours before being promoted to primary, eliminating "new key is bad key" scenarios.
Best Practices
- Rotation cadence: rotate free keys every 30 days and paid keys every 90 days; trigger an early rotation if anomalous 401 ratios cross threshold.
- Zero trust: even internal team members get only the client token — they never see upstream key plaintext.
- Degradation plan: if KMS fails, keys already loaded in memory remain usable, but new keys must be blocked from the pool to prevent mis-rotation.
- Leak response: on detecting a leak, complete revocation and new-key activation within 5 minutes using a pre-written automation script.
Centralizing keys is not "putting all eggs in one basket" — it is "replacing the basket with a vaulted room."