Bug Summary
The public API rate limiter in apps/public-api/src/middlewares/api_usage.js is configured with:
const limiter = rateLimit({
windowMs: 15 * 60 * 1000,
max: 100,
validate: {
xForwardedForHeader: false,
trustProxy: false
}
});
Setting validate.trustProxy: false suppresses the express-rate-limit warning about proxy trust but does NOT configure Express to trust X-Forwarded-For headers. When the public API server is deployed behind a load balancer or reverse proxy (which is the case on Render, as indicated by render.yaml), all incoming requests arrive at the Node.js process with the same internal load-balancer IP as req.socket.remoteAddress.
Because app.set('trust proxy', 1) is absent from the public API Express setup, express-rate-limit keys every request on the same internal IP. The effect is that all SDK users on the platform share a single rate-limit counter: once any combination of users makes 100 requests in 15 minutes, every other user is throttled as well. Conversely, a single abusive client can exhaust the shared bucket for all users by making 100 rapid requests.
The dashboard API correctly sets app.set('trust proxy', 1) (line 17 of apps/dashboard-api/src/app.js), but the public API does not.
Steps to Reproduce
- Deploy the public API behind a load balancer.
- Send 101 requests from two different client IPs.
- Observe that the 101st request from Client B is rate-limited even though Client B has only made 1 request.
Expected Behavior
The public API should set app.set('trust proxy', 1) to correctly extract the real client IP from the X-Forwarded-For header, so each client is rate-limited independently.
Affected Files
apps/public-api/src/app.js: missing app.set('trust proxy', 1)
apps/public-api/src/middlewares/api_usage.js: validate.trustProxy: false suppresses the warning without fixing the root issue
@geturbackend I would like to work on this issue. Could you please assign/ it to me? Contributing under NSoC '26.
Bug Summary
The public API rate limiter in
apps/public-api/src/middlewares/api_usage.jsis configured with:Setting
validate.trustProxy: falsesuppresses theexpress-rate-limitwarning about proxy trust but does NOT configure Express to trustX-Forwarded-Forheaders. When the public API server is deployed behind a load balancer or reverse proxy (which is the case on Render, as indicated byrender.yaml), all incoming requests arrive at the Node.js process with the same internal load-balancer IP asreq.socket.remoteAddress.Because
app.set('trust proxy', 1)is absent from the public API Express setup,express-rate-limitkeys every request on the same internal IP. The effect is that all SDK users on the platform share a single rate-limit counter: once any combination of users makes 100 requests in 15 minutes, every other user is throttled as well. Conversely, a single abusive client can exhaust the shared bucket for all users by making 100 rapid requests.The dashboard API correctly sets
app.set('trust proxy', 1)(line 17 ofapps/dashboard-api/src/app.js), but the public API does not.Steps to Reproduce
Expected Behavior
The public API should set
app.set('trust proxy', 1)to correctly extract the real client IP from theX-Forwarded-Forheader, so each client is rate-limited independently.Affected Files
apps/public-api/src/app.js: missingapp.set('trust proxy', 1)apps/public-api/src/middlewares/api_usage.js:validate.trustProxy: falsesuppresses the warning without fixing the root issue@geturbackend I would like to work on this issue. Could you please assign/ it to me? Contributing under NSoC '26.