Skip to content

fix: introduce per-job cert volume with %gcl% token#1877

Open
ticapix wants to merge 1 commit into
firecow:masterfrom
ticapix:fix/per-job-cert-volume
Open

fix: introduce per-job cert volume with %gcl% token#1877
ticapix wants to merge 1 commit into
firecow:masterfrom
ticapix:fix/per-job-cert-volume

Conversation

@ticapix

@ticapix ticapix commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Hello,

This addresses #918

Jobs using docker:dind as a service share TLS client certificates via a named volume. The previous approach relied on a static volume name (e.g. certs) configured in .gitlab-ci-local-env, which caused race conditions when concurrent jobs wrote to and cleaned up the same volume, each dind service writing its own certificates.

A new %gcl-cert%: prefix in VOLUME entries is now resolved at runtime to a per-job unique volume name (gcl-<job>-<id>-cert), matching the naming pattern of the existing build/tmp volumes.
The %gcl-cert% token was chosen because Docker hard-rejects it if it ever reaches the daemon unsubstituted (invalid volume name character), rather than silently bind-mounting an unintended host path.

Changes:

  • get certVolumeName() getter returning a per-job unique name
  • Cert volume is created and registered for cleanup alongside build/tmp volumes when any %gcl-cert%: entry is present in argv.volume
  • %gcl-cert%: prefix is resolved to certVolumeName in both the job container and service container volume loops

I'm not sure how to add a test.

I used this config to test the implementation

docker1:
  stage: test
  image: docker:29-cli
  services:
    - docker:29-dind
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
  script:
    - docker info

docker2:
  stage: test
  image: docker:29-cli
  services:
    - docker:29-dind
  before_script:
    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY"
  script:
    - docker info

The .gitlab-ci-local-env looks like

PRIVILEGED=true
ULIMIT=8000:16000
VOLUME=%gcl-cert%:/certs/client
VARIABLE="DOCKER_TLS_CERTDIR=/certs"

Summary by cubic

Adds a per-job cert volume for Docker-in-Docker by introducing a %gcl-cert%: volume token. This prevents cross-job TLS cert races and cleanup conflicts when jobs run in parallel.

  • Bug Fixes

    • Create and track certVolumeName (gcl-<job>-<id>-cert) when any argv.volume starts with %gcl-cert%:, matching build/tmp naming.
    • Resolve %gcl-cert%: at runtime for job and service --volume flags so the token never reaches Docker, avoiding accidental host bind mounts.
  • Migration

    • Replace a static cert volume like certs:/certs/client with %gcl-cert%:/certs/client to enable per-job isolation.

Written for commit e3fcf9a. Summary will update on new commits.

Review in cubic

Jobs using docker:dind as a service share TLS client certificates via a
named volume. The previous approach relied on a static volume name (e.g.
`certs`) configured in .gitlab-ci-local-env, which caused race conditions
when concurrent jobs wrote to and cleaned up the same volume.

A new `%gcl%:` prefix in VOLUME entries is now resolved at runtime to a
per-job unique volume name (`gcl-<job>-<id>-cert`), matching the naming
pattern of the existing build/tmp volumes. The `%gcl%` token was chosen
because Docker hard-rejects it if it ever reaches the daemon unsubstituted
(invalid volume name character), rather than silently bind-mounting an
unintended host path.

Changes:
- get certVolumeName() getter returning a per-job unique name
- Cert volume is created and registered for cleanup alongside build/tmp
  volumes when any %gcl%: entry is present in argv.volume
- %gcl%: prefix is resolved to certVolumeName in both the job container
  and service container volume loops

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

Re-trigger cubic

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant