Safeguard
Product•

Fix Vulnerabilities in Container Base Images with Safeguard

Split base image findings from your own layers, rebuild on a fresh or better base, prove the fix with a Safeguard scan in CI, then roll it out everywhere.

Safeguard Security Team
38 min read

You fix a vulnerability in a container base image by rebuilding, not by patching the running container. Find out which findings come from the image in your FROM line, move that line to a fresher digest, a newer tag or a smaller base, rebuild without stale cache, and let a Safeguard scan in CI prove the count went down before you promote. Container image scanning is part of Safeguard SCA, which is GA.

This post is about the fixing half of the job. If you want the scanning half first, the published post on scanning container images in Safeguard covers how Safeguard reads image layers and gets images scanned. Here we assume you already have a long list of OS package CVEs and need to make it shorter in a way that stays short.

Key takeaways

  • Base image fixes are rebuilds. NIST SP 800-190 says container updates "must be made upstream in the images themselves, which are then redeployed". Running a package upgrade inside a live container does not fix the image.
  • Split the findings first. Scan the exact base reference from your FROM line on its own and compare it with your built image. Findings in both belong to the base owner. Findings only in your image belong to your Dockerfile or your application. Container image scanning is part of SCA (GA).
  • Four fixes cover almost every base image finding. Rebuild against the current digest of the same tag, move to a newer tag, move to a newer distribution release, or move to a smaller base. Pick the smallest change that clears the findings you care about.
  • Prove each fix with a scan. The Safeguard CLI (GA) scans a local image before you push. The CI step (GA) scans the image your pipeline built, records one version per environment and tag, and can fail the build with --wait --fail-on. Policies and gates (GA) decide what may be promoted.
  • Keep it fixed. A registry integration (part of ESSCM, GA) keeps the image under continuous scanning, so a new CVE in a base you fixed last month shows up without anyone remembering to rescan. Vulnerability management with EPSS and CISA KEV (GA) tells you which new findings need a rebuild this week.
  • Application dependencies are fixed in the repository. Autonomous remediation (GA) can open fix pull requests for them. It ships switched off, with every category set to Manual.
  • Self-healing containers is generally available. Safeguard's docs describe a detect, plan, rebuild and promote loop with an advisory mode and autonomous modes. Run the manual process in this post first, then start it in advisory mode.
  • Choose bases with evidence. Gold Open Source (GA, free, no login) has a Container Images directory at gold.safeguard.sh/directory/images, and its CVE pages show affected and fixed versions. Shortlist there, then scan your candidates with Safeguard before you switch.

Why base image vulnerabilities need a different fix

Application fixes follow one pattern: bump a version in a manifest, update the lockfile, merge. Base image findings do not, for three reasons.

You did not choose most of the packages. A general purpose base image carries a C library, a TLS library, compression libraries, certificate bundles, a shell, core utilities and a package manager. Your service may use three of them. Every one of them can carry a CVE, and every one of them shows up in your scan.

The fix is published by someone else, on their schedule. The distribution patches the package. The image publisher rebuilds the base image tag with the patched package. Only then can you rebuild on it. You control the last step, not the first two.

The image is frozen at build time. Once an image is built, nothing inside it changes. NIST SP 800-190, the Application Container Security Guide, puts it plainly in section 3.1.1: an image built with fully up to date components may be clean for days or weeks, but at some point vulnerabilities will be found in its components and it will no longer be up to date. Unlike servers patched in place, the guide says, container updates must be made in the images themselves, which are then redeployed.

That last point is the whole method. The unit of fixing is the image build, and the unit of deployment is the image digest. Everything in this post is about making that rebuild cheap, safe and provable.

What the standards ask for

You do not need a regulation to tell you to patch, but it helps to know which documents your auditors and customers will cite.

