Set GITLAB_BIN_DIR for Duo CLI and bump workflow image to v0.0.23

What does this MR do and why?

This is the forward fix for INC-15070. It moves the default DAP workflow image forward to workflow-generic-image:v0.0.23 (Duo CLI 9.30.0) instead of staying on v0.0.21 (Duo CLI 9.27.0).

Since Duo CLI 9.29.0, the CLI extracts its embedded rg to $HOME/.cache and no longer falls back to the temp directory (gitlab-org/editor-extensions/gitlab-lsp@e75d2c37). 9.30.0 keeps that behaviour. The job sandbox mounts $HOME read-only, so extraction fails and the agent's find_files tool stops working:

[RgBinaryProvider] Failed to extract rg from /$bunfs/root/rg-jgk48zc6.: Error: EROFS: read-only file system, mkdir '/root/.cache'
[RipgrepService] rg is unavailable: Error: Could not extract the embedded rg to a private directory; set GITLAB_BIN_DIR to a directory only you can write

This MR:

  1. Sets GITLAB_BIN_DIR=/tmp/gitlab-bin in Gitlab::DuoWorkflow::Sandbox#environment_variables. Keys in that hash already pass through env -i, so this covers both the SRT and nono sandboxes. It also covers the unsandboxed fallback, because it is a job variable.
    • /tmp is already writable in both sandboxes, so the filesystem policy does not change.
    • The CLI's private-directory check accepts this path: /tmp is root-owned and sticky, and the CLI creates gitlab-bin with mode 0700.
    • The CLI also extracts its seccomp helper there now, so the misleading Sandbox unavailable startup log from gitlab-org/editor-extensions/gitlab-lsp#3249 goes away too.
  2. Makes ResumeWorkflowService refresh the sandbox variables. A resumed job copies the first job's variables but rebuilds the image and the sandbox wrapper. Without this, a session started before this change would resume on the new image with an empty GITLAB_BIN_DIR and hit the same failure.
  3. Bumps IMAGE_PATH to v0.0.23 and DUO_CLI_VERSION to 9.30.0, so the CLI downloaded for custom images matches the one in the default image. The only difference between v0.0.22 and v0.0.23 is the Duo CLI version (gitlab-org/duo-workflow/default-docker-image!56 (merged)). Between 9.29.0 and 9.30.0, the CLI's binary extraction code is unchanged.

Security: the CLI asks for a directory "only you can write" so that sandboxed commands can't swap out the extracted binary. That protects the CLI's own sandbox, which is opt-in and not used in remote flows. In remote flows the agent's commands already run as the same UID inside the same job-level sandbox as the CLI, so a tampered rg gives the agent nothing it couldn't already do.

Merge order: !261473 (merged) reverts DUO_CLI_VERSION to 9.27.0 and is still open. Whichever of the two merges second gets a conflict on the DUO_CLI_VERSION line. If that is this MR, resolve the conflict to keep 9.30.0.

Custom images that run Duo CLI 9.29.0 or later also get the fix, without any image change.

References

Screenshots or screen recordings

Verified in a local GDK with this MR's IMAGE_PATH (the default image, v0.0.23, Duo CLI 9.30.0). The project's agent config had no image key. The developer/v1 goal called find_files with *.md once, then ran uname -m && git --version. "Before" ran the same image without GITLAB_BIN_DIR.

Before (session 117, job 728) After (session 116, job 727)
1-before-session-wf117 3-after-session-wf116
find_files is unavailable: ripgrep could not be located. The shell command works. find_files returns the 11 .md files in the project. The shell command works.
2-before-job728-rg-unavailable 4-after-job727-rg-resolved
Extraction root defaulted to /root/.cache → EROFS → rg is unavailable Extraction root from GITLAB_BIN_DIR: /tmp/gitlab-bin → rg binary resolved to "/tmp/gitlab-bin/gitlab-duo/bin/e152ea68/rg"

The after job also logs [SandboxAvailability] Sandbox available: platform=linux, provider=srt, where the before job logged Sandbox unavailable. The same before/after result was also seen with v0.0.22 (Duo CLI 9.29.0). The resume refresh is covered by specs only. It was not exercised in GDK.

How to set up and validate locally

  1. In a GDK project with remote flows enabled, remove the image key from .gitlab/duo/agent-config.yml so the flow uses the default image.
  2. Start a developer/v1 flow with a goal such as: "Call the find_files tool exactly once with the pattern *.md and report the result."
  3. In the job log, check for workflow-generic-image:v0.0.23 and Extraction root from GITLAB_BIN_DIR: /tmp/gitlab-bin, check that find_files returns results, and check that there are no rg is unavailable lines.
  4. To see the failure, remove GITLAB_BIN_DIR from Gitlab::DuoWorkflow::Sandbox#environment_variables, restart Rails, and repeat.

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 Sebastian Rehm

Merge request reports

Loading
Loading