Challenge 3: Explain the Registry Authentication Step — Possible Solution ==================================================================== # CI pipeline step echo "$REGISTRY_PASSWORD" | docker login registry.example.com -u "$REGISTRY_USER" --password-stdin docker build --cache-from myapp/api:latest -t myapp/api:$GIT_SHA -t myapp/api:latest . trivy image --exit-code 1 --severity CRITICAL myapp/api:$GIT_SHA docker push myapp/api:$GIT_SHA docker push myapp/api:latest WHY THIS MUST NEVER HARDCODE CREDENTIALS: $REGISTRY_USER and $REGISTRY_PASSWORD are references to CI secrets configured separately in the CI platform's own secrets store — the actual credential values never appear as literal text anywhere in this pipeline file. If the password were instead written directly (e.g. docker login -u admin -p Sup3rSecret), anyone with read access to the pipeline configuration — including its full Git history, since pipeline files are typically version-controlled — would have the real registry credentials in plain sight, permanently and irrevocably, the same way a credential committed to Git or baked into a Dockerfile layer (Chapter 6) is compromised the moment it exists in that form. This is exactly Chapter 7's own guidance applied directly to this capstone's CI step: registry credentials are secrets like any other, and the discipline of loading them from a secrets store at runtime — never hardcoding them into a file that gets committed and shared — applies here with no exception, regardless of how convenient hardcoding might seem during initial setup.