SourceWhat it says about image fixesHow it shapes your process
NIST SP 800-190, section 3.1.1Images go stale as new CVEs are found; updates are made in the image and redeployedRebuild and redeploy is the fix, not in place patching
NIST SP 800-190, section 4.1.1Tools need visibility into all layers, not just the base, and quality gates at each stageScan base and app layers, gate promotion
NIST SP 800-190, section 4.1.2Use base layers from trusted sources only, update base layers frequently, prefer minimal basesChoose bases deliberately and rebuild on a schedule
NIST SP 800-190, section 4.2.2Prune stale images from registries and deploy immutable, versioned namesRetire old images and pin what you deploy
NIST SP 800-218 (SSDF)Practices for using well secured third party components and responding to vulnerabilitiesTreat the base image as a third party component with an owner
CISA KEV catalogLists vulnerabilities known to be exploited in the wildRebuild first for KEV listed findings
FIRST EPSSEstimates the probability that a CVE will be exploitedRank the rest of the queue
CISA BOD 26-04 (10 June 2026)Risk based timelines for federal agencies; it superseded BOD 22-01If you sell to US federal agencies, map your rebuild cadence to it

BOD 22-01 and its fixed deadlines are history; BOD 26-04 replaced them with risk based timelines. None of these documents name a base image. They tell you to know what is in it, keep it current and prove both.

How image layers decide who owns a fix

The OCI image specification describes an image manifest as an ordered list of layers, with the base layer first. Each later layer is a change set applied on top. Your Dockerfile maps onto that list:

  • The FROM line brings in every layer of the base image.
  • Each RUN, COPY or ADD instruction adds a layer on top.
  • In a multi-stage build, only the final stage's layers end up in the image you ship. Docker's multi-stage build documentation describes using several FROM statements and copying only the artifacts you need into the last stage.

That structure tells you who owns each finding:

Where the vulnerable package came fromTypical examplesWho usually owns the fixThe fix
The base imageC library, TLS library, compression libraries, certificate bundle, shell utilitiesPlatform team or base image ownerRebuild on a fresh digest, a newer tag, a newer distribution release or a smaller base
An OS package your Dockerfile installsA download tool, an image processing library, a database clientThe service teamRemove it, move it to a build stage, or upgrade it in the same RUN line
An application dependencynpm, PyPI, Maven, Go, Cargo, NuGet, Composer or Bundler packagesThe service teamFix the manifest and lockfile in the repository, then rebuild
A compiled binary copied inA Go or Rust binary, a vendored toolWhoever builds that binaryRebuild the binary with fixed dependencies

Safeguard's container FAQ lists what it scans in an image: OS packages from apt, yum and apk, application dependencies, and compiled Go and Rust binaries. That covers every row in the table. What the scan does not do for you is decide whose row a finding belongs to. That is the next section.

Step 1: split base image findings from your own

Before you change anything, find out how many of your findings you can clear by changing one line. This uses only documented commands.

  1. Find the exact base reference. Read the FROM line of the final stage of your Dockerfile. If it names a tag, look up the digest that tag pointed to when your image was built. Safeguard's container FAQ supports both tag references such as nginx:1.21 and digest references such as nginx@sha256:..., and recommends digests for production scanning because a digest always names the same image.

  2. Scan the base image on its own. From the Safeguard CLI (GA):

    safeguard scan --image node@sha256:<digest-from-your-build>
    

    Or connect the base image in the app under Integrations as a public or private container image, so it is scanned continuously in its own right. The FAQ's flow for a public image is: go to Integrations, select Container Image, choose the Public tab, enter the image reference and click Connect.

  3. Scan your built image. Either locally, as the FAQ shows:

    docker build -t myapp:test .
    safeguard scan --image myapp:test
    

    or in CI, with the step described later in this post.

  4. Compare the two results. A finding on the same package and version in both scans is inherited from the base. A finding that appears only in your image came from your own layers.

  5. Cross check the leftovers with your repository scan. If a package and version in your image also appears in your repository's SCA results, it is an application dependency with a lockfile to fix. If it appears only in the image, it came from an OS package you installed or a binary you copied in.

The container FAQ explains why an image shows more vulnerabilities than its source code: base OS packages, build dependencies, system libraries and outdated base images. The comparison turns "we have a lot of findings" into "one line in our Dockerfile owns most of them", which is an easier conversation with whoever owns that line.

