Container image security and the registry

Objective 4.3 · Security · 19% of the exam

Why this matters

Objective 1.4 explained what a container image is. This objective asks how to keep one safe, and the answer starts before anything runs: most container security problems are decided at build time and inherited unchanged into production.

The structural reason is the one from objective 1.4 — layers are immutable and additive. Whatever is in an image stays in it, including things a later layer appears to remove. So the image is the security boundary that matters, and the registry is the distribution point where a compromise would spread fastest.

The related risk is supply chain. A container image is largely software you did not write, pulled from somewhere you do not control, assembled by a build process that runs automatically. Every one of those is worth securing.

The lesson

Base image choice, minimal images, and the attack surface you inherit for free

An image starts from a base, and everything in that base is yours to defend whether you knew about it or not. A general-purpose operating system base brings a package manager, a shell, network utilities, an init system and hundreds of libraries — almost none of which your application needs, and all of which can be used by an attacker who gets code execution inside the container.

Prefer minimal base images, and understand the ladder:

  • A full distribution base. Familiar, easy to debug, largest surface.
  • A slim variant. The same distribution with much removed. A good default.
  • Alpine or similar small distributions. Very small, with a caveat: a different C library, which occasionally causes subtle incompatibilities.
  • Distroless images. Language runtime and dependencies only — no shell, no package manager. Very small surface, and an attacker with code execution finds almost no tooling to work with. Debugging requires a different approach, which is the real cost.
  • Scratch. Nothing at all, for statically-linked binaries. The smallest possible surface.

The security benefit is direct and measurable: fewer packages means fewer vulnerabilities to triage, which makes the process in objective 4.1 tractable. A team drowning in image findings is often one base-image change away from not being.

Two more build-time rules:

  • Pin the base by digest, not by a moving tag. latest means the image you built yesterday and the one you build today can differ with no change on your side — which is both a reproducibility problem and a supply-chain one.
  • Use multi-stage builds, so compilers, build tools, source code and credentials used during the build do not ship in the final image.

Scanning images for known vulnerabilities, and re-scanning images already published

Image scanning inspects the layers, enumerates the packages and application dependencies, and compares them against vulnerability databases.

Scan at the three points from objective 4.1:

  • At build, with results going to the team that built it.
  • As a promotion gate, failing the pipeline above an agreed severity — set sensibly, with a documented exception path, or it will be bypassed.
  • Continuously in the registry, which is the one people miss. An image scanned clean in March is not clean in June, because new vulnerabilities are disclosed against software that has not changed. Only re-scanning finds these, and it is what turns a point-in-time check into an ongoing control.

Two things scanning does not do, worth knowing so you do not over-trust it:

  • It finds known vulnerabilities in known packages. Software installed outside the package manager — a binary copied in — may be invisible to it.
  • It does not judge exposure. The prioritisation from objective 4.1 still applies: a vulnerability in a package the application never loads is different from one in its network-facing path.

The remediation is almost always rebuild rather than patch. Containers are immutable; you do not patch a running container, you build a new image and replace the workloads (objective 3.1). That makes image freshness the real control: an estate that rebuilds and redeploys weekly absorbs most vulnerability fixes without a vulnerability process even being invoked.

Image signing and verification, so the cluster runs what you built

Scanning tells you whether an image is safe. Signing tells you whether it is yours.

The threat is substitution: an attacker who can write to the registry, or intercept a pull, replaces a legitimate image with a modified one carrying the same tag. Nothing about the deployment looks unusual and the cluster runs the attacker's code.

Image signing addresses it cryptographically. The build process signs the image with a private key; the cluster verifies the signature before running it and refuses anything unsigned or signed by an unknown key. This is the supply chain control, and it is increasingly expected rather than optional.

The pieces:

  • Signing in the pipeline, using a key the pipeline holds and humans do not. Keyless signing tied to workload identity avoids managing a long-lived key at all.
  • Verification at admission — the cluster's admission controller checks the signature and rejects unverified images. Signing without enforced verification achieves nothing, and that gap is a good exam distractor.
  • Provenance and an SBOM. A software bill of materials lists what is in the image; attestations record how and from what source it was built. Together they let you answer "are we affected?" for a newly-disclosed library vulnerability in minutes rather than days — which is a genuinely valuable capability and increasingly a contractual requirement.

Related and important: tags are mutable, digests are not. A tag can be repointed at different content; a digest identifies exact bytes. Deploy by digest where integrity matters.

Private registries, access control and the public tag that silently changed

