Apply group IP address restrictions to Orbit graph queries

What does this MR do and why?

Orbit graph queries (/api/v4/orbit/query and /api/v4/orbit/mcp) authorize their results through a redaction callback that runs read_project / read_group. That callback is served on an internal endpoint, and internal endpoints do not receive the request IP, so group IP address restrictions are not applied to Orbit results the way they are on the standard REST and UI paths.

This MR aligns Orbit with the platform behavior: it forwards the request IP resolved at the user-facing endpoint through Workhorse to the redaction callback and evaluates the authorization policy with it, mirroring how the git internal API re-establishes the IP on its own internal endpoint.

Raised via the forum: https://forum.gitlab.com/t/orbit-and-api-networking-access/134447

Changed files
  • ee/lib/ee/gitlab/workhorse.rb — send_orbit_query forwards Gitlab::IpAddressState.current as the ClientIp send-data param (the user-facing request is non-internal, so the IP is already set).
  • workhorse/internal/orbit/sendquery.go, workhorse/internal/orbit/redaction.go — carry ClientIP through and set the X-Gitlab-Orbit-Client-Ip header on the redaction callback.
  • ee/lib/api/internal/orbit.rb — wrap RedactionService in Gitlab::IpAddressState.with(request.headers['X-Gitlab-Orbit-Client-Ip']).
  • ee/spec/requests/api/internal/orbit_redaction_spec.rb — regression coverage: resource redacted from a disallowed IP, authorized from an allowed IP.

The header is set only by Workhorse on the internal callback (guarded by verify_workhorse_api!), so it is not client-controllable.

How to set up and validate locally

Verified end to end on GDK. With a group that has an IP address range set and a request from an IP outside it:

  • /orbit/query and MCP query_graph now return no rows for projects/definitions in that group, matching the standard API behavior.
  • A request from an in-range IP still returns the rows, and removing the range restores them. Non-restricted queries are unaffected.

Tests: existing redaction/workhorse specs green (25 examples) plus 2 new IP examples; Go orbit package tests green.

Performance

No N+1. One additional ip_restrictions load per distinct root namespace in the redaction batch (measured +1 query for a 16-project batch sharing one root; timing within noise). This is the same policy check the standard request path already performs.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist.

Related to gitlab-org/orbit/knowledge-graph#310 (closed)

Edited by Michael Angelo Rivera

Merge request reports

Loading
Loading