Rank before you rebuild

Not every base image finding needs a rebuild today. Safeguard's vulnerability management (GA) attaches CVSS, EPSS and CISA KEV status to each finding and groups findings as Critical, High, Medium, Low and Exploitable. Use that to decide urgency:

  • KEV listed, fix available in a newer base: rebuild now. CISA's catalog exists for exactly this case.
  • High EPSS, fix available: rebuild in the current cycle.
  • Low EPSS, fix available: let the scheduled rebuild pick it up.
  • No fix available yet: record an exception with an expiry date and watch for the fixed revision.

Reachability analysis (GA) ranks application dependency findings by whether your code calls the vulnerable path. The published post on prioritising vulnerabilities with reachability, EPSS and KEV explains how those signals combine. Safeguard's reachability docs list support by programming language, not by OS package manager, so rank inherited OS packages by KEV, EPSS and whether your process actually uses the package.

Step 2: pick the smallest base change that clears the findings

There are four ways to change a base image. They differ in how much can break and how many findings they clear.

Fix A: the same tag, a newer digest

Base image publishers rebuild their tags when the distribution ships patched packages. A tag such as 20-alpine or bookworm-slim keeps its name while the image behind it changes. If your last build pulled that tag three weeks ago, a fresh pull today may already contain the fixes.

What to do:

  • Rebuild with a fresh pull of the base and without the layer cache. Docker's build best practices page has sections titled "Rebuild your images often", "Use --pull to get fresh base images" and "Use --no-cache for clean builds" for this reason. A cached build can happily reuse a three week old base layer.
  • If you pin by digest, which you should, update the digest in your FROM line to the one the tag points to now.
  • Scan the new base digest on its own with safeguard scan --image and compare it with the old one before you rebuild your service on it.

Risk: low. The distribution's stable branch changes as little as possible between revisions. Debian's security FAQ explains that it backports security fixes into the version shipped in a stable release instead of moving to a new upstream version, so that "things will not change or break unexpectedly". The same reasoning applies to most stable distribution branches.

Fix B: a newer tag in the same line

Sometimes the fix lives in a newer minor version of the runtime image, for example moving from one point release of a language runtime image to the next. The OS layer may stay the same while the runtime binaries change.

Update the tag and digest, rebuild and rerun your tests. Risk: moderate, since the runtime itself changes. Read its release notes.

Fix C: a newer distribution release

Distribution releases reach end of life. After that, packages in the old release stop getting security fixes, and every new CVE in them stays open forever. If your Safeguard scan shows a growing list of findings with no fixed version, and the base is on an old distribution release, the fix is a move to a supported release.

What to do: change the FROM line to the same runtime on the newer distribution, rebuild, and test anything that links against system libraries. Native extensions, database drivers and image processing libraries are the usual sources of breakage.

Risk: moderate to high. Plan it as a small migration with its own pull request and test run.

Fix D: a smaller base

If most of your findings sit in packages your service never uses, the most durable fix is to stop shipping those packages. Safeguard's container FAQ recommends minimal base images, gives Alpine and distroless as examples, and recommends official images where possible. NIST SP 800-190 section 4.1.2 makes the same point: select base layers from minimal technologies to reduce attack surface.

The distroless project describes its images as containing only an application and its runtime dependencies, without package managers or shells. Safeguard's FAQ confirms distroless images can be scanned and adds a fair warning: they have fewer packages but may still have vulnerabilities in the components they include.

What to do: use a multi-stage build. Compile or install in a full build stage, then copy only the artifacts into a minimal final stage. Rebuild and run your full test suite, including startup and health checks, because a missing shared library or certificate bundle only shows up at runtime.

Risk: highest of the four. Debugging changes too, since there may be no shell in the final image. The payoff is that the next six months of base image CVEs mostly never reach you.

Which fix to choose

