谁能访问什么

访问控制与安全边界

展开 API Key、来源网络、权限范围、重放防护和日志保护,明确默认拒绝的授权规则。

展开 API Key、来源网络、权限范围、重放防护和日志保护,明确默认拒绝的授权规则。

5. 身份、API Key 与授权模型

5.1 API Key 凭据格式

客户端通过 Authorization 请求头传递凭据,认证方案名为 ApiKey。凭据由公开 Key ID 和 256 位随机 Secret 组成。公开 Key ID 用于定位记录,Secret 用于证明持有权。

安全要求:

  1. Secret 使用密码学安全随机源生成,熵不少于 256 位。
  2. Secret 只在创建或轮换成功响应中展示一次。
  3. 服务端不保存明文 Secret;使用 KMS 保护的 Pepper 对 Secret 计算 HMAC-SHA-256 摘要,并把 pepper_version 与摘要一起保存。
  4. 摘要比较必须使用常量时间算法。
  5. 网关、WAF、APM 和应用日志必须统一脱敏 Authorization 请求头。
  6. 生产与非生产环境使用不同 Key;请求入口、Key、路由和后端端点必须属于同一环境,任何跨环境组合都拒绝。
  7. Pepper 轮换只用于新签发的 Secret 版本;旧 Pepper 在对应 Secret 版本全部失效前保持只读可用,禁止轮换时重新计算或批量作废存量摘要。

5.2 权限 Scope

权限采用三个层级的明确标识:平台、资源、操作。首批示例为:

Scope含义
webpay_inbox.payment.read查询 WebPay Inbox 支付信息
webpay_inbox.payment.submit向 WebPay Inbox 提交支付操作
bps.payment.read查询 BPS 支付信息
bps.payment.submit向 BPS 提交支付操作
zero_confirmation.payment.read查询 Zero Confirmation 支付信息
zero_confirmation.payment.submit向 Zero Confirmation 提交支付操作

实际资源和操作清单必须由各平台负责人逐项确认后发布。授权规则如下:

  1. 每条可访问路由必须声明一个明确的 required scope。
  2. API Key 必须拥有该 required scope,不能依赖前缀匹配或隐式通配权限。
  3. 新增路由在没有绑定 required scope 时不得发布。
  4. Scope 变更必须生成新配置版本并记录审计。
  5. 一个 API Key 可以显式拥有多个平台的 Scope。

5.3 API Key 与 IP 绑定

绑定粒度必须是 API Key,不是商户。一个 Key 可以绑定多个明确的 IPv4 地址、IPv6 地址或 CIDR 网段;一个 IP 只有在被显式绑定到某个 Key 后才能与该 Key 配合使用。

以同一商户拥有 Key A、Key B、IP A、IP B 为例,授权矩阵如下:

API Key来源 IP是否存在绑定结果
Key AIP A继续进行 Scope 校验
Key AIP B拒绝
Key BIP A拒绝
Key BIP B继续进行 Scope 校验

具体规则:

  1. 不允许把商户级 IP 列表自动应用到该商户的全部 Key。
  2. 同一个 IP 可以被多个 Key 使用,但每一组绑定都必须单独创建并审计。
  3. IPv4、IPv6 和 CIDR 在写入时必须规范化。默认自助配置只允许 IPv4 /32 和 IPv6 /128;IPv4 /29/31、IPv6 /64/127 必须提供业务原因并通过双人审批;IPv4 小于 /29 或 IPv6 小于 /64 一律拒绝。
  4. 数据面只信任边缘负载均衡传递的客户端 IP;来自公网请求的任意 X-Forwarded-For 值不得直接作为授权依据。
  5. 边缘层必须覆盖客户端自带的转发头,并通过受信网络或 PROXY Protocol 把原始 IP 传给网关。
  6. 无法可靠确定来源 IP 时默认拒绝,不允许退化为只校验 API Key。
  7. 商户使用动态出口 IP 或第三方 NAT 时,必须先完成固定出口或专线方案,不能通过放宽到互联网级 CIDR 解决。
  8. 同一 Key 下禁止保存重复或相互包含的网段;新绑定与现有网段重叠时,控制面必须拒绝并要求先原子替换绑定集合。

5.4 Key 生命周期

API Key 状态包括 pendingactivesuspendedrevokedexpired

  1. 创建:校验商户、环境、Scope 和 IP 绑定后生成 Key,Secret 仅展示一次。
  2. 启用:高权限生产 Key 通过审批后从 pending 进入 active
  3. 轮换:为同一逻辑 Key 创建新 Secret 版本,默认允许新旧版本并行 24 小时,之后旧版本自动失效。
  4. 暂停:用于短期风险处置,可由授权管理员恢复。
  5. 吊销:不可逆,必须在各地域快速传播。
  6. 过期:到达明确的 expires_at 后自动拒绝。

建议生产 Key 最长有效期为 180 天,并在到期前 30 天、14 天、7 天和 1 天通知责任人。该周期属于安全建议,需由安全与商户运营团队确认。

5.5 请求重放防护

静态 API Key 本质上属于 Bearer 凭据。TLS 与 Key 级 IP 绑定可以降低泄露和异地重放风险,但不能阻止在受信出口网络、TLS 终止点或日志链路中窃取凭据后的重放。

