Repository navigation
Rate limit the delivery API and check the read performance target - #2598
Merged
Merged
Conversation
# Conflicts: # docs/api/delivery.md # src/FluentCMS.Api/DeliveryEndpoints.cs # src/FluentCMS.Core/Delivery/IPublishedContent.cs # src/FluentCMS.Infrastructure/Delivery/PublishedContentReader.cs # tests/FluentCMS.IntegrationTests/Delivery/DeliveryEndpointsTests.cs # tests/FluentCMS.IntegrationTests/Delivery/PublishedContentTests.cs
… reviewed read endpoints
# Conflicts: # CONTRIBUTING.md # src/FluentCMS.Api/DeliveryEndpoints.cs # src/FluentCMS.Core/Delivery/IPublishedContent.cs # tests/FluentCMS.IntegrationTests/Delivery/DeliveryEndpointsTests.cs
# Conflicts: # src/FluentCMS.Infrastructure/Delivery/PublishedContentReader.cs
# Conflicts: # CONTRIBUTING.md # docs/api/delivery.md
# Conflicts: # src/FluentCMS.Infrastructure/Persistence/FluentCmsDbContext.cs
# Conflicts: # src/FluentCMS.Infrastructure/Persistence/FluentCmsDbContext.cs
# Conflicts: # docs/api/delivery.md # src/FluentCMS.Api/DeliveryEndpoints.cs # src/FluentCMS.Infrastructure/Delivery/PublishedContentReader.cs
# Conflicts: # CONTRIBUTING.md # docs/api/delivery.md
# Conflicts: # CONTRIBUTING.md
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.
Closes #2583
What
The last F-API (#2425) slice, on the delivery endpoints of #2563, #2571 and #2577: rate limits, input validation and the read performance target (SEC-07, PERF-03).
FluentCMS.Api):DeliveryRateLimitis a fixed-window policy per client address. It covers every delivery endpoint and/llms.txt.Delivery__RateLimit__PermitLimit(600 by default) perDelivery__RateLimit__Window(one minute by default). A limit below 1, or a window that isn't positive, stops the host at startup.Retry-Afterand the coderate_limited. The sign-in forms keep their own policy and their plain-text answer.AddFluentCmsApinow takes the configuration and registers the policy and its options. The host passes the configuration in.FluentCMS.Host):ReverseProxy__KnownProxies__0andReverseProxy__KnownNetworks__0list the proxies whoseX-Forwarded-Fornames the client, before the rate limiters run. This covers the sign-in limit too.nosniffand content security policy headers are now tested on delivery responses.IPublishedContent, after 10 warm-up reads, and asserts the p95 is under 100 ms on SQLite and on PostgreSQL. No new index is needed: reads use the entry primary key, versions by entry and version, and references by entry and version.docs/api/delivery.mdhas a Limits section, and its error table hasrate_limited.Why
SEC-07 asks for rate limits and input validation on the delivery API. The API is anonymous, so a per-address limit is what keeps one client from exhausting the host. PERF-03 sets the bar for a single resolved entry, and the test keeps it measured on both providers, so a regression shows up in CI.
Choices worth a look:
Tests
Retry-Afterandrate_limited./llms.txtshares the limit, and/healthstays reachable.X-Forwarded-Foreach get their own limit. Without a trusted proxy, the header is ignored and the fourth request is refused.Product-Page,product_pageanda bas a type are 404 problems that carrynosniffand the content security policy.The full suite ran locally against a
postgres:17container as well as SQLite, and markdownlint is clean. There is no migration and no new package.Review
An independent review blocked this PR. Behind a reverse proxy, every client shared the proxy's address. Honouring
X-Forwarded-Forfrom anyone would have let a client pick a fresh bucket. Both are fixed with trusted proxies from configuration. Its other findings are fixed too:A second review gave MERGE. Its Low finding is fixed in the docs, which now say that one forwarded hop is read and how to set up a proxy chain. The sign-in limit's IPv6 grouping, which was already there before this PR, is tracked in #2640.
Checklist
v2