Your situationStart withWhy
Findings have fixed versions and your base tag is currentFix A, fresh digestThe publisher has probably already rebuilt the tag
The fixed version is only in a newer runtime releaseFix B, newer tagThe runtime binaries carry the fix
Findings pile up with no fixed version and the distribution release is oldFix C, newer distribution releaseThe old release may no longer get fixes
Most findings are in packages your service never usesFix D, smaller baseRemoves the packages instead of patching them
Findings appear only in your image, not in the baseNot a base fixEdit your Dockerfile RUN lines or your lockfile
A KEV listed CVE has no fix in any base you could useAn exception with an expiry, plus compensating controlsRecord the decision and revisit it on a date

A useful rule: do Fix A on a schedule for every image. It keeps the gap between "the publisher fixed it" and "you shipped it" short, and turns Fix B, C and D into planned work.

Step 3: choose a base with Gold Open Source

When you need a new base, either for Fix C or Fix D or for a new service, start with evidence rather than habit. Gold Open Source is Safeguard's free public directory. It needs no login. The offering files list a Container Images directory alongside the Gold Certified Packages directory, and CVE intelligence with CVSS, EPSS, CISA KEV status and affected and fixed versions. Gold Open Source is GA.

What the Container Images page shows

The Container Images directory lives at gold.safeguard.sh/directory/images. It sits in the site's "Explore Gold" menu next to Packages, Gold Packages, AI Models, MCP Servers and Agent Skills. The page describes itself as a place to find Docker and OCI container images scanned for CVEs and license issues, with full vulnerability reports and verification status for production ready base images.

One honest caveat about this section. We read the page with a plain HTTP fetch while writing, and that returns the page shell and its description. The image list itself loads in your browser. So we are not going to describe columns, filters or counts we could not see. Open the page, look at what each listing shows for the images you are considering, and treat the listing as a starting point, not a verdict.

A shortlist method that works with any listing

  1. Write down your constraints first. Runtime and version, C library (glibc or musl), architecture, whether you need a shell or package manager at runtime, and how long the distribution release is supported.
  2. Shortlist two or three candidate bases from the Gold Container Images directory and from the runtime's official images.
  3. Look up your worst current CVEs on Gold Open Source. Its CVE pages show affected and fixed versions. If a candidate's package version falls in the fixed range, that candidate clears the finding. The published post on using Gold Open Source in your workflow covers the lookup, the free API and badges.
  4. Scan each candidate yourself. Run safeguard scan --image against each candidate by digest. This is the step that matters, because it uses the same scanner and data you will be judged by later.
  5. Build your service on the best candidate in a branch. Scan the built image, run your tests, and compare the result with your current image.
  6. Record the decision. Note the candidate digests, the counts before and after, and why you chose the one you did. That record answers the auditor question "why this base?" without a meeting.

What to compare between candidates

QuestionWhere to lookWhat good looks like
How many known CVEs does the candidate carry today?safeguard scan --image on the candidate digestFewer, and few or none that are KEV listed
Are the remaining CVEs fixable?Fixed version field in the scan; Gold Open Source CVE pagesFixed versions exist, or the package is unused
How many packages does it ship?The scan's SBOM for the candidateOnly what your service needs at runtime
Is the distribution release supported?The distribution's own release and security pagesSupported well past your next planned migration
Does your service still work?Your test suite against an image built on the candidateTests and startup checks pass
Is the reference pinned?Your Dockerfile FROM lineA digest, with the tag kept as a comment for humans

Step 4: rebuild and prove the fix in CI

