[FF] dap_git_credential_helper -- Authenticate Duo Agent Platform git operations with a credential helper
Summary
Roll out the feature currently behind the dap_git_credential_helper feature flag.
- DRI: @AndrasHerczeg
- Team Slack channel:
#f_duo-agent-platform - Introduced by: !243872 (merged)
- Milestone: 19.4
When enabled, Duo Agent Platform git operations authenticate through a credential helper instead of a token embedded in the origin URL. The flag also turns on FF_GIT_URLS_WITHOUT_TOKENS and drops the sed-based git remote set-url rewrite that previously wrote the OAuth token into .git/config.
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
Preconditions
These must be confirmed before the flag is enabled anywhere, including staging.
-
get_sourcesdispatch-time token staleness. With the flag on, the Runner's ownget_sourcesclone authenticates with the composite-identity OAuth token instead of job-lifetimeCI_JOB_TOKEN. Sinceget_sourcesruns at job start, this only fails if the token is already stale or near-expiry at dispatch (e.g. a queueing delay between token mint and job start) - not from the 1h TTL elapsing mid-job. Confirm the queue-to-dispatch gap stays comfortably inside the token TTL before widening beyond canary.This is narrower than it may first appear: the broader "1h composite-token TTL vs 2h job timeout" mid-job risk is real, but it is pre-existing and unconditional on this flag - the sed-based path this MR replaces already authenticates the same ongoing git operations (
run_command,run_git_command) with this same token today, at full production scale. This flag's rollout percentage does not change exposure to that risk, so it does not block rollout here. Tracked separately in #623427, against the OAuth-token git-auth behaviour in general and decoupled from this rollout.Discussion: !243872#note_3673850333, !243872#note_3677581132, !243872#note_3686509543.
-
Runner fleet includes gitlab-org/gitlab-runner!6729 (merged 2026-06-23). That MR makes the credential helper visible to user-authored git commands by writing a per-job seed file and exporting
GIT_CONFIG_GLOBAL. Without it, git run outside Runner's own clone (which is how the agent runs git) does not see the helper and fails to authenticate. Confirm the runners serving Duo Agent Platform jobs are on a version containing it. -
FF_USE_CONCRETE=trueis not in play for DAP jobs. !6729 (merged) explicitly defers the step-runner path:setupGlobalGitConfigis scoped to theget_sourcesstage, so the seed file is deleted before user-script stages run. If DAP executors run concrete, the fix does not apply and this rollout should not proceed. -
run_git_command(LSP) authenticates successfully. It builds its own inline credential helper reading$GIT_PASSWORDrather than using the installed git config, and previously failed with exit 128 against a credential-free origin. See !243872#note_3557360524. -
No second remote or host in the coding environment. The credential helper is installed as
credential.<gitlab-url>.helper, built fromGitlab.config.gitlab.url— the full instance URL, including any relative-URL path — rather than the barecredential.helperkey, so the OAuth password is only offered when git is challenged by the GitLab instance; helpers for other hosts (submodules, LFS, bundle URIs) are unaffected. Path-scoped keys do match withoutuseHttpPath, so on a relative-URL install (https://host/gitlab) the path narrows the scope further, to the GitLab instance path rather than the whole host. The helper's own stdin check still comparesprotocol://hostonly, since git never sends a path in the credential request. Submodules are not fetched (the Runner defaultGIT_SUBMODULE_STRATEGY: none— not pinned by DAP, so a project could override it) andGIT_LFS_SKIP_SMUDGE=1is set, as a second layer. Raised in !243872#note_3672274449; scoping corrected in !243872#note_3760616037 and !243872#note_3760903580; reconfirm before widening if the coding environment ever gains a second host. -
fix_pipeline_experimentalis off for the projects being enabled. With that flag on for a project or its root ancestor,Ai::Catalog::FoundationalFlow::Definitions::FixPipeline#flow_version_resolverroutes Fix Pipeline away fromfix_pipeline/v11.0.3(clean) tofix_pipeline/experimental1.0.0, whosegit_setupentry point still runsgit remote set-url originwith the token in the URL - defeating the point of the credential helper for those jobs. This cannot be detected from the job script, which finishes before the flow's first component runs. Two experimental flow configs need patching first, tracked in ai-assist#2778.
Historical context: gitlab-org/gitlab-runner#38268 tracked the 17.5 regressions (submodule auth, Windows credential-helper erase, GCM credential caching) that caused FF_GIT_URLS_WITHOUT_TOKENS to be defaulted back off in 17.5.1. It is closed (17.6), so it is not a blocker, but it is a useful checklist of the failure modes to watch for during rollout.
What could go wrong?
Blast radius is limited to Duo Agent Platform workflow jobs; the flag does not affect regular CI. The failure mode is a hard one — git operations fail with exit 128 or could not read Username for 'https://gitlab.com' — so it surfaces immediately rather than degrading silently. There is no data-loss risk. Rollback is a single chatops command and takes effect on the next workflow start; already-running jobs keep the configuration they started with.
The exception is a Runner too old to honour FF_GIT_URLS_WITHOUT_TOKENS: the clone succeeds with the token still embedded in the origin URL, so the security objective is missed with nothing surfacing it. Confirm the fleet version rather than expecting to detect it at runtime.
Rollout
Run all production /chatops in #production and cross-post the results to the team channel. Background: incremental rollout process, feature actors.
Non-production
/chatops gitlab run feature set dap_git_credential_helper 50 --actors --dev --pre --staging --staging-ref
/chatops gitlab run feature set dap_git_credential_helper true --dev --pre --staging --staging-refProduction — canary projects first:
/chatops gitlab run feature set --project=gitlab-org/gitlab dap_git_credential_helper true
/chatops gitlab run feature set --group=gitlab-org dap_git_credential_helper trueThen percentage rollout (wait ≥15 min between steps, watch dashboards). Do not start this until the preconditions above are confirmed:
/chatops gitlab run feature set dap_git_credential_helper 1 --actors
/chatops gitlab run feature set dap_git_credential_helper 10 --actors
/chatops gitlab run feature set dap_git_credential_helper 25 --actors
/chatops gitlab run feature set dap_git_credential_helper 50 --actors
/chatops gitlab run feature set dap_git_credential_helper 100 --actorsBefore global rollout
Confirm the relevant gotchas before going to 100% — see enabling a feature for GitLab.com:
- All preconditions above confirmed
- Docs + version history updated
- Change management issue opened, if required
- Self-managed guidance covered: the flag depends on Runner behavior, so self-managed instances need a Runner version containing !6729 (merged) before enabling
Cleanup
Remove the flag once deemed stable — see cleaning up. Remove the flag and its YAML definition from the codebase, then:
/chatops gitlab run release check https://gitlab.com/gitlab-org/gitlab/-/merge_requests/243872 19.4
/chatops gitlab run feature delete dap_git_credential_helper --dev --pre --staging --staging-ref --productionRollback
/chatops gitlab run feature set dap_git_credential_helper false # production
/chatops gitlab run feature set dap_git_credential_helper false --dev --pre --staging --staging-ref # non-production
/chatops gitlab run feature delete dap_git_credential_helper --dev --pre --staging --staging-ref --production # remove entirelyRelated: https://gitlab.com/gitlab-org/gitlab/-/work_items/593467