feat: share rate-limit counters across API instances

未关闭
#581 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
5/5
预计耗时
一周以上
新手友好度
35/100
Issue 类型
功能
描述清晰度
基本清楚
活跃度
活跃
技术栈
express, postgresql, typescript

调研方向

Start with docs/production-operations.md and inspect the account notice limiters, flow_rate_limits, and the global per-IP limiter to understand how counters are stored and applied. The issue leaves the store, limiter scope, and failure behavior open, so first map those choices into a design note or ADR. Done means the design is recorded, limits are verified across multiple instances by a test, and the operations documentation is updated.

由索引模型根据 Issue 内容生成。

描述

P2 secure v1.0

Why

Every rate limiter and slow-down in the API uses the in-memory store of express-rate-limit or express-slow-down. Each instance counts on its own, so with N instances behind a load balancer a client whose requests spread across them gets up to N times each budget. docs/production-operations.md ("Running More Than One Instance") documents this and the workaround: route by client address, or limit at the proxy as well.

Routing by address does not help the account notice limits on POST /applications/account-notices, because they are keyed by application and user. An application can send up to N times its notice allowance however requests are routed.

The counters that bound guessing are already shared in Postgres (auth_failures, OTP codes, magic links, WebAuthn challenges, refresh rotation, the OAuth state record), so the gap is volume (OTP and magic link sends, notice spam, load), not account takeover. Split from #553, whose per-user key fix shipped in #567.

What

Decide and build a shared store for the limiters where per-instance counting matters:

  • Which limiters share. The account notice limiters and flow_rate_limits first. Whether the global per-IP limit and slow-down need it, or stay in memory to keep the hot path free of a database write.
  • Which store. Postgres needs no new service, since every deployment has it already. A Redis or Valkey store could be an option for large deployments, never a requirement.
  • Failure mode when the store is unreachable: fail open, fail closed, or fall back to memory, per limiter.
  • Window and cleanup for expired counters.

Related

The global per-IP limit counts the provider edge's /oidc/* calls against the browser's address. Look at it in the same design.

Done when

  • A design note or ADR records which limiters share, the store, and the failure mode
  • Shared limits hold across two or more instances, covered by a test that runs more than one
  • docs/production-operations.md is updated
主要语言
TypeScript
星标
2
派生
2
平均合并
12 小时 23 分钟
30 天内合并 PR
109

环境准备

  • 提供 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

fells-code/seamless-auth-api 的其他 Issue

查看 fells-code/seamless-auth-api 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。