Once you have chosen the change, make it in a pull request and let the pipeline prove it. This is the flow from Safeguard's CI/CD container images docs. The CLI and the CI step are GA.

  1. Update the FROM line. Change the tag, the digest or both. A digest pinned base keeps the build repeatable:

    # node 20 on Alpine, digest updated after rescan
    FROM node@sha256:<new-digest>
    
  2. Get a CI key. Create a key with scans:trigger and scans:read. Admins create one in the Set up CI/CD sheet or under Settings › Developer. Store it in your CI as SAFEGUARD_API_KEY.

  3. Add the scan step after the build. The docs show this GitHub Actions example:

    - name: Build
      run: docker build -t "ghcr.io/acme/api:${{ github.sha }}" .
    - name: Safeguard image scan (prod)
      env:
        SAFEGUARD_API_KEY: ${{ secrets.SAFEGUARD_API_KEY }}
        SAFEGUARD_INSTALL_DIR: ${{ runner.temp }}/safeguard-bin
        IMAGE: ghcr.io/acme/api:${{ github.sha }}
      run: |
        set -eu
        curl -fsSL https://cli.safeguard.sh/install | bash
        "$SAFEGUARD_INSTALL_DIR/safeguard" ci scan --image "$IMAGE" --environment prod --wait --fail-on critical
    

    The docs say the scan runs on the runner and only the results leave it. The image is read from the local Docker daemon when the step runs on the machine that built it, or from a registry using SAFEGUARD_REGISTRY_USERNAME and SAFEGUARD_REGISTRY_PASSWORD.

  4. Use one step per environment. Each step gets its own --environment, and each environment's build is recorded as its own version, for example prod-1.4.2 or staging-1.4.2. You can fail on critical findings in production and set no --fail-on in development. With --wait, --fail-on accepts critical, high, medium or low.

  5. Compare before and after. The image is recorded under its repository, one version per environment and tag, so the version built from your pull request sits next to the version currently in production. The difference is your evidence that the base change worked.

  6. Gate promotion in the platform. Policies and gates (GA) are evaluated in Safeguard. The published post on plain English security policies to release gates walks through creating one. A gate that blocks KEV listed criticals in production images is a sensible first rule.

  7. Merge, build, push, deploy. Deploy by digest, not by a mutable tag, so the image you scanned is the image that runs. NIST SP 800-190 section 4.2.2 recommends deploying immutable, specific versions rather than trusting a "latest" label.

The published post on tracking container images per environment goes deeper on environment names, registry credentials and fail thresholds.

What a good result looks like

You are looking for three things in the comparison:

  • Inherited findings dropped. The findings you attributed to the base in Step 1 are gone or reduced.
  • Nothing new and severe arrived. A newer base can bring newer packages with their own CVEs. Check the new findings, not just the totals.
  • Your own findings are unchanged. Findings from your RUN lines and your application dependencies should be the same as before. If they changed, something else changed in the build.

If the count did not move, suspect a cached base layer, an edited builder stage while the final stage keeps the old base, or a tag the publisher has not rebuilt yet.

Step 5: fix what is left in your own layers

Once the base is current, the remaining findings are yours. They come in three kinds, and each has its own fix.

OS packages your Dockerfile installs

If a package appears in your image but not in your base, your Dockerfile installed it. In order of preference:

  1. Remove it if the service does not need it at runtime. Build tools, download tools and version control clients often survive from a build step. Safeguard's container FAQ lists "Don't include build tools in final image (multi-stage builds)" and "Remove package manager caches" under image hygiene.
  2. Move it to a build stage so it never reaches the final image.
  3. Upgrade it in the same RUN line that installs it, then rebuild. Putting the upgrade in a separate, earlier layer that the cache reuses defeats the point.

The published post on running apt upgrade inside a container versus rebuilding the image covers the trade offs in more detail.

Application dependencies

Application packages inside the image are the same packages your repository scan sees. Fix them in the repository, then rebuild. Safeguard's autonomous remediation (GA) can open a fix pull request that moves the dependency to a safe version, on one repository or in bulk with one pull request per repository, with breaking change detection. It ships switched off, with every category set to Manual, so your team decides what runs on its own. The published post on autonomous remediation in Safeguard explains the categories and strategies.

Compiled binaries

If a Go or Rust binary in your image carries a vulnerable library, the fix is in that binary's build. Update its dependencies, rebuild the binary, then rebuild the image. If the binary comes from a third party, check whether a newer release exists and pin to it.

Step 6: keep it fixed

A base image you fixed today will have new CVEs within weeks. The goal is not a clean scan once; it is a short gap every time.

Continuous scanning of the images you run

