Reject large repository file reads for ai_workflows tokens

What does this MR do and why?

Duo agent tool calls to GET /projects/:id/repository/files/:file_path are the largest memory allocator on the ai-assisted fleet, at up to 4.5 GB per request. Rails loads the whole blob, hashes it, then Base64-encodes it into JSON.

None of that work can succeed for a large file. Workhorse caps the response it relays to the Duo Workflow Service at just under 4 MiB, and the Duo Workflow Service caps every gRPC message at 4 MiB. The Base64 content of anything over about 3 MB is dropped after Rails has already paid for it. The agent often retries the resulting 500 responses as well.

This MR returns 413 with a message the agent can act on when a token with the ai_workflows scope asks for a file over 3,000,000 bytes. The check uses the blob size that is already loaded with the metadata, so it runs before any content is read. It covers the JSON endpoint and /raw, since /raw also reads the whole blob to compute X-Gitlab-Content-Sha256. Other tokens are unaffected.

The check is behind the limit_repository_file_size_for_ai_workflows feature flag (gitlab_com_derisk, default off).

Why 3,000,000 bytes and 413
  • Workhorse's ActionResponseBodyLimit is 4 MiB minus 4 KiB (4,190,208 bytes). Base64 of 3,000,000 bytes is 4,000,000 bytes, which leaves room for the JSON metadata. Files a little over 3 MB already fail today, so the cap does not take away anything that works.
  • 413 comes from the existing file_too_large! helper. The Duo Workflow Service retries 5xx, 401 and 429 responses but not 413, so the agent gets the message on the first attempt.
  • ai_workflows tokens are also available to remote flows running in CI, which could call the API without the 4 MiB message limit. The feature flag covers that risk during rollout.

References

Screenshots or screen recordings

Not applicable, this is an API-only change.

How to set up and validate locally

  1. Enable the feature flag in the Rails console:
    Feature.enable(:limit_repository_file_size_for_ai_workflows)
  2. Commit a file larger than 3 MB to a project, for example head -c 3500000 /dev/urandom | base64 > big.txt.
  3. In Duo Agentic Chat on that project, ask the agent to read big.txt.
  4. Confirm the get_repository_file tool call fails with the "File is too large to read" message, and log/api_json.log shows a 413 for the request with user agent Agent-Flow-via-GitLab-Workhorse.
  5. Request the same file with a personal access token and confirm it is still returned:
    curl --header "PRIVATE-TOKEN: <your_access_token>" \
      --url "http://gdk.test:3000/api/v4/projects/<id>/repository/files/big.txt?ref=main"

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Merge request reports

Loading
Loading