Resolve Duo tool approvals from the Slack review modal

What does this MR do and why?

Third of three MRs that let a user approve or deny a paused Duo agent's tool call from Slack. This one applies the decision submitted through the review modal.

  • DuoToolApprovalModalSubmitService handles the modal's view_submission: reads the Approve / Deny choice and workflow_id:fingerprint from private_metadata, resolves the Slack user, and calls ResolveToolApprovalService.
  • ResolveToolApprovalService is the security gate: only the session owner, only with live update_duo_workflow permission, only while the fingerprint still matches the pending request, serialized under a lease. Then the run resumes via ExecuteRunService and the decision is audited (duo_tool_call_approved / duo_tool_call_denied) and tracked (ai_duo_messaging_tool_approval_resolved).
  • On success the channel message is updated in place via pending_approval_ts so the Review button disappears, and the modal swaps to the outcome. Refusals swap the modal to a notice saying why (not owner, already answered, unavailable).
  • The session's status and checkpoint only change once the runtime picks the run up, so a second submission in that window would otherwise pass the fingerprint check and dispatch a second resume. The applied decision is recorded as answered_approval in the callback context, checked under the lease after reloading the row from the primary.
  • The callback context's status_ts is left alone, so the resumed run keeps editing the reply the user is already reading rather than posting a new message (see !257339 (merged)).

The Review click in the previous MR only decided what to show; a modal payload is not proof of anything, so everything is re-checked here.

Resuming goes through ExecuteRunService, which landed in !256183 (merged) (#628435). This MR was stacked on that branch and has been rebased onto master now that it is merged. Behind the default-off slack_duo_api_flow flag.

Stack:

  1. Foundations — !255536 (merged) (merged)
  2. Post the request and open the review modal — !255537 (merged) (merged)
  3. This MR — resolve the decision

Split out of !254849 (closed).

Nothing pauses a real Slack session yet: the slack_assistant flow has no approval nodes and pre-approves every privilege it holds. Those switches are sequenced after this MR on purpose (a pending approval has no timeout, so turning them on first would strand sessions). In flight:

References

Screenshots or screen recordings

Slack only; no changes to the GitLab web UI.

Demo

How to set up and validate locally

End to end, with a real session. Prerequisites: GitLab for Slack installed on the GDK with the bot token, your Slack user linked (ChatName), Slack events and interactions reaching the GDK (tunnel or Socket Mode), slack_assistant/v1 enabled for the group, Feature.enable(:slack_duo_api_flow).

Until the items listed under "In flight" above land, three local changes make a session pause on create_issue:

  1. GDK AI gateway, duo_workflow_service/agent_platform/v1/flows/configs/slack_assistant/1.0.0.yml: add require_tool_approval: true to the slack_agent component, then gdk restart duo-workflow-service. (Tracked in #629377.)

  2. ee/app/services/ai/messaging/adapters/base.rb, start_workhorse_flow: pass pre_approved_agent_privileges: flow.agent_privileges - [AgentPrivileges::READ_WRITE_GITLAB], then gdk restart rails-background-jobs. (What !256214 (merged) does properly.)

  3. The DWS status-before-checkpoint race (gitlab-org/modelops/applied-ml/code-suggestions/ai-assist!7008 (merged)) means the Review message is usually not posted by the worker. Either apply gitlab-org/modelops/applied-ml/code-suggestions/ai-assist!7008 (merged) to the gateway, or re-fire the hook once the session is paused:

    w = Ai::DuoWorkflows::Workflow.order(:id).last # status tool_call_approval_required
    ctx = w.messaging_callback_context
    Ai::Messaging::Adapters::Slack.from_callback_context(ctx).on_approval_required(callback_context: ctx, workflow: w)

Then, in Slack: @Duo create an issue in <group>/<project> titled "Demo" with a short description.

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.

Edited by Jannik Lehmann

Merge request reports

Loading
Loading