Rules / GL066
GL066 Hardcoded registry credentials in DOCKER_AUTH_CONFIG
Severity: error
OWASP: CICD-SEC-6 – Insufficient Credential Hygiene
CWE: CWE-798 – Use of Hard-coded Credentials
Risk
GitLab authenticates to private container registries via the DOCKER_AUTH_CONFIG variable, a JSON document holding base64-encoded registry credentials. When it is hardcoded in .gitlab-ci.yml instead of stored as a masked/protected CI/CD variable, the credentials are committed to the repository in a plaintext-recoverable form — the auth field is just base64, not encryption, so anyone with read access to the repo (or its history) can decode user:password.
What glsec checks
glsec flags any DOCKER_AUTH_CONFIG entry in a variables: block (top-level, default:, or per-job) whose value is an inline credential document — i.e. it contains an "auths" / "auth" JSON key.
variables:
DOCKER_AUTH_CONFIG: '{"auths":{"registry.example.com":{"auth":"dXNlcjpwYXNz"}}}' # flagged
A whole-value variable reference is the safe form and is not flagged:
variables:
DOCKER_AUTH_CONFIG: $REGISTRY_AUTH # not flagged
Trigger example
variables:
DOCKER_AUTH_CONFIG: '{"auths":{"registry.example.com":{"auth":"dXNlcjpwYXNz"}}}'
build:
image: registry.example.com/builder:1.0.0
script:
- docker build -t registry.example.com/app:1.0.0 .
Safe alternative
Define DOCKER_AUTH_CONFIG as a masked, protected CI/CD variable in Settings → CI/CD → Variables, and reference it (or simply let the runner pick it up) rather than committing the JSON:
# Settings → CI/CD → Variables: DOCKER_AUTH_CONFIG = {"auths":{...}} (masked, protected)
build:
image: registry.example.com/builder:1.0.0
script:
- docker build -t registry.example.com/app:1.0.0 .
Why this matters
Unlike a masked CI/CD variable — which GitLab keeps out of the repository, redacts in job logs, and can restrict to protected branches — a committed DOCKER_AUTH_CONFIG lives in git history forever. Rotating the credential requires a force-rewrite of history, and any fork or clone made before rotation retains the working secret. GL006 catches generic hardcoded secrets but does not recognise this structured registry-auth form.
Documentation for glsec 1.23.0. Source of this page · Rule implementation