Connect your registry under Integrations in the app (part of ESSCM, GA). Safeguard's container FAQ recommends scanning images in CI before pushing, scanning production images daily, using webhooks for automatic scanning on push, and setting up alerts for new critical vulnerabilities. The registry integration is how a new CVE in a base you already shipped reaches you without a fresh build.

A rebuild cadence

Use a calendar trigger in your CI to rebuild every service image on a fresh pull of its base, scan it with the CI step, and open a pull request when the base digest changed. Weekly is common. The CI step's per environment versions make it easy to see when a rebuild cleared findings.

Docker's best practices page has a section titled "Pin base image versions" alongside "Rebuild your images often". Those two pieces of advice sound like they conflict. They do not: pin so that every build is repeatable, and rebuild on a schedule so that the pin moves forward deliberately. The published post on pinning base images by digest for repeatable rebuilds shows the mechanics.

Roll out across many services

When a base image fix lands, many services usually need it. Treat the base as a product:

  • Publish an internal base image that your services inherit from, owned by the platform team.
  • Rebuild the internal base first, scan it, then trigger downstream rebuilds.
  • Track which services are still on the old digest. Keep the base digest in your build metadata, and use each service's per environment versions in Safeguard to confirm the inherited findings cleared.

The published post on rolling out a patched base image across many services covers this pattern in depth.

Retire stale images

NIST SP 800-190 section 4.2.2 recommends pruning registries of unsafe, vulnerable images that should no longer be used. Forgotten jobs and rollbacks pull old images, so once a fixed version is stable, remove or quarantine the old tags.

Step 7: when there is no fix yet

OS package CVEs often have no fixed revision in your distribution release, or the distribution has decided the issue does not warrant a fix in stable. What to do:

  1. Check that the finding is real for your build. Distributions often backport fixes without changing the upstream version number. Debian's security FAQ answers the question "the version number indicates that I am still running a vulnerable version" by explaining the backport policy and pointing you at the package changelog and the security tracker. Compare the exact package revision, not just the upstream version.
  2. Check whether another base fixes it. Look up the CVE on Gold Open Source to see affected and fixed versions, and scan an alternative base.
  3. Record an exception with an expiry. Accept the risk for a fixed period with a business justification, so the decision comes back for review when the distribution's position may have changed. The published post on writing an exception record for a base image vulnerability with no fix has a template.
  4. Say so in a machine readable way. If customers will ask, a VEX statement says whether the CVE affects your product. CSAF and VEX upload is GA in Safeguard. The published post on ingesting and sharing VEX and CSAF in Safeguard covers that flow.
  5. Remove the package if you can. A finding in a package you do not need is a finding you can delete. This is often the fastest fix of all.

For open source components where upstream has no fix, the published post on Safeguard fork and patch explains that flow.

Self-healing containers

Safeguard's docs describe self-healing containers as automation for the rebuild chain in this post. It is generally available. Here is what the docs describe:

  • A four step loop. Detect a new CVE in one of your images, plan a patch, rebuild the image with your existing tests, and promote it if tests and guardrails pass.
  • Three modes. Advisory, where Safeguard files a pull request against your Dockerfile repository or Kubernetes manifest repository and humans review and merge; autonomous with promotion gated, where it rebuilds and promotes to a staging tag and a human approves production; and autonomous continuous, where it promotes to production with policies still applied.
  • Base image healing. For a FROM node:20-alpine style line, the docs describe rebuilding against the latest digest of the same tag.
  • Rollback. The docs say the previous image digest is preserved so a heal can be reversed.

How to roll it out: run the manual process in this post first, start in advisory mode, where a pull request against your Dockerfile is easy to review or reject, and confirm with Safeguard which registries, CI systems and orchestrators it supports for your account.

Requirement, what Safeguard does, and what you still own

