Repository navigation
docs: describe the built-in inbound rate limiter, server.security.rateLimit and server.trustProxy - #25328
Merged
Conversation
…eLimit and server.trustProxy HARDENING.md, production-readiness.mdx and the wire-format callout still described rate limiting as an adapter-wired primitive that is not wired by default, keyed the Hono recipe on X-Forwarded-For unconditionally, and never named the two keys an operator sets. Rewrite them to what the runtime does: the limiter is built in and off until server.security.rateLimit.enabled, keyed principal-first with the caller address as fallback, forwarded headers believed only under server.trustProxy, counters in the kernel cache service (in-memory per process under objectstack serve, so multi-node needs a shared cache). The adapter recipe survives only as a per-class layer keyed through resolveRateLimitKey. Fixes #24740 Claude-Session: https://claude.ai/code/session_01XyLjAesp3Fkx794wqMb4hK Co-authored-by: Claude <noreply@anthropic.com>
This was referenced Oct 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Elon · project thread
Fixes #24740
Clause-②: no
Metadata-protocol: none
What changed
docs/HARDENING.md,content/docs/deployment/production-readiness.mdxand the rate-limit callout incontent/docs/api/wire-format.mdxdescribed rate limiting as a primitive the runtime does not wire, to be added at the adapter layer, and never named the two keys an operator actually sets. Since the inbound limiter landed that is false. The three pages now say what the runtime does, each claim read againstorigin/mainat9dc1f42d5:packages/runtime/src/security/inbound-rate-limit.ts:89,packages/runtime/src/dispatcher-plugin.ts:917-922,packages/spec/src/shared/http.zod.ts:221server.security.rateLimit(enabled,windowMs,maxRequests), forwarded byobjectstack servepackages/spec/src/stack.zod.ts:906,packages/spec/src/system/stack-server.zod.ts:148,packages/cli/src/commands/serve.ts:4785-4787packages/spec/src/shared/http.zod.ts:226,231,inbound-rate-limit.ts:91-92maxRequests, refillmaxRequests / (windowMs / 1000)per secondinbound-rate-limit.ts:108-111http.server;OPTIONSnever metered; warns when nohttp.serverdispatcher-plugin.ts:906-942,inbound-rate-limit.ts:259,289Retry-After(seconds) +RATE_LIMIT_EXCEEDED; noX-RateLimit-*header anywhereinbound-rate-limit.ts:342-352, pinned ininbound-rate-limit.test.ts:212-234;git grep -i X-RateLimit -- 'packages/**/*.ts' ':!**/*.test.ts'= 0 hitsdefineStack; unknown keys (keyBy,store) refusedstack-server.zod.ts:101-118,http.zod.ts:194-214Inbound rate limit armedwith budget andtrustProxydispatcher-plugin.ts:924-931inbound-rate-limit.ts:149-163,313-323server.trustProxythe leftmostX-Forwarded-For, thenX-Real-IP, else the peerpackages/plugins/plugin-auth/src/client-address.ts:69-88,client-address-forwarding.ts:24server.trustProxydefaultsfalse; the same value drives the auth allow-list,last_login_ipand per-endpoint budgetsstack-server.zod.ts:203-231,serve.ts:4273cacheservice, resolved at consume time; per-process fallback warned onceinbound-rate-limit.ts:194-226,275-283,packages/plugins/plugin-auth/src/rate-limit-storage.ts:194-225objectstack servecacheis always on and in-memory (per process);adapter: 'redis'refuses to startpackages/spec/src/kernel/platform-capabilities.ts:351,packages/core/src/capability-providers.ts:84-88,packages/services/service-cache/src/cache-service-plugin.ts:80-89inbound-rate-limit.ts:204-208stack-server.zod.ts:54-58DEFAULT_RATE_LIMITSis reference material nothing readspackages/runtime/src/security/rate-limit.ts:229-247The old Hono recipe (keyed on
X-Forwarded-Forunconditionally) and the RedisRateLimitStoreparagraph are gone. A compact recipe survives under Per-class budgets, the one thing the built-in single bucket does not do, keyed throughresolveRateLimitKeyso its trust rule is the runtime's. TheHARDENING.mdTL;DR row keeps "Off (opt-in)" (accurate: off by default) and now points atserver.security.rateLimit; the audit checklist line and the go-live checklist now name the built-in keys.The CORS half of
HARDENING.mdis untouched (another card).Gates
Derived with
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackat4a59f49: 41 commands, all exit 0;--ranreconciliation 41 derived, 41 run, 0 NOT-MEASURED, 0 UNRUN. Docs only, nothing published from any package:skip-changeset.Acceptance notes
content/docs/api/wire-format.mdxwas a third page repeating the same stale claim (and promisingX-RateLimit-*headers the runtime never sends); named to the seat before editing, which agreed.packages/plugins/plugin-auth/src/rate-limit-storage.ts:219-221prescribes "Redis via @objectstack/service-cache", whichcache-service-plugin.ts:80-86refuses to start. Reported to the seat.Generated by Claude Code