Safeguard
Security Guides•

What should a CI runner image never contain?

A CI runner image is copied to every job. Keep credentials, registry logins, source code, sudo and unused tools out of it. Here is the checklist.

Safeguard Security Team
3 min read

A runner image should never contain credentials, saved registry logins, SSH keys, copies of private source code, passwordless sudo, or tools no pipeline uses. Every job starts from the image, so anything inside it is available to every job and to anyone who can pull the image.

Why the image is a high value target

With ephemeral runners, the image replaces the long-lived server. It is pulled by every job, often from a registry many people can read. A secret placed inside is effectively shared with all of them, and it stays in the image layers even if a later step deletes the file.

GitLab's runner guidance gives a concrete example of the wrong pattern: credentials kept in the runner host's Docker configuration files are available to every job the runner executes, which is why it advises against running docker login as the runner user on shared runners.

Do not include

ItemWhy notWhat to do instead
Cloud keys or API tokensShared by every jobInject per job, short lived
Registry loginsUsable by any jobPer job token
SSH private keysReads as full accessDeploy keys per repository, issued at runtime
Source of private projectsLeaks code to anyone who pullsCheck out at job time with scoped access
Passwordless sudoEasy privilege stepRemove sudo, fix ownership at build
Package manager caches with credentialsConfig files can hold tokensClean in the same layer
Unused compilers and debug toolsExtra attack surfaceSplit images by need
Shell history and temp filesCan hold pasted secretsBuild from clean definition

How to check an image

  1. List the layers and read the build commands, looking for copied files and environment settings.
  2. Search the filesystem for key files, config directories and token patterns.
  3. Review environment variables set at build and run time.
  4. Run a dependency and image scan, and read the inventory for tools nobody expects.
  5. Compare against the written image definition. Anything present that the definition does not explain is a finding.

Remember the limit of scanning: image scanners report known vulnerabilities and inventory, and are not a guarantee that no secret is present. Review build steps as well.

Keep it small and specific

Several smaller images with clear purposes are easier to review than one image with everything. The language build image does not need the deploy CLI, and the deploy image does not need compilers.

Keep it current

An image that is clean today ages. Rebuild on a schedule and rescan. See how often to rebuild runner images. For build time secrets in particular, see Docker build secrets without leaking into layers.

Quick check

If I delete a secret in a later layer, is it gone?

No. Earlier layers keep it and anyone who can pull the image can extract it. Rebuild without ever adding it.

Can the image hold a public CA bundle or config?

Yes. Public, non-secret configuration is fine. Keep anything that grants access out.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.