[FF] duo_client_executed_flow_governance -- govern Duo flow runs by how they are executed

Summary

Roll out the fix currently behind the duo_client_executed_flow_governance feature flag.

Note

Process and guidance live in the docs — this issue is just the commands and a place to track the rollout. "Rolling out" means incrementally enabling the flag on GitLab.com to validate stability — it is not the same as releasing the feature, which happens when the flag is removed. Feature flag controls · Feature flag lifecycle

What could go wrong?

Blast radius is small by construction. Only developer/v1, code_review/v1 and fix_pipeline/v1 are governed by the new classification at all — chat, agentic_chat/v1 and software_development are not foundational catalog flows, so web chat, IDE chat and IDE flow mode are unaffected. Of those three, only developer/v1 is client-executed in practice, and the CLI only sends it when duo_cli_default_flow is also enabled. The GraphQL mutation and the agent delegation endpoint are not eligible for the client-executed branch, so they keep their current behaviour.

Blocker before going past non-production: access_duo_agentic_chat checks the agentic_chat licensed feature, where the path it replaces checked ai_workflows. If any tier or add-on grants ai_workflows without agentic_chat, those customers lose Duo CLI session creation once this flag and duo_cli_default_flow are both on. This needs a licensing answer before a percentage rollout — nobody can reach it while duo_cli_default_flow is off.

What the flag changes when on, for a run the caller executes itself:

  • the per-container flow allowlist (Settings → Automate → Flows) no longer applies
  • the minimum role for asynchronous execution no longer applies; the Developer floor and the configurable interactive minimum role still do
  • no service account is resolved, so the AI Gateway subject is the user

Rollback is clean. Turning the flag off restores catalog governance on the next request; nothing is persisted differently, so sessions created while it was on are unaffected.

Rollout

Run all production /chatops in #production and cross-post the results to #g_duo_agent_platform . Background: incremental rollout process, feature actors.

Non-production

/chatops gitlab run feature set duo_client_executed_flow_governance 50 --actors --dev --pre --staging --staging-ref
/chatops gitlab run feature set duo_client_executed_flow_governance true --dev --pre --staging --staging-ref

Production — percentage rollout (wait ≥15 min between steps, watch dashboards):

/chatops gitlab run feature set duo_client_executed_flow_governance <percentage> --actors

Or target specific actors instead:

/chatops gitlab run feature set --group=gitlab-org,gitlab-com duo_client_executed_flow_governance true

Important

The actor is the root namespace, so only --group and percentage gates work. FlowExecutionAuthorizer calls Feature.enabled?(:duo_client_executed_flow_governance, root_ancestor). Flipper matches the gate against that actor's flipper_id (for example Group:9970), so:

Enablement Matches a root namespace actor?
--group=<root group> yes
<percentage> --actors, or global true yes
--user=<username> no
--project=<path> no
--feature-group=gitlab_team_members no — the group block matches User actors

Two consequences:

  • --group must name the root group. The check reads container.root_ancestor, so a subgroup gate never fires.
  • A session in a personal namespace can never be targeted, because there is no group actor. Those runs need the percentage or global gate.

Enabling with a gate that cannot match is silent: the run falls back to the background branch and the create endpoint answers a bare 403 Forbidden with no message, which Duo CLI shows as "GitLab Duo Agent Platform is not available for this namespace or project" and then "This session has ended". Reproduced on 2026-08-14, see the note below.

Before global rollout

Confirm the relevant gotchas before going to 100% — see enabling a feature for GitLab.com:

  • Licensing answer (blocker, see "What could go wrong?"): confirm no tier or add-on grants ai_workflows without agentic_chat. If one does, those customers lose Duo CLI session creation when this flag and duo_cli_default_flow are both on.
  • Docs: clarify that per-container flow enablement (Settings > Automate > Flows) governs what GitLab runs unattended; a session the user executes themselves (for example, Duo CLI) is governed by Duo access and the flow's own entitlement.
  • Follow-up: enforce background governance at the execution boundary (StartWorkflowService), not only at the create endpoints, so a future "promote a client-executed session to run unattended" feature re-runs catalog governance at promotion time by construction.
  • Docs + version history updated
  • Breaking changes announced, if any
  • Change management issue opened, if required
  • External API consumers handled with a fail-open mechanism, if applicable

Cleanup

Remove the flag once deemed stable — see cleaning up. Track it here, or open a follow-up Feature Flag Cleanup issue. Remove the flag and its YAML definition from the codebase, then:

/chatops gitlab run release check https://gitlab.com/gitlab-org/gitlab/-/merge_requests/248339 <milestone>
/chatops gitlab run feature delete duo_client_executed_flow_governance --dev --pre --staging --staging-ref --production

Rollback

/chatops gitlab run feature set duo_client_executed_flow_governance false                                         # production
/chatops gitlab run feature set duo_client_executed_flow_governance false --dev --pre --staging --staging-ref     # non-production
/chatops gitlab run feature delete duo_client_executed_flow_governance --dev --pre --staging --staging-ref --production  # remove entirely
Edited by Thomas Schmidt