The registry stores and distributes images, and it deserves to be treated as production infrastructure.

  • Use a private registry for your own images. Anything pushed to a public registry is public, and images have repeatedly been found to contain credentials, internal hostnames and source code — pushed by accident, indexed immediately.
  • Authenticate both directions. Push rights only for the build pipeline; pull rights scoped to the environments that need them. A registry that allows anonymous pull of internal images is an information disclosure.
  • Separate registries or repositories per environment, so a development image cannot be pulled into production by mistake.
  • Apply retention. Old image versions accumulate storage cost (objective 3.1) and keep vulnerable images available to be deployed.
  • Log and monitor pushes and pulls. An unexpected push is a serious signal.

The public dependency problem deserves its own note, because it is the supply-chain risk most teams actually carry. Building FROM a public base means your build depends on a third party's content, availability and integrity. Public images have been abandoned, renamed, deleted, rate-limited and — occasionally — compromised. The defences:

  • Mirror public images into your own registry and build from the mirror. This gives you availability, immutability and a scanning point.
  • Pin by digest, so a repointed tag cannot change what you build.
  • Vet what you depend on: prefer official or verified publishers, and treat an arbitrary public image the way you would treat arbitrary code from a stranger — because that is what it is.

Secrets that must never be baked into a layer, and what to do instead

The rule from objective 1.4, stated as the security control it is: a secret placed in an image is in that image permanently, even if a later layer deletes it, because every layer remains readable to anyone who can pull the image.

The ways secrets get in:

  • Copied in during the build "temporarily" and deleted later.
  • Passed as a build argument, which is recorded in the image metadata.
  • Baked into a configuration file.
  • Present in source code copied in by a broad copy instruction — which is also how .git directories and local environment files end up in images.
  • Written into an environment variable in the image definition, where they are readable by anything that can inspect the image or the running container.

What to do instead:

  • Inject at run time from a secret manager, fetched by the workload's own identity — the same principle as objectives 2.4 and 4.2.
  • Mount secrets as files from the platform's secret mechanism rather than passing them as environment variables. Environment variables leak easily: they appear in process listings, crash dumps, logs and debug endpoints.
  • Use build-time secret mounts where the build genuinely needs a credential; these are designed not to persist in a layer.
  • Scan for secrets in images and in the repository, before push, so a mistake is caught rather than published.
  • Rotate immediately anything that reaches an image. Deleting the image is not sufficient — assume it was pulled.

The related discipline is keeping build context small: copy exactly what is needed rather than the whole working directory, and use an ignore file so local credentials, history and environment files cannot be swept in.

What to take into the exam

  • Minimal and distroless bases cut attack surface and vulnerability count. No shell means much less for an attacker to use.
  • Pin by digest; tags are mutable. Use multi-stage builds so build tooling does not ship.
  • Re-scan images already in the registry — clean in March is not clean in June. Remediation is rebuild, not patch; image freshness is the real control.
  • Signing proves origin; verification at admission is what enforces it. Signing without enforcement achieves nothing. SBOM and provenance answer "are we affected?" quickly.
  • Mirror public base images into a private registry and pin them.
  • A secret in any layer is in the image forever. Inject at run time, prefer mounted files over environment variables, and rotate anything exposed.

Practise what you just read

1. Why does a secret deleted in a later build instruction remain recoverable?

Select one

  1. Layers are additive and the earlier one persists
  2. The runtime reconstructs the full filesystem history when a container is created from the image for the first time
  3. Build caches retain the original instruction
  4. Registries store an unoptimised copy of each image
Show answer

A. The final filesystem view no longer shows the file and the layer containing it is still in the image. Anyone who can pull the image can extract it, which is why secrets are injected at run time instead.

2. What does a distroless base image remove that most aids an attacker?

Select one

  1. The package database
  2. The shell and package manager
  3. The init system, which would otherwise allow additional processes to be started alongside the main application
  4. The certificate trust store
Show answer

B. An attacker with code execution finds almost no tooling to work with. The cost is that debugging requires a different approach, which is the genuine trade rather than a theoretical one.

3. Signing is configured but the cluster runs unsigned images anyway. What is missing?

Select one

  1. A trusted certificate authority for the signing key
  2. A private registry to hold signed images
  3. Verification enforced at admission
  4. A policy requiring that every image be re-signed whenever it is promoted from one environment to the next
Show answer

C. Signing without enforced verification achieves nothing, because nothing checks the signature before running the workload. The admission controller rejecting unverified images is what makes the control real.

10 more questions on this objective are part of the full course.

Practise the full question bank in the exam simulator

Hands-on labs

All hands-on labs

This is an independent study companion for CompTIA Cloud+ CV0-004 and is not produced by or endorsed by CompTIA.