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 writeThis MR:
- Sets
GITLAB_BIN_DIR=/tmp/gitlab-bininGitlab::DuoWorkflow::Sandbox#environment_variables. Keys in that hash already pass throughenv -i, so this covers both the SRT and nono sandboxes. It also covers the unsandboxed fallback, because it is a job variable./tmpis already writable in both sandboxes, so the filesystem policy does not change.- The CLI's private-directory check accepts this path:
/tmpis root-owned and sticky, and the CLI createsgitlab-binwith mode0700. - The CLI also extracts its seccomp helper there now, so the misleading
Sandbox unavailablestartup log from gitlab-org/editor-extensions/gitlab-lsp#3249 goes away too.
- Makes
ResumeWorkflowServicerefresh 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 emptyGITLAB_BIN_DIRand hit the same failure. - Bumps
IMAGE_PATHtov0.0.23andDUO_CLI_VERSIONto9.30.0, so the CLI downloaded for custom images matches the one in the default image. The only difference betweenv0.0.22andv0.0.23is 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
- INC-15070
- Incident revert of the image: !261482 (merged)
- Revert of the CLI version: !261473 (merged)
- Image bumps: gitlab-org/duo-workflow/default-docker-image!55 (merged) (9.29.0,
v0.0.22) and gitlab-org/duo-workflow/default-docker-image!56 (merged) (9.30.0,v0.0.23) - CLI change: gitlab-org/editor-extensions/gitlab-lsp@e75d2c37
- Related CLI sandbox log issue: gitlab-org/editor-extensions/gitlab-lsp#3249
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.
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
- In a GDK project with remote flows enabled, remove the
imagekey from.gitlab/duo/agent-config.ymlso the flow uses the default image. - Start a
developer/v1flow with a goal such as: "Call the find_files tool exactly once with the pattern*.mdand report the result." - In the job log, check for
workflow-generic-image:v0.0.23andExtraction root from GITLAB_BIN_DIR: /tmp/gitlab-bin, check thatfind_filesreturns results, and check that there are norg is unavailablelines. - To see the failure, remove
GITLAB_BIN_DIRfromGitlab::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.



