Skip to content

feat(sms): 短信全局/每租户日发送配额(成本总量闸) #2814

Description

@os-zhuang

背景

#2780(PR #2790/#2797)为 OTP 端点落了按号码维度的防滥用:60s 冷却 + 每号码 5 条/小时(hooks.before 准入层,集群经 secondaryStorage 共享),外加 per-IP 限流。但 SMS pumping 的总量维度仍然缺失:攻击者轮换大量不同号码时,每个号码都在自己的预算内,日累计成本没有上限;notify(channels:['sms']) 走 messaging channel 的发送也完全不经过任何配额。

诉求

  1. 全局日配额sms 设置命名空间新增 daily_quota(0 = 不限),对经过 services.sms.send所有发送计数(OTP、邀请、notify channel 统一在 service 层扣减,而不是只挡 auth 端点)。
  2. 每租户日配额(多租户部署):daily_quota_per_tenant,按 organizationId 维度计数。
  3. 超限行为
    • OTP/邀请路径 → 与按号码冷却一致的 429 TOO_MANY_REQUESTS(不泄露配额剩余细节);
    • messaging channel → SendResult.ok=false + classifyError='rate_limited'(进 outbox 重试/死信,不静默丢)。
  4. 计数存储:单节点内存、集群复用 cache/secondaryStorage(对齐 otp-send-guard 的降级策略:存储故障 fail-open + 告警日志,配额闸不能把登录拖下水)。
  5. 可观测:接近阈值(如 80%)打 WARN,超限打 WARN(含当日计数,绝不含正文)。

相关

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions