Skip to content

feat: add max_req_body_size to bound client request body in forward-auth and ai-proxy#13466

Open
shreemaan-abhishek wants to merge 2 commits into
apache:masterfrom
shreemaan-abhishek:feat/forward-auth-body-size-limit
Open

feat: add max_req_body_size to bound client request body in forward-auth and ai-proxy#13466
shreemaan-abhishek wants to merge 2 commits into
apache:masterfrom
shreemaan-abhishek:feat/forward-auth-body-size-limit

Conversation

@shreemaan-abhishek
Copy link
Copy Markdown
Contributor

@shreemaan-abhishek shreemaan-abhishek commented Jun 3, 2026

Description

Several plugins read the entire client request body into memory with no upper bound, which lets a client force a worker to buffer an arbitrarily large body. The only existing backstop is the global nginx client_max_body_size, which operators routinely raise or disable for upload routes.

This adds a max_req_body_size option (integer, default 67108864 = 64 MiB, minimum 1) to the affected request-body readers, so oversized requests are rejected with 413 before the body is buffered/parsed:

  • forward-auth: caps the POST body forwarded to the authorization service (passed to core.request.get_body()).
  • ai-proxy / ai-proxy-multi: caps the body parsed for LLM proxying, enforced at the top of access().

Docs and e2e tests are included.

⚠️ Default behavior change

These plugins now default max_req_body_size to 64 MiB. The change is observable only when all of the following hold:

  1. the route uses forward-auth with request_method=POST, or ai-proxy / ai-proxy-multi; and
  2. the operator has raised nginx client_max_body_size above 64 MiB (or set it to 0); and
  3. a client sends a request body larger than 64 MiB.

In that case the request is now rejected with 413 instead of being buffered in full. Under the default client_max_body_size (1 MiB) there is no change. The limit is configurable via max_req_body_size to restore prior behavior.

Which issue(s) this PR fixes:

Fixes #

Checklist

  • I have explained the need for this PR and the problem it solves
  • I have explained the changes or the new features added to this PR
  • I have added tests corresponding to this change
  • I have updated the documentation to reflect this change
  • I have verified that this change is backward compatible (see the documented default behavior change above; configurable via max_req_body_size)

When request_method is POST, the plugin reads the entire client request
body into memory to forward it to the authorization service, with no upper
bound. Add a max_req_body_size option (integer, default 1048576, minimum 1)
passed to core.request.get_body() so oversized bodies are rejected with 413
instead of being buffered without limit.
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. enhancement New feature or request labels Jun 3, 2026
@membphis
Copy link
Copy Markdown
Member

membphis commented Jun 3, 2026

P1 blocker: the PR description and documentation need to explicitly document this default behavior change.

This PR adds max_req_body_size with a default of 1048576 (1 MiB). For forward-auth with request_method = "POST", request bodies larger than 1 MiB will now be rejected with 413. However, APISIX currently defaults client_max_body_size to 0 (unlimited), so this is not behavior-preserving under the existing default configuration: POST bodies larger than 1 MiB that were previously forwarded to the auth service will now be rejected by the plugin default.

Please update the PR description and the forward-auth documentation to clearly state:

  • this affects users who use forward-auth POST mode to forward large request bodies;
  • the effective default changes from unlimited to 1 MiB for this plugin path;
  • oversized requests will receive 413;
  • users need to configure max_req_body_size to a larger value to preserve the previous behavior.

…e forward-auth default

Extend the max_req_body_size request-body cap to the AI proxy plugins and
align the forward-auth default:

- ai-proxy / ai-proxy-multi: add max_req_body_size (default 67108864 = 64 MiB);
  oversized requests are rejected with 413 in access() before the body is
  parsed for LLM proxying
- forward-auth: raise the max_req_body_size default from 1 MiB to 64 MiB so
  existing large-body POST auth flows are not affected by the default

Docs and e2e tests updated.
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Jun 3, 2026
@shreemaan-abhishek shreemaan-abhishek changed the title feat(forward-auth): support max_req_body_size to limit forwarded body feat: add max_req_body_size to bound client request body in forward-auth and ai-proxy Jun 3, 2026
@shreemaan-abhishek
Copy link
Copy Markdown
Contributor Author

@membphis addressed: the PR description now includes an explicit Default behavior change section documenting exactly when the 64 MiB default is observable, and the user-facing docs for forward-auth, ai-proxy, and ai-proxy-multi document the new max_req_body_size attribute and its default. Under the default client_max_body_size there is no behavior change.

end

function _M.access(conf, ctx)
local _, body_err = core.request.get_body(conf.max_req_body_size)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an unnecessary body read performed solely to check the size. However, reading the body consumes performance, resulting in some resource waste.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally, I realized variables like post_args.model defined within route.var will also trigger body reading, and this cannot be restricted via plugin configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants