Repository navigation
docs: HARDENING.md and production-readiness.mdx still describe rate limiting as adapter-wired and off, and never name server.security.rateLimit or trustProxy #24740
Description
Filing gate ③ a task the maintainer set, in the repo:hotcrm seat 2 chat on 2026-10-20 (verbatim): 「docs/HARDENING.md 里的限流配方引用了已经不存在的代码」. Filed by the repo:hotcrm seat 2 (os-support-ai, session session_01KqkTQNLcxVc588eZpJmp1r, seat post objectstack-ai/hotcrm#2180). ⛔ Not a claim. Domain, type and grade are triage's.
A correction to the order's wording, on measurement: the symbols the recipe imports still exist. RateLimiter and DEFAULT_RATE_LIMITS are in packages/runtime/src/security/rate-limit.ts, exported from @objectstack/runtime. What is false is what the two pages say about the runtime, since #4910 wired the built-in limiter. The seat reported this correction to the maintainer when filing.
Reader (who acts): objectstack triage routes it to the owner of docs/ and content/docs/deployment/. It is the docs follow-up #4937 did not reach.
What is false (read on objectstack main 9b2953d62)
docs/HARDENING.md § Rate limiting:
- "The runtime exposes a token-bucket primitive but does not auto-wire it into the dispatcher plugin … the decision to enable belongs at the adapter layer." False since 「v17」入站 rateLimit 接执行:ApiEndpoint / HttpServer 的 RateLimitConfig 推导为 runtime token bucket 配置,dispatcher 生效(#4686 拆向之一) #4910.
createDispatcherPlugin({ rateLimit })installs the inbound limiter as global middleware from the authoredserver.security.rateLimitblock, andobjectstack serveforwards it.rate-limit.ts's own header andpackages/runtime/src/index.ts("The dispatcher plugin wires BOTH automatically") say so. - § Trust the proxy or don't: "The dispatcher's default key extractor reads
x-forwarded-for[0]". False.resolveRateLimitKey(inbound-rate-limit.ts) keys on the principal first. It reads forwarded headers only underserver.trustProxy, and otherwise uses the transport peer. - The Hono recipe keys its buckets on
x-forwarded-for's first entry, unconditionally. That is the client-influenced key the runtime's own resolver refuses withouttrustProxy. A reader who copies it gets a weaker limiter than the one the runtime already ships. - "For multi-instance deploys, replace the default
MemoryStorewith a Redis-backedRateLimitStore." The built-in limiter already counts in the kernelcacheservice (shared when that is Redis), and warns when it falls back to per-process. - The page never names
server.security.rateLimitortrustProxy, the two keys an operator actually sets. They are documented only incontent/docs/references/system/stack-server.mdx.
content/docs/deployment/production-readiness.mdx (published):
- The defaults table says rate limiting is "Off (opt-in via adapter)".
- The prose says "Rate limiting is the one piece you wire at the adapter layer … See the HARDENING.md recipes".
- The go-live checklist says "Rate limit configured at the adapter for
/auth/*…".
All three send a reader past the built-in limiter. The published page matters more, because it ships to every operator.
The same HARDENING.md's CORS section ("not opinionated by the runtime") is carried by the CORS card filed alongside this one, not here.
Expected (proposed; triage owns it)
- Both pages say that rate limiting is built in and off by default. They name
server.security.rateLimitwith an example budget,server.trustProxywith when to set it, and the shared-cache requirement for multi-node. - The adapter recipe is either deleted or kept only as "per-class budgets, which the built-in single bucket does not do", using the runtime's trust rule for its key.
- The go-live checklist points at the built-in key.
Dedupe (objectstack issues, all states, semantic search)
"HARDENING.md rate limiting recipe stale adapter layer server.security.rateLimit production-readiness docs": 3 hits, all closed.
packages/runtime/src/security/rate-limit.ts零调用点,且注释断言了两个不存在的东西(429 短路 /DispatcherPluginConfig.rateLimit) #4937 fixedrate-limit.ts's comments.- ADR-0049:spec 两份 RateLimitConfig 全仓零 reader,真正在限流的是 runtime 自己的第三份形状 #4686 was the ADR-0049
RateLimitConfigretirement. - SYNC_ARCHITECTURE.md 的 L3 段仍在三处宣传 Rate Limiting,而 connector.rateLimitConfig 及其整个形状已在 #4911 退役 #5554 fixed
SYNC_ARCHITECTURE.md's L3 claims.
None covers these two pages.
Dedupe words: HARDENING.md rate limiting stale; production-readiness rate limit adapter; server.security.rateLimit docs; x-forwarded-for recipe.
Generated by Claude Code
Activity