一个请求进来,怎样确认调用者是谁、能做什么,以及不能看谁的数据?

鉴权与多租户:API Key、权限范围与数据授权合规

约 14 分钟6 道自测更新于 2026-11-01

一句话记住鉴权要分清认证、授权和对象隔离;数据能被技术访问,不等于可以按任意用途转发或再分发。

01学完你能做到

  • 区分认证、授权、权限范围和数据授权。
  • 设计 API Key 的哈希存储、轮换、吊销和审计日志。
  • 识别对象级授权失效和多租户串数据风险。
  • 用最小权限、最小必要和授权范围思路设计数据服务。

02这课解决什么问题

数据服务面对多个客户时,如何确认调用者是谁、允许调用哪些接口、可以访问哪些数据,并保证一个租户不能读到另一个租户的对象?

03认证、授权与对象隔离

认证(authentication)回答“你是谁”。请求没有有效凭证或凭证已失效,通常返回 401。

授权(authorization)回答“你能做什么”。调用者已经通过认证,但没有对应权限,通常返回 403。

对象级授权继续回答“你要访问的这个对象属于你吗”。即使 API Key 和权限范围都正确,也必须检查对象的租户归属。为了不暴露其他租户对象是否存在,某些系统会对越权对象返回 404;具体错误合同应保持一致并写入文档。

多租户系统还需要在数据访问层统一带上 tenant_id 过滤,或使用数据库的行级安全策略。不能只依赖开发者“记得在每个接口加一个 WHERE 条件”,还要用自动化测试验证 A 租户无法读取 B 租户的数据。

04API Key 是持有者凭证

API Key 可以理解为持有者凭证:谁拿到它,谁就可能以对应身份调用服务。因此应把它当作秘密处理,而不是普通的用户编号。

一套基本的生命周期包括:

  1. 生成足够随机的 Key,并使用可识别但不泄露秘密的前缀,方便扫描和审计。
  2. 明文只在创建时展示一次;服务端保存不可逆的哈希或带服务端密钥的哈希。
  3. 支持轮换:先创建新 Key,切换调用方后再吊销旧 Key,避免为了换密钥而停服。
  4. 支持按用途、环境或 Agent 分开创建 Key,减少单个 Key 泄露时的影响范围。
  5. 审计日志只记录 Key 前缀、租户、工具、对象、时间和结果,不记录完整 Key。

高熵随机 API Key 可以使用适合秘密凭证的哈希方案;用户密码则应使用专门的慢哈希方案。密钥管理服务、环境变量和访问控制比把 Key 写进代码、截图或聊天记录更合适。

05Scope 与数据授权

scope 描述一把 Key 能执行哪类操作,例如 market:read、finance:read。最小权限原则要求只授予当前任务所需的 scope。

数据授权(entitlement) 描述调用者能访问哪些数据集、时间范围、频率或使用场景,例如日终行情与实时行情分开授权。scope 管“能做哪类操作”,entitlement 管“能看哪份数据”,两者都要检查。

数据授权还可能来自上游许可、合同和展示范围。一个 API 能返回某份数据,不代表调用者可以将它再发布给自己的用户。对外展示、转发、再分发和用于产品化的权限,需要回到上游许可和合同确认。

06数据合规的通用原则

数据服务至少要区分两类授权问题:

  • 数据来源授权:上游数据提供方是否允许采集、存储、调用、展示、转发或再分发,以及允许的终端范围和用途。
  • 用户数据保护:账号、调用日志、自选股、组织信息等是否包含个人信息或其他受保护数据,收集和保存是否有明确目的和必要性。

《中华人民共和国数据安全法》确立了数据分类分级保护和全流程安全管理等要求。工程上可以落实为:识别数据类别,控制访问范围,记录处理活动,进行风险监测,发现漏洞及时补救,发生事件按适用要求处置和报告。

《中华人民共和国个人信息保护法》要求个人信息处理具有合法、正当、必要目的,收集范围应限于实现处理目的所需的最小范围,保存期限应为实现目的所必要的最短时间。课程中的审计日志、租户信息和自选股数据,也应评估是否涉及个人信息,并据此设计访问、脱敏、留存和删除策略。