RequirementWhat Safeguard doesWhat you still own
Visibility into vulnerabilities at all image layers (NIST SP 800-190, 4.1.1)Scans OS packages, application dependencies and compiled binaries in images (SCA, GA)Scanning the base and the built image so you can split ownership
Quality gates at each stage (NIST SP 800-190, 4.1.1)--wait --fail-on in the CI step (GA); policies and gates in the platform (GA)Setting thresholds per environment and running the exception process
Frequent base layer updates from trusted, minimal sources (NIST SP 800-190, 4.1.2)Scans candidate bases on demand with the CLI (GA); Gold Open Source Container Images directory and CVE lookups (GA, free)Choosing the base, migrating to it and testing
Updates made in the image and redeployed (NIST SP 800-190, 3.1.1)Records each rebuilt version per environment so you can compare; self-healing containers can automate the rebuildRebuilding, deploying and retiring old containers
Immutable, versioned deployments and pruned registries (NIST SP 800-190, 4.2.2)Supports digest references for scanning; records image versions per environment and tagDeploying by digest and pruning old tags
Prioritise exploited vulnerabilities (CISA KEV, FIRST EPSS)KEV and EPSS on every finding (vulnerability management, GA)Response timelines, including BOD 26-04 if you are a federal agency
Explain unfixed findings to customersCSAF and VEX upload (GA); SBOM export in SPDX and CycloneDX (GA)Writing accurate VEX justifications

What Safeguard does not do

  • It does not patch running containers. Every fix in this post is a rebuild and redeploy. Safeguard scans, records and gates; your pipeline builds and your orchestrator deploys.
  • It does not change your base image by default. Autonomous remediation opens pull requests for application dependencies and ships switched off. Self-healing containers can rebuild images; nothing in this post depends on it.
  • It does not pick your base image for you. Gold Open Source and the CLI give you data to compare candidates. The decision about glibc or musl, shell or no shell, and which distribution release to support is yours.
  • It does not publish distribution fixes. If a distribution has no fixed revision for a package, no scanner can conjure one. You can switch base, remove the package, or record an exception.
  • It does not split findings by layer in a single view that we could confirm. The method in Step 1 uses two scans and a comparison. Do not plan triage around a per layer column unless you see one in your account.
  • It does not make reachability decisions for OS packages. The reachability docs list programming languages, not OS package managers.
  • It does not test your service on the new base. The CI step scans the image. Your own test suite has to prove the service still works.

Common mistakes

Running a package upgrade in the running container. It changes one container until it restarts and leaves the image, and every other replica, unchanged. NIST SP 800-190 is explicit that updates are made in the image and redeployed.

Rebuilding with a cached base layer. The build finishes in seconds and nothing changes. Pull the base fresh and skip the cache on scheduled rebuilds.

Changing the wrong FROM line. In a multi-stage Dockerfile, only the final stage ships. Updating the builder stage's base clears nothing in the runtime image.

Treating latest as fresh. NIST SP 800-190 warns that a "latest" tag is only a label, not a guarantee of freshness. Pin by digest and move the pin on purpose.

Chasing upstream version numbers on a backporting distribution. The upstream version may look old while the package revision includes the fix. Compare exact revisions against the distribution's advisory.

Switching to a minimal base without testing at runtime. Missing certificate bundles, time zone data or shared libraries fail at startup or on the first outbound call, not at build time.

Fixing app dependencies in the image. An upgrade step in the Dockerfile for a library your lockfile controls creates drift. Fix the lockfile and rebuild.

Leaving old images in the registry. Rollbacks and forgotten jobs pull them. Prune or quarantine once the fixed version is stable.

Accepting risk without an expiry. An exception with no review date becomes permanent. Set a date every time.

FAQ

How do I fix vulnerabilities in a Docker base image?

Rebuild your image on a fresher or better base. Start by pulling the current digest of the same tag and rebuilding without cache. If the fix is only in a newer runtime or distribution release, move the tag. If most findings are in packages you never use, move to a smaller base with a multi-stage build. Scan the result with Safeguard in CI before you promote it.

How do I know which vulnerabilities come from the base image?

Scan the exact base reference from your FROM line on its own with safeguard scan --image, scan your built image, and compare. Findings in both are inherited from the base. Findings only in your image come from your Dockerfile instructions or your application dependencies.

