Skip to main content

Registry authentication

Configure credentials once to pull private job images, build images, or mirror container images and OCI Helm charts. Include the common component and grant each credential only the registry permissions required by its jobs.

Choose where to supply credentials​

VariableUsed byValue
DOCKER_AUTH_CONFIGGitLab Runner before startup, then commands inside the jobDocker-compatible authentication JSON; use a text variable for Runner image pulls.
CI_REGISTRY_AUTH_FILECommands inside the jobA GitLab file variable or literal Docker-compatible JSON for additional registries.
CI_REGISTRYCommands inside the jobDestination hostname without https://, such as harbor.example.com.
CI_REGISTRY_PROJECT_PATHContainer build and publish jobsRepository namespace below the destination hostname; the component appends its image name.
CI_REGISTRY_USER, CI_REGISTRY_PASSWORDCommands inside the jobCredentials for CI_REGISTRY; normally predefined by GitLab CI.
CI_JOB_TOKENCommands inside the jobFallback password when the GitLab registry password is unavailable.

Runner pulls image and services images before before_script starts. A runtime login or CI_REGISTRY_AUTH_FILE alone cannot authorize those pulls. See GitLab's private image authentication for Runner configuration and access requirements.

Store credentials under Settings > CI/CD > Variables at project or group level, or under Admin > Settings > CI/CD > Variables for an instance-wide credential. Use compact, single-line JSON without spaces when masking a text variable, and disable variable-reference expansion for literal credentials. See GitLab's masking requirements. Mark credentials protected only when all consuming jobs run on protected branches or tags; protected variables are unavailable on other refs.

Configure an additional registry​

Generate an auth value locally, without committing the secret:

printf '%s' '<registry-user>:<registry-password>' | base64 | tr -d '\n'

Put the result in a masked DOCKER_AUTH_CONFIG text variable, or in CI_REGISTRY_AUTH_FILE when only commands inside the job need it:

{
"auths": {
"registry.example.com:5000": {
"auth": "<base64-username-colon-password>"
}
}
}

Registry keys must exactly match the hostname and optional port in the image reference. Base64 is an encoding, not encryption. Prefer static auths entries unless both Runner and each component image provide the required credential helper.

Include the components and use the matching registry name:

include:
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/common@stable
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/oci-mirror@stable
inputs:
source: registry.example.com:5000/team/application:1.0.0
target: $CI_REGISTRY_IMAGE/mirrors

On a tag pipeline, the job publishes mirrors/application:1.0.0 below $CI_REGISTRY_IMAGE. An authentication error fails the registry operation; credentials are not inferred from unrelated API tokens.

Authenticate to a protected group registry​

For projects sharing private job images, create a group deploy token with read_registry and, for publishing jobs, write_registry. Set these group variables:

VariableValue
CI_REGISTRY_USERDeploy-token username.
CI_REGISTRY_PASSWORDMasked deploy-token secret.
DOCKER_AUTH_CONFIGMasked authentication JSON using the registry hostname and deploy-token credentials.

Use the JSON format above, with the hostname from the private image reference. If the variables are protected, run both the build and every job pulling its image on protected refs. Limit the token to the group owning those images.

Add credentials in a before script​

Use ci_registry_auth_add REGISTRY USER PASSWORD when a job obtains credentials at runtime. Create masked MIRROR_USER and MIRROR_PASSWORD variables first. Load the library before calling the helper:

include:
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/common@stable
- component: $CI_SERVER_FQDN/xrow-public/ci-tools/oci-mirror@stable
inputs:
source: registry.example.com/team/application:1.0.0
target: $CI_REGISTRY_IMAGE/mirrors

mirror:oci:
before_script:
- source <(echo "${CI_BOOTLOADER}" | base64 -d) stable
- ci_registry_auth_add registry.example.com "${MIRROR_USER}" "${MIRROR_PASSWORD}"

Keep the library reference (stable here) aligned with the included component version. The helper adds or replaces only that registry's credentials; other registry entries remain available. It does not enable private Runner image pulls retroactively.

Credential precedence and client support​

CI Tools merges DOCKER_AUTH_CONFIG, then CI_REGISTRY_AUTH_FILE, then runtime logins into a private job-scoped configuration. Later entries override the same registry from earlier sources. Automatic GitLab and legacy Red Hat logins run when their login helper is called, which can be after before_script.

Podman, Buildah, skopeo, Helm, ORAS, and Cosign share the merged configuration through DOCKER_CONFIG, REGISTRY_AUTH_FILE, and HELM_REGISTRY_CONFIG. After initialization, CI_REGISTRY_AUTH_FILE points to the merged output file. Do not edit a source variable expecting a second initialization to reload it; use ci_registry_auth_add for later changes.

Registry-specific credentials​

For GitHub Container Registry, add ghcr.io with a GitHub username and a token authorized for the required packages. GITHUB_TOKEN, GITHUB_USER, and GITHUB_USERNAME no longer trigger automatic image or Helm registry login. GITHUB_TOKEN remains available to unrelated GitHub API, Composer, and Renovate operations. A job using a legacy GitHub registry variable prints a ⚠️ deprecation warning without using that token for registry authentication.

For Red Hat Registry, add registry.redhat.io using its registry account and secret. The legacy RH_REGISTRY_ACCOUNT and RH_REGISTRY_PASSWORD pair still works when both variables are defined, but prints a ⚠️ deprecation warning. Migrate the pair to authentication JSON or ci_registry_auth_add.

For Harbor, use the registry hostname and a robot account with the required repository pull/push permissions. Store the robot secret when it is created; see Harbor robot accounts.

For Azure Container Registry, use its login server, a service-principal application ID, and its client secret. Grant the repository permissions required by the registry's RBAC or ABAC mode; see service-principal authentication.

Diagnose missing credentials​

If Runner cannot pull a private job image, check its DOCKER_AUTH_CONFIG, the exact registry hostname, and whether the ref can access the configured variable. If a command inside the job fails, check the merged configuration's registry keys and the credential's pull/push scope without printing secret values. The host-rules input for Renovate configures its dependency queries; it does not log Runner or OCI command-line clients in.