认证
每一个 /agents* 路由都限定在某个组织的作用域内。只有一种认证原语 —— API 密钥 ——
以及一个签发密钥的地方。
Authorization: Bearer ik_live_2718ddec_a1b2c3d4e5f6...
密钥格式
ik_live_2718ddec_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
└─────前缀──────┘└──────────── 密文 ─────────────┘
我们存储的是前缀和 sha256(完整密钥)。密文那一半在签发时只返回一次,之后再也不会 ——
列表里没有,找支持也没有,从数据库也拿不到。密钥丢了是换一把,不是找回来。
前缀可以安全地记录和展示。它是密钥在 GET /keys 中的呈现方式,也是你撤销时要传的东西。
签发密钥
这个路由需要一个已登录的控制台会话,所以它不是一条你能在终端里跑的 curl。
控制台目前还没有密钥管理界面;在它出现之前,请在
incarna.io 登录状态下从浏览器签发 ——
控制台的服务端会把你已验证的身份转发给 API。
await fetch("/api/keys", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ name: "production-backend" }),
}).then((r) => r.json());
{
"key": "ik_live_2718ddec_a1b2c3d4e5f6...",
"prefix": "ik_live_2718ddec",
"name": "production-backend"
}
API 密钥不能签发另一把 API 密钥,这条限制是有意的,不是疏漏:
一把能签发密钥的密钥,活得比自己的撤销更久。它泄漏一次,持有者就再签一把, 于是撤销第一把毫无意义。签发这件事必须留在「有人类完成过认证」的那个界面上 —— 那才是一份真的能被收回的凭据。
用 API 密钥调用 POST /keys 会返回 403 forbidden。
列出与撤销
两者同样只限控制台会话,理由相同,方式也一样 —— 在已登录的浏览器里调用
GET /api/keys 和 DELETE /api/keys/{prefix}。
[
{
"prefix": "ik_live_2718ddec",
"name": "production-backend",
"created_at": "2026-08-02T13:41:02.118Z",
"last_used_at": "2026-08-02T14:02:55.907Z",
"revoked_at": null
}
]
last_used_at 在每一次通过认证的请求上更新,这让它成为找出「已经没人用的密钥」的最快办法。
撤销立即生效 —— 下一个带该密钥的请求就会拿到 401。撤销限定在调用方所属的组织:
属于另一个租户的前缀返回 404,而不是跨租户撤销。前缀对任何持有该密钥的人都是可见的,
所以「知道一个前缀」绝不能足以停用它。
被撤销的密钥仍留在列表中,revoked_at 有值。它们不会被删除,因此审计线索得以保留。
控制台这条路径
Web 控制台不持有 API 密钥。它用 Clerk 认证浏览器,再由它的服务端把已验证的身份转发给 API:
Authorization: Bearer <INCARNA_SERVICE_SECRET>
X-Incarna-Clerk-Id: user_...
X-Incarna-Email: someone@example.com
X-Incarna-Name: Someone
这里的 bearer 是一份只由 backend-for-frontend 持有、浏览器永远拿不到的共享密钥。
这条路径正是 POST /keys 接受的,也正是 MCP 刻意不接受的 ——
MCP 的调用方是程序,应当携带一份可以被单独撤销的凭据。
速率限制
每个组织每分钟 120 次请求,滚动 60 秒窗口。超出时:
HTTP/1.1 429
{"error":{"code":"rate_limited","message":"rate limit exceeded (120/min)"}}
限制是按组织计的,不是按密钥,所以多签几把密钥并不会把它抬高。
凭据的处理
Incarna 对客户的平台凭据做静态加密存储,且从不以明文记录它们。作为交换,有两件事需要你做到:
- 绝不要把 Incarna 密钥放进客户端代码。 它是一份组织级凭据; 任何持有它的东西都能操作该组织下的每一个 agent。
- 任何被粘贴到不该粘贴的地方的东西都要轮换 —— 聊天、工单、截图。 先签一把新的、部署上去,再撤销旧的前缀。顺序不能反;先撤销会造成一次故障。