Should I run apt-get upgrade in my Dockerfile?

Prefer a fresh base. If you must upgrade packages, do it in the same RUN line that installs them and rebuild regularly, so the cache does not freeze an old upgrade. Never run upgrades in a running container as a fix, because the image stays vulnerable.

Why does my image still show a CVE after I rebuilt it?

The usual causes are a cached base layer, a publisher that has not rebuilt the tag yet, the wrong FROM line in a multi-stage build, or a distribution that has not shipped a fix. Rebuild with a fresh pull and no cache, check the final stage's base, and compare the base digest's scan before and after.

Are distroless or Alpine images free of vulnerabilities?

No. Safeguard's container FAQ recommends minimal bases such as Alpine and distroless and says distroless images can still have vulnerabilities in the components they include. Fewer packages means fewer findings and fewer future findings, not zero.

How often should I rebuild container images?

Often enough that published fixes reach production quickly. Weekly scheduled rebuilds on a fresh pull of the base are a common baseline, with immediate rebuilds for KEV listed findings. Safeguard's FAQ recommends scanning production images daily so you know when a rebuild is due.

Can Safeguard rebuild my images automatically?

Self-healing containers can detect, plan, rebuild and promote images. Autonomous remediation, which opens fix pull requests for application dependencies, is GA but ships switched off with every category set to Manual. Neither replaces a pinned base and a rebuild process you understand.

How do I choose a secure base image?

Write down your runtime, C library and support window. Shortlist candidates from the Gold Open Source Container Images directory and the runtime's official images. Scan each candidate by digest with Safeguard, build your service on the best one in a branch, run your tests, and record why you chose it.

What should I do when a base image CVE has no fix?

Confirm the finding against the distribution's advisory, since backported fixes can hide behind old version numbers. Check whether another base fixes it. If not, record an exception with an expiry date, and publish a VEX statement if customers need to know whether it affects them.

Try it on your own images

Install the Safeguard CLI from safeguard.sh/download, scan your current image and the base in its FROM line, and see how much of the list one line owns. The Safeguard docs cover the CLI, the CI container step and registry integrations.

The rest of this post is the standard way Safeguard closes the gap between a published fix and a deployed one, and what happens when there is no fix yet. For container base images, the same split applies: rebuild when a fixed base exists, and use the options below for the open source components you build and ship when it does not.

Fix it without waiting for upstream

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation categories include dependencies, licenses, security posture and findings, and each one is set separately. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.

3. Gold Registry: start from components that are already fixed

Gold Registry provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. Ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingSafeguard policies and gates in CI
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

The first demo is a real Safeguard CLI session. It installs the CLI, opens the interactive terminal, and asks the assistant to fix a lodash CVE in a repository: it reads the finding and advisory, asks before any command that changes something, edits package.json to the fixed version, runs the install and tests, prints a summary and pushes nothing. That is the flow for the application dependency findings left in your image after the base is current: fix the lockfile in the repository, then rebuild the image.

Click through it at your own pace, or open it full screen.

The second demo sets up the local runner on your own machine, approves it with its device code, and then scans from the terminal. If you want to compare candidate base images on hardware you control before you change a FROM line, this is the setup you would start from.

Click through it at your own pace, or open it full screen.

Quick check

Your image has 120 findings. A scan of the exact base digest in your FROM line shows 95 of them. What is the fastest first move?

Rebuild on a fresh pull of the same tag without the layer cache, update the pinned digest, and scan the new base on its own first. If the publisher has rebuilt the tag, many of the 95 inherited findings clear with a one line change. Then deal with the 25 that belong to your own layers.

You updated the base image, rebuilt, and the CI scan shows the same CVEs. What do you check?

Check that you changed the final stage's FROM line in a multi-stage build, that the build pulled the base fresh and did not reuse a cached layer, and that the new base digest's own scan actually lacks those CVEs. If the distribution has not shipped a fix, record a dated exception and look for another base.

Sources

Last reviewed: 24 October 2026. Product capabilities change; check docs.safeguard.sh for the current state.

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.