API Key
每个 App 可以签发多把 Key。Key 是长期 bearer token(eapk_live_xxx 格式)。
端点
创建 Key
POST /openapi/v1/apps/:clientId/keys
Body:
{
"scopes": ["projects:read", "tasks:read", "risks:read"],
"expiresAt": "2026-12-31T23:59:59Z"
}
成功响应(仅此一次包含完整 Key):
{
"success": true,
"data": {
"id": "cmsj1vydh0003sfhagsre5lj5",
"clientId": "eacli_xxx",
"apiKey": "eapk_live_VYPC4AD5D1BN22E96SFV78",
"prefix": "eapk_live_VYP",
"lastFour": "FV78",
"scopes": ["projects:read", "tasks:read", "risks:read"],
"expiresAt": null,
"createdAt": "2026-08-07T14:39:03.366Z"
}
}
列出 Key
GET /openapi/v1/apps/:clientId/keys
只显示 prefix / lastFour / scopes / createdAt / lastUsedAt / expiresAt —— 完整 Key 永远不会再次出现。
撤销 Key
DELETE /openapi/v1/apps/:clientId/keys/:keyId
立即生效。撤销后所有引用此 Key 的请求返回 401 INVALID_TOKEN。
Key 不可真正删除(保留审计记录),只标记 revokedAt。
安全
apiKey仅创建时返回一次——丢失后必须重新创建- 完整 Key 不存在数据库;存的是 argon2id 哈希(即使数据库泄露也无法恢复)
prefix索引到数据库用于 O(1) 查询;lastFour仅 UI 展示用- 撤销是软删除(
revokedAt时间戳),不是物理删除
端到端
# 1. 创建 Key
KEY=$(curl -X POST https://easypm.yiproject.com/openapi/v1/apps/$CLIENT_ID/keys \
-H "X-Client-ID: $CLIENT_ID" \
-H "Cookie: sid=$SID" \
-H "Content-Type: application/json" \
-d '{"scopes":["projects:read"]}' | jq -r '.data.apiKey')
# 2. 使用 Key
curl https://easypm.yiproject.com/openapi/v1/resource/project/list \
-H "X-Client-ID: $CLIENT_ID" \
-H "Authorization: $KEY"
# 3. 撤销
curl -X DELETE https://easypm.yiproject.com/openapi/v1/apps/$CLIENT_ID/keys/$KEY_ID