Skip to content

Commit 1379d30

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/issue-25104-docs-viewer-script
2 parents b55b8f7 + edcc8ce commit 1379d30

3 files changed

Lines changed: 23 additions & 9 deletions

File tree

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@objectstack/spec': patch
3+
---
4+
5+
docs(spec): `server.trustProxy`'s description names all three consumers of the client-address rule
6+
7+
Clause-②: no (prose only: no shape, key, default or accepted value moves)
8+
9+
The `.describe()` on `server.trustProxy` said the client-address rule had two consumers: the inbound rate limiter and the authentication plugin. There is a third. A declared endpoint (`apis:`) whose own `rateLimit` is enabled is metered by the endpoint policy chain, which keys anonymous callers by the same rule under the same `trustProxy`, whether or not `server.security.rateLimit.enabled` is set. The description and the TSDoc now name it. No key, type, default or accepted value changes.

‎content/docs/references/system/stack-server.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ const result = ServerRateLimitConfigSchema.parse(data);
101101
| Property | Type | Required | Description |
102102
| :--- | :--- | :--- | :--- |
103103
| **security** | `{ rateLimit?: object }` | optional | Server-level security configuration. Today: the global inbound rate limit. |
104-
| **trustProxy** | `boolean` | optional (default: `false`) | Believe `X-Forwarded-For` / `X-Real-IP` when identifying a caller. Declare `true` ONLY when a reverse proxy you control overwrites those headers on every inbound request. Left `false` (the default) the caller IP is the transport's own peer address, which a client cannot forge. One client-address rule, two consumers: the inbound rate limiter when `server.security.rateLimit.enabled` is set, and the authentication plugin, whose IP allow-list (`allowed_ip_ranges`) judges and whose login audit stamps (`last_login_ip`) the same address. |
104+
| **trustProxy** | `boolean` | optional (default: `false`) | Believe `X-Forwarded-For` / `X-Real-IP` when identifying a caller. Declare `true` ONLY when a reverse proxy you control overwrites those headers on every inbound request. Left `false` (the default) the caller IP is the transport's own peer address, which a client cannot forge. One client-address rule, three consumers: the inbound rate limiter when `server.security.rateLimit.enabled` is set; the per-endpoint rate limiter of every declared endpoint (`apis:`) whose own `rateLimit` is enabled, whether or not the server-level one is; and the authentication plugin, whose IP allow-list (`allowed_ip_ranges`) judges and whose login audit stamps (`last_login_ip`) the same address. |
105105

106106
### Nested Shape: `StackServerConfig.security`
107107

‎packages/spec/src/system/stack-server.zod.ts‎

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -210,19 +210,24 @@ export const StackServerConfigSchema = lazySchema(() => strictObject(
210210
* of authorship — the operator asserting "a proxy I control rewrites this
211211
* header on every request" — and never a default.
212212
*
213-
* Both consumers apply one rule, `resolveClientAddress` from
213+
* Three consumers apply one rule, `resolveClientAddress` from
214214
* `@objectstack/plugin-auth/client-address`: the runtime's inbound rate
215-
* limiter, and `AuthPlugin` (passed this value by `objectstack serve`),
216-
* whose ADR-0069 D5 IP allow-list and D7 `last_login_ip` audit use the
217-
* address it establishes — so a header believed without such a proxy is
218-
* an allow-list bypass as well as a rate-limit one.
215+
* limiter; the endpoint policy chain's per-endpoint rate limiter, for
216+
* every declared endpoint whose own `rateLimit` is enabled, whether or not
217+
* the server-level budget is; and `AuthPlugin` (passed this value by
218+
* `objectstack serve`), whose ADR-0069 D5 IP allow-list and D7
219+
* `last_login_ip` audit use the address it establishes — so a header
220+
* believed without such a proxy is an allow-list bypass as well as a
221+
* rate-limit one.
219222
*/
220223
trustProxy: z.boolean().default(false).describe(
221224
'Believe `X-Forwarded-For` / `X-Real-IP` when identifying a caller. Declare `true` ONLY when a reverse proxy '
222225
+ 'you control overwrites those headers on every inbound request. Left `false` (the default) the caller IP is '
223-
+ "the transport's own peer address, which a client cannot forge. One client-address rule, two consumers: the "
224-
+ 'inbound rate limiter when `server.security.rateLimit.enabled` is set, and the authentication plugin, whose IP '
225-
+ 'allow-list (`allowed_ip_ranges`) judges and whose login audit stamps (`last_login_ip`) the same address.',
226+
+ "the transport's own peer address, which a client cannot forge. One client-address rule, three consumers: the "
227+
+ 'inbound rate limiter when `server.security.rateLimit.enabled` is set; the per-endpoint rate limiter of every '
228+
+ 'declared endpoint (`apis:`) whose own `rateLimit` is enabled, whether or not the server-level one is; and the '
229+
+ 'authentication plugin, whose IP allow-list (`allowed_ip_ranges`) judges and whose login audit stamps '
230+
+ '(`last_login_ip`) the same address.',
226231
),
227232
},
228233
));

0 commit comments

Comments
 (0)