Forward the client identity on Workhorse-run agent actions

What does this MR do and why?

The Duo Workflow Service never calls GitLab Rails directly. For websocket clients (browser and mobile app), the service sends actions to the executor, which is Workhorse. Workhorse forwarded no client headers on those action requests, so every agent_platform_session_started event for a web session is unattributable today.

Production data since 2026-09-23:

  • agent_platform_session_created: 6,452 events with a recognised browser, 6,708 without.
  • agent_platform_session_started: 0 events with a recognised browser, 12,991 without.

This MR adds client header forwarding through Workhorse:

  • Ai::DuoWorkflows::ConnectionConfigService#cloud_connector_headers reads the identity resolved by the first MR and adds x-gitlab-client-type and x-gitlab-client-name when not already supplied.
  • Workhorse runHTTPActionHandler extracts these from connection config and sets X-Gitlab-Client-Type and X-Gitlab-Client-Name on every action request.
  • Rails accepts the forwarded browser family (chrome, firefox, and so on) in the name header and maps it to the browser type. The resolver previously read the family only from the User-Agent, and the Workhorse User-Agent has no browser family, so the name would otherwise be lost.
  • Before this MR is deployed, Rails treats the Workhorse User-Agent as system as a fallback, so there is no regression.

Verification: 2 Go tests added and passing. 61 Ruby spec examples green (resolver plus connection config service).

References

Depends on !257624 (merged) for Gitlab::Tracking::ClientIdentity.

How to set up and validate locally

  1. In GDK with the Duo Agent Platform working, start an agentic chat in the browser and check log/api_json.log for the PUT /api/v4/ai/duo_workflows/workflows/:id/status request: ua should be Agent-Flow-via-GitLab-Workhorse, meta.client_type should be browser, and meta.client_name should be the browser family, for example chrome.

MR acceptance checklist

Evaluated against the MR acceptance checklist.

🤖 Generated with Claude Code

Edited by Marcel van Remmerden

Merge request reports

Loading
Loading