API密钥管理
--- title: "API密钥管理" description: "全面介绍LLM API密钥的生成、存储、轮换和安全管理实践" tags: ["API密钥", "密钥管理", "安全"] category: "llm" icon: "🧠"
API密钥管理
为什么密钥管理很重要
API密钥是访问LLM服务的凭证,一旦泄露可能导致账户被盗用、产生巨额费用或数据泄露。有效的密钥管理策略是保护LLM应用安全的基础。
密钥生成最佳实践
使用安全的随机数生成器
import secrets
import hashlib
from datetime import datetime
class APIKeyGenerator:
def __init__(self, prefix="sk"):
self.prefix = prefix
def generate_key(self, length=48) -> str:
# 使用密码学安全的随机数生成器
random_bytes = secrets.token_bytes(length)
key_material = secrets.token_hex(length // 2)
return f"{self.prefix}-{key_material}"
def generate_scoped_key(self, scopes: list, user_id: str) -> str:
key = self.generate_key()
# 将作用域信息编码到密钥中(不包含敏感信息)
scope_hash = hashlib.sha256(
f"{user_id}:{':'.join(scopes)}".encode()
).hexdigest()[:8]
return f"{key}_{scope_hash}"
密钥格式规范
建议采用清晰的密钥格式,便于识别和管理。
class APIKeyFormat:
# 常见的密钥格式示例
FORMATS = {
"openai": "sk-[48个字符]",
"anthropic": "sk-ant-[32个字符]",
"custom": "llm_[环境]_[40个字符]"
}
@staticmethod
def validate_format(api_key: str, format_type: str) -> bool:
import re
patterns = {
"openai": r"^sk-[a-zA-Z0-9]{48}$",
"anthropic": r"^sk-ant-[a-zA-Z0-9]{32}$",
"custom": r"^llm_(prod|dev|test)_[a-zA-Z0-9]{40}$"
}
pattern = patterns.get(format_type)
if not pattern:
return False
return bool(re.match(pattern, api_key))
安全存储方案
环境变量
最简单但有效的存储方式。
import os
from dataclasses import dataclass
@dataclass
class LLMConfig:
api_key: str
org_id: str = None
base_url: str = None
@classmethod
def from_env(cls) -> "LLMConfig":
api_key = os.getenv("LLM_API_KEY")
if not api_key:
raise ValueError("LLM_API_KEY环境变量未设置")
return cls(
api_key=api_key,
org_id=os.getenv("LLM_ORG_ID"),
base_url=os.getenv("LLM_BASE_URL")
)
密钥管理服务
企业环境应使用专业的密钥管理服务。
import hvac # HashiCorp Vault客户端
class VaultKeyManager:
def __init__(self, vault_url, token):
self.client = hvac.Client(url=vault_url, token=token)
def get_secret(self, path: str, key: str) -> str:
secret = self.client.secrets.kv.v2.read_secret_version(
path=path
)
return secret["data"]["data"][key]
def rotate_secret(self, path: str, key: str, new_value: str):
self.client.secrets.kv.v2.create_or_update_secret(
path=path,
secret={key: new_value}
)
def list_secrets(self, path: str) -> list:
return self.client.secrets.kv.v2.list_secrets_versions(
path=path
)
密钥轮换策略
定期轮换
设置自动轮换周期,降低密钥泄露风险。
from datetime import datetime, timedelta
from typing import Optional
class KeyRotationManager:
def __init__(self, rotation_days: int = 90):
self.rotation_days = rotation_days
self.key_registry = {}
def register_key(self, key_id: str, created_at: datetime):
self.key_registry[key_id] = {
"created_at": created_at,
"last_rotated": created_at,
"is_active": True
}
def needs_rotation(self, key_id: str) -> bool:
if key_id not in self.key_registry:
return True
key_info = self.key_registry[key_id]
days_since_rotation = (datetime.now() - key_info["last_rotated"]).days
return days_since_rotation >= self.rotation_days
def rotate_key(self, key_id: str, new_key_func) -> str:
if key_id not in self.key_registry:
raise ValueError(f"密钥 {key_id} 不存在")
new_key = new_key_func()
# 保留旧密钥一段时间用于验证
self.key_registry[key_id]["is_active"] = False
self.key_registry[f"{key_id}_backup"] = {
"key": self.key_registry[key_id].get("key"),
"expires_at": datetime.now() + timedelta(hours=24)
}
# 注册新密钥
self.key_registry[key_id] = {
"key": new_key,
"created_at": datetime.now(),
"last_rotated": datetime.now(),
"is_active": True
}
return new_key
密钥使用监控
监控密钥使用情况,及时发现异常。
from collections import defaultdict
from datetime import datetime, timedelta
class KeyUsageMonitor:
def __init__(self):
self.usage_records = defaultdict(list)
self.alerts = []
def record_usage(self, key_id: str, endpoint: str,
success: bool, response_time: float):
self.usage_records[key_id].append({
"timestamp": datetime.now(),
"endpoint": endpoint,
"success": success,
"response_time": response_time
})
def detect_anomalies(self, key_id: str) -> list:
anomalies = []
records = self.usage_records.get(key_id, [])
if len(records) < 10:
return anomalies
# 检查请求频率异常
recent_records = [r for r in records
if r["timestamp"] > datetime.now() - timedelta(hours=1)]
if len(recent_records) > 1000:
anomalies.append({
"type": "high_frequency",
"message": f"过去1小时内有{len(recent_records)}次请求",
"severity": "high"
})
# 检查失败率异常
failure_count = sum(1 for r in recent_records if not r["success"])
failure_rate = failure_count / len(recent_records) if recent_records else 0
if failure_rate > 0.5:
anomalies.append({
"type": "high_failure_rate",
"message": f"失败率{failure_rate:.2%}超过阈值",
"severity": "medium"
})
return anomalies
安全检查清单
- 不在代码中硬编码密钥:使用环境变量或密钥管理服务
- 限制密钥作用域:只授予必要的最小权限
- 启用密钥轮换:定期更换密钥
- 监控使用情况:设置异常告警
- 及时撤销泄露密钥:发现泄露立即禁用
- 使用不同的密钥:生产、测试环境使用不同密钥
正确的密钥管理能有效降低安全风险,保护你的LLM应用。