企业级 Agent 的「脑」安全——如何让每次模型访问都可控、可追溯、可计费。
一、背景:传统 API Key 的问题
企业部署 Agent,模型访问是核心能力。但大多数方案还在用静态 API Key:
❌ API Key 泄露 = 无限期可访问
❌ 无法精确追踪谁在调用
❌ revocation(吊销)困难
❌ 按使用量计费困难
❌ 无法控制端点访问时效
这些问题不只是「安全隐患」,更是**企业合规和成本管理」的痛点。
二、核心方案:URL 即凭证
我们的方案很简单:每个登录会话获得一个专属的、有时效的 LLM 访问端点。
传统方案:
客户端 → 持有静态 API Key → 访问 LLM
我们的方案:
客户端 → 登录 → 获得专属 URL(带随机 token)→ 访问 LLM
↓
URL 有时效,过期自动失效
URL 格式
https://llm-gw.example.com/v1/ep/xK9mQ2vL7pN4wR1tY6uJ3hB5cA0eG8dF/chat/completions
xK9mQ2vL...:32 位以上的 URL-safe 随机字符串,不可猜测- 路径本身即凭证,无需额外 Header 鉴权
三、核心流程
3.1 用户登录时
客户端 登录系统 大模型网关
│ │ │
│ 登录请求 │ │
│────────────────────────►│ │
│ │ 申请端点 │
│ │─────────────────────────►│
│ │ 生成随机 token │
│ │ 注册端点(含过期时间) │
│ │◄─────────────────────────│
│ 返回登录结果 │ │
│ { access_token, │ │
│ llm_base_url, │ │
│ expires_at } │ │
│◄────────────────────────│
登录成功后,客户端拿到一个专属的 llm_base_url,后续所有 LLM 请求都使用这个 URL。
3.2 Token 刷新时
刷新登录 Token 时,llm_base_url 保持不变,仅延长端点有效期。客户端无需感知切换。
3.3 用户登出时
登录系统 → 通知网关 DELETE /internal/endpoints/{token}
端点立即从注册表删除,即使有人拿到这个 URL,也无法再访问。
四、技术架构:三层拦截
网关用 Go 实现,利用其高性能 HTTP 处理能力,拦截逻辑作为中间件链:
请求进入 (Go net/http)
│
▼
┌─────────────────────────────────────────────┐
│ M1 - IP 速率限制 + 路径格式校验 │ ← 纯内存,纳秒~微秒级
│ • 令牌桶 IP 限流
│ • 正则校验 URL 路径格式
│ 拒绝:格式异常 / 超限 → 直接返回 403
└────────────────┬────────────────────────────┘
│ 格式合法
▼
┌─────────────────────────────────────────────┐
│ M2 - 端点有效性校验 │ ← 微秒级
│ • 优先查本地内存缓存 (sync.Map)
│ • 未命中则查 Redis,回填本地缓存
│ • 校验 expires_at
│ 拒绝:未注册/已过期 → 返回 403
│ 通过:将 user_id 注入 context
└────────────────┬────────────────────────────┘
│ 有效端点
▼
┌─────────────────────────────────────────────┐
│ M3 - 业务处理层 │
│ • 加载用户权限,应用模型/速率策略
│ • 代理请求至 LLM 上游
│ • 异步记录用量
└─────────────────────────────────────────────┘
为什么三层?
| 层级 | 作用 | 性能 |
|---|---|---|
| M1 | 快速过滤非法请求 | 纳秒级 |
| M2 | 校验端点有效性 | 微秒级 |
| M3 | 业务处理 | 正常延迟 |
非法请求在 M1/M2 层就被阻断,不会到达 LLM 上游,几乎不消耗后端资源。
五、数据存储
5.1 端点注册表(Redis)
Key: ep:{endpoint_token}
Type: Hash
Fields: {
user_id: "u_abc123",
expires_at: "1741795200", // Unix timestamp
created_at: "1741788000"
}
TTL: 与 expires_at 对齐(Redis 自动过期清理)
5.2 计费记录
每次 LLM 请求完成后异步写入:
{
"user_id": "u_abc123",
"endpoint_token": "xK9mQ2vL...",
"timestamp": "2026-03-12T15:30:00Z",
"model": "gpt-4",
"input_tokens": 1200,
"output_tokens": 350,
"latency_ms": 2300
}
每个请求都可追溯到具体用户,天然支持按量计费。
六、安全设计
6.1Anti-DDoS
| 措施 | 说明 |
|---|---|
| IP 速率限制 | 单 IP 每秒最多 100 次请求 |
| Token 速率限制 | 单端点每分钟请求上限 |
| 路径格式前置校验 | 不符合 [A-Za-z0-9_-]{32,64} 直接 403 |
| IP 黑名单 | 高频 403 的 IP 自动加入 |
| 内部 API 隔离 | /internal/* 绑定独立端口,不暴露公网 |
6.2 统一返回 403
无论端点是「未注册」还是「已过期」还是「格式错误」,统一返回 403,不泄露具体原因。
七、方案优势
| 优势 | 说明 |
|---|---|
| URL 即凭证 | 客户端无需管理额外 API Key |
| 自动过期 | 与登录态天然同步,无需额外吊销机制 |
| 前置拦截 | 非法请求在网关最前端被阻断 |
| 计费溯源 | 每个请求都可追溯到用户 |
| 无状态客户端 | 客户端只需持有一个 URL |
| 架构简洁 | Go 单进程完成限流、校验、代理全链路 |
八、适用场景
- 企业部署 Agent:需要精确的访问控制和计费
- 多租户系统:需要隔离每个租户的模型访问
- 敏感数据环境:需要审计谁在什么时间访问了什么模型
- 按量付费场景:需要精确统计每个用户的 Token 消耗
九、与第一篇的关系
| 篇 | 控制对象 | 核心能力 |
|---|---|---|
| 第1篇 | Agent 的「手」(工具执行) | 策略引擎 + DLP + 审批 |
| 第2篇 | Agent 的「脑」(模型访问) | URL 即凭证 + 动态端点 |
| 第3篇 | 执行环境 | 容器沙箱隔离 |
第一篇解决了 Agent 能否做的问题,第二篇解决了 Agent 能否访问模型的问题。
十、总结
LLM 网关的核心理念:
- 把 URL 变成凭证——不需要额外的 API Key 管理
- 让端点有时效——与登录态同步,过期自动失效
- 每一请求都可追溯——天然支持计费和审计
这是企业级 Agent 安全方案不可或缺的一环。
预告:第三篇将介绍容器沙箱隔离,解決 Agent 执行环境的安全问题。
本文是「企业级 Agent 安全方案」系列第 2 篇