首个只读纵向切片可以在安全团队明确接受风险后使用 TLS、API Key 与 IP 绑定。任何 payment.submit 类生产路由在开放前必须满足以下两种方案之一:

  1. 商户使用 mTLS,客户端证书与 API Key 建立显式绑定,并执行证书吊销检查。
  2. 商户使用独立的 Ed25519 私钥对请求方法、规范化路径、请求体 SHA-256、UTC 时间戳、随机 Nonce、Idempotency-Key 和 API Key ID 进行签名;网关保存公钥,允许的时钟偏差为 5 分钟,Nonce 在 10 分钟内不得重复。

请求签名私钥由商户持有,网关不得接收或保存。Nonce 状态保存在允许写入故障转移地域之间的安全缓存中;该状态不可用且后端全局幂等能力未验证时,支付写请求失败关闭。TLS 在 WAF 终止还是透传到网关属于部署决策,但无论选择哪种方式,所有终止点都必须执行凭据日志脱敏并受最小权限控制。

5.6 访问控制中心

访问控制中心是“API Key 验证服务 + API Gateway 权限策略执行”的逻辑并集,不是一个新增的单体服务。验证服务只确认凭据、状态、环境与 Key-IP 绑定,并返回身份和 Scope;网关策略再判定路由可见性与 required scope。认证完成前可以暂存路由匹配结果,但不能据此返回差异响应。

%%{init: {"flowchart": {"curve": "linear", "nodeSpacing": 34, "rankSpacing": 38, "htmlLabels": true}}}%% flowchart TB REQUEST["统一接入层输出<br/>Key ID + Secret · 可信来源 IP<br/>入口环境 · 暂存 route match"] --> PARSE["解析公开 Key ID<br/>格式错误直接进入认证拒绝"] SNAPSHOT["本地域版本化快照<br/>Key · Secret 摘要 · 状态 · 环境<br/>Key-IP · Scope · 路由"] --> LOOKUP["读取记录并合并拒绝项<br/>校验 epoch / sequence 与有效期"] BREAKGLASS["独立 break-glass 通道<br/>已验签的本地域拒绝项"] -.-> LOOKUP subgraph VERIFY["组件 1 · API Key 验证服务"] direction LR PARSE --> LOOKUP LOOKUP --> CREDENTIAL["固定顺序验证<br/>Secret 常量时间比较 → 状态与时效<br/>→ 环境 → Key-IP 绑定"] CREDENTIAL --> AUTH{"身份认证通过?"} end AUTH -->|"否"| DENY401["统一 401<br/>内部记录精确 reason_code"] AUTH -->|"是"| IDENTITY["已验证身份<br/>merchant · key · Scope 集合<br/>配置版本"] subgraph POLICY["组件 2 · API Gateway 权限策略"] direction LR AUTHORIZE["读取暂存 route match<br/>路由可见性 · required scope"] AUTHORIZE --> ALLOWED{"路由存在且 Scope 充分?"} end IDENTITY --> AUTHORIZE ALLOWED -->|"否"| DENY404["统一 404<br/>路由不存在与 Scope 不足同语义"] ALLOWED -->|"是"| OUTPUT["输出到请求治理层<br/>已授权请求 + 可信身份上下文"] classDef input fill:#F4F7FB,stroke:#72849A,color:#253954,stroke-width:1.5px classDef runtime fill:#FFFFFF,stroke:#4F79A7,color:#18212F,stroke-width:1.5px classDef policy fill:#EDF8F3,stroke:#16835E,color:#124D3B,stroke-width:1.5px classDef reject fill:#FFF2EC,stroke:#C7582B,color:#6B2812,stroke-width:1.5px class REQUEST,SNAPSHOT,BREAKGLASS input class PARSE,LOOKUP,CREDENTIAL,AUTH,IDENTITY runtime class AUTHORIZE,ALLOWED,OUTPUT policy class DENY401,DENY404 reject style VERIFY fill:#F8FBFF,stroke:#B8CDEA,stroke-width:2px style POLICY fill:#F5FBF8,stroke:#AAD8C7,stroke-width:2px

本地域快照不是独立授权板块,它由第 10.1 节的发布链路产生,并由验证服务和网关策略在地域内读取。快照过期、版本不可确认或未知 Key 均失败关闭。break-glass 拒绝项与中央配置取并集,只能收缩访问,不能恢复 Key 或扩大 Scope。

11. 安全设计

  1. 外部链路最低使用 TLS 1.2,优先 TLS 1.3;内部服务间使用 mTLS。
  2. KMS 中的 Pepper 和内部签名密钥按环境、地域和用途隔离。Pepper 轮换按第 5.1 节保留旧版本,直到引用该版本的 Secret 全部失效。
  3. 管理员采用短期身份令牌和最小权限角色,不使用商户 API Key 调用管理接口。
  4. Key 创建、Scope 提权、IP 网段扩大、路由发布和跨地域写入开关变更全部审计。
  5. 网关覆盖外部传入的商户身份、权限、来源地域和内部追踪头,避免身份头伪造。
  6. 请求体大小、Header 数量、路径长度、连接数和并发数都有明确上限。
  7. 限流至少包含来源 IP、API Key、商户和平台四个维度,并支持紧急封禁。
  8. 访问日志不记录 Authorization、Cookie、支付卡数据、银行账户信息或完整请求体。
  9. 日志中的来源 IP 按敏感数据治理,限制查询权限并设置保留周期。
  10. 每季度执行 Key 权限复核,每半年执行一次跨地域故障演练和一次 API Key 泄露演练。

建议在详细设计阶段完成 STRIDE 威胁建模,重点覆盖伪造转发头、Key 枚举、Secret 泄露、缓存投毒、配置回滚、重放攻击、跨地域重复写和内部身份头伪造。