这些是通用工程原则,不替代针对具体业务、数据类型和跨境场景的法律意见。涉及交易所或其他上游数据的商业许可时,还要单独核对许可文本和合同,不要仅凭“公开可查”判断可以再分发。

07在金融数据链路中的位置

客户 / Agent
     │ API Key
     ▼
网关或 MCP 服务
     ├─ 认证:Key 是否有效、是否吊销
     ├─ scope:是否允许这类操作
     ├─ entitlement:是否包含这份数据
     ├─ 对象归属:是否属于当前租户
     ├─ 限流与计量
     ▼
数据访问层:强制 tenant_id 过滤
     ▼
返回结果 + 脱敏审计日志

鉴权应发生在业务逻辑之前,但不能只在网关做一次。数据访问层仍要强制做租户过滤,尤其是内部服务之间调用时。审计日志要能回答“谁、何时、调用了什么、访问了哪个数据集、结果如何”,同时避免生成新的密钥泄露源。

08一个最小模型

PEPPER = secrets.token_bytes(32)  # 生产环境由密钥管理服务托管

def hash_key(raw):
    return hmac.new(PEPPER, raw.encode(), hashlib.sha256).hexdigest()

def handle(raw_key, tool, object_id=None):
    meta = KEY_STORE.get(hash_key(raw_key)) if raw_key else None
    if meta is None or meta["revoked"]:
        return 401
    if REQUIRED_SCOPE[tool] not in meta["scopes"]:
        return 403
    if REQUIRED_DATASET[tool] not in meta["datasets"]:
        return 403
    if object_id and OBJECTS[object_id]["tenant_id"] != meta["tenant_id"]:
        return 404
    return 200

这只是教学模型。生产系统还需要处理并发、密钥轮换、密钥管理服务故障、缓存失效、权限变更传播和审计数据留存等问题。

09常见误区

  1. 把认证当成授权:有有效 Key 只说明调用者被识别,不说明它能访问所有接口和数据。
  2. 数据库明文存 Key:数据库泄露后会直接暴露全部凭证,应保存安全的哈希并支持轮换。
  3. 只做接口级权限,不做对象级权限:修改一个对象 ID 就能读到别人的数据,是常见的 API 安全风险。
  4. 所有用途共用一把 Key:按生产、测试、Agent 或数据集拆分 Key,便于最小授权和单独吊销。
  5. 把数据授权当成技术权限:技术上能调用,不代表合同允许展示、转发或再分发。
  6. 只在应用代码里过滤租户:应在统一数据访问层或数据库安全策略中强制隔离,并测试跨租户访问。
  7. 无限保存调用日志:日志可能含有个人信息或敏感业务信息,应设定必要字段、访问权限和保存期限。

10延伸阅读

11一分钟讲给别人

试着用自己的话讲一遍API 安全不是只有登录。先用 Key 认证“你是谁”,再用 scope 判断“你能做什么”,再检查数据授权和对象归属,防止租户之间串数据。Key 只展示一次、服务端存哈希、能轮换和吊销。金融数据还有合同边界:技术上能返回,不代表就能对外转发。

想一想

6 道自测

先在心里答一遍,再展开对照。能说清理由,比答对数字更重要。

  1. 01401 和 403 通常分别表示什么?

  2. 02为什么 API Key 不应以明文保存?

  3. 03scope 与数据授权有什么区别?

  4. 04什么是对象级授权失效?

  5. 05数据服务为什么要同时考虑来源授权和用户数据保护?

  6. 06多租户隔离为什么不能只靠每个接口手写过滤条件?

已看 0/6 题

练动手练习

任务:为一个“Agent 专用 Key”设计权限:只允许读取日终行情,不允许读取实时行情、财务数据或其他租户的自选股。列出 Key 存储、权限检查、对象过滤、日志字段和吊销流程,并写出至少两条跨租户访问测试。

完成这一课

完成这一课

读完讲义、看完自测答案,这一课就算学完了。

  • 读完讲义
  • 看完全部自测

本课为投资者教育内容,案例数字均为示意,不构成任何投资建议,也不承诺收益。规则和费率会变,实际操作前请以交易所、监管机构和产品的最新公告为准。