IWish Auth开发者文档
V1 Alpha GitHub

Service Token 与 Webhook

机器身份、签名验签、幂等投递和缓存失效

Service Token 与 Webhook

业务 App 的服务端任务使用 Service Token 调用 IWish Auth;权限或身份上下文发生变化时,IWish Auth 通过 Webhook 通知业务 App 清理缓存。两者都只允许在服务端使用。

1. Service Token

管理员在“系统集成”中先创建 Service Account,再签发 iwa_ 开头的 Token。

  • Token 明文只显示一次,必须立即写入业务 App 的服务端 Secret 管理。
  • 数据库只保存带服务端 pepper 的 HMAC-SHA256 hash。
  • Service Account 可以绑定 App、组织、scope 和到期时间。
  • Token scope 必须是 Service Account scope 的子集。
  • 停用 Service Account 或吊销 Token 后立即失效,不依赖员工会话。
  • 禁止把 Token 写入浏览器、NEXT_PUBLIC_*、日志、Git 或 Manifest。

服务端权限检查:

import { IWishAuthClient } from "@iwish/auth-sdk";

const auth = new IWishAuthClient({
  apiUrl: process.env.IWISH_AUTH_API_URL!,
  token: process.env.IWISH_AUTH_SERVICE_TOKEN!
});

const decision = await auth.checkUserPermission({
  userId,
  organizationId,
  appKey: "crm",
  permission: "crm.contact.read"
});

Python 使用 check_user_permission(...),字段语义相同。

2. Webhook 请求

创建或轮换 endpoint 时,管理后台只显示一次 whsec_ 开头的签名密钥;接收方必须立即保存到服务端 Secret 管理中。

请求头:

IWish-Event-Id: <uuid>
IWish-Event-Type: permission.changed
IWish-Delivery-Id: <uuid>
IWish-Delivery-Attempt: 1
IWish-Timestamp: <unix-seconds>
IWish-Signature: v1=<hex-hmac-sha256>

签名原文必须使用未解析、未重新序列化的原始请求体:

<timestamp>.<eventId>.<rawBody>

TypeScript 验签:

import { verifyIWishWebhook } from "@iwish/auth-sdk/webhook";

const rawBody = await request.text();
const event = await verifyIWishWebhook({
  secret: process.env.IWISH_AUTH_WEBHOOK_SECRET!,
  rawBody,
  headers: request.headers
});

Python 验签:

from iwish_auth import verify_iwish_webhook

event = verify_iwish_webhook(
    secret=webhook_secret,
    raw_body=await request.body(),
    headers=request.headers,
)

SDK 默认拒绝超过 300 秒的时间戳、签名不匹配、事件 ID 不一致和无效 Envelope。

3. 幂等与缓存失效

接收方必须持久化 IWish-Event-Id,重复事件直接返回 2xx。不要按 Delivery ID 幂等,因为同一个 Event 可能重试多次。

Envelope 的 cacheInvalidation 包含:

  • userIds
  • organizationIds
  • appKeys
  • clientProjectIds

业务 App 收到 user.disableduser.role_changedpermission.changedorganization.app_disabledemployee.disabled 或客户项目团队变更时,应清理与上述维度相交的权限和上下文缓存。业务 App 是否消费客户项目数据仍由自身业务决定。

4. 投递策略

投递状态依次使用 pendingprocessingdeliveredfaileddead_letter,便于业务 App 和运维工具统一识别。

  • 成功:HTTP 2xx。
  • 自动重试:1 分钟、5 分钟、30 分钟、2 小时,最多 5 次。
  • HTTP 410:立即进入死信并停用 endpoint。
  • 其他失败:耗尽次数后进入死信,可在管理后台人工重试。
  • 接收方应在 10 秒内返回;耗时业务先入本地队列再返回 2xx。

5. 安全边界

  • 生产 endpoint 只接受公网 HTTPS URL。
  • 密钥轮换后旧版本立即失效。
  • 不记录 Authorization、Token、签名密钥或完整敏感 payload。
  • CORS 使用精确 allowlist;基于 Cookie 的状态变更请求不属于 IWish Auth API 协议。
  • 受保护写接口使用 Cloudflare Rate Limiting binding。