What breaks without Docker image scanning
The image is built from a base layer that is updated once every six months to a year.
During this time, outdated dependencies accumulate in it: libraries with known vulnerabilities remain inside because the application has not abandoned them, and no one has rebuilt the base layer.
Docker image scanning starts with this layer — it has the most high-severity findings, and they affect all services built on the common base equally.
The second point of degradation is the build itself. The package manager in the Dockerfile pulls versions without pinning; the final image includes build-time packages and utilities that do not participate in the container's operation.
Every extra package is an additional attack surface, but the build says nothing about it: a successfully built image looks working.
Exploitation risk appears where a vulnerable dependency is accessible from outside.
By default, the container starts with root privileges, the library parses external data — and one unchecked dependency becomes an entry point that is not visible in either application logs or monitoring.
Then the scenario is the same: the vulnerability lives in production for months and surfaces only during an incident after deployment.
Closing it requires rebuilding all services on the common base layer, rechecking images in the registry, rolling back the release, and rotating secrets. We explain how this is closed by scanning at each stage.
What early vulnerability detection in the build provides
A vulnerability in the base image or a transitive dependency surfaces not when it starts being exploited, but when someone looks at an old tag months later.
Early vulnerability detection moves checking to every build step and at the same time records the image composition: which package version ended up in which layer and through which change.
Dependency traceability turns "somewhere inside" into a specific line in the component inventory — and it can be closed in a targeted way rather than rebuilding everything blindly.
The effect is measurable. The speed of closing defects changes from weeks to hours: a critical update enters the build on the same day it appears in the vulnerability database, because the check is embedded in the pipeline rather than living as a separate report.
The share of release rollbacks due to a surfaced dependency approaches zero — an incompatible update is filtered out before deployment. The volume of manual review decreases when the engineer sees not the entire list, but only new findings relative to the baseline.
This eliminates an entire class of failures: a production environment with a vulnerable base image that they "were going to update," and incidents due to an abandoned package that no one in the project even remembered.
Reduced downtime here is a consequence, not a slogan: the release is not taken apart manually, and rollback goes to a previously verified image.
Technically, this is a set of policies: the severity threshold at which the build stops; an exception list with mandatory justification and a review date; comparison with the baseline so old findings do not drown in the noise of false positives.
We run Trivy in the pipeline, store the result in a machine-readable report, and link it to a specific artifact — so the question "which release introduced this dependency" is answered by a query, not by digging.
Check modes: manual run or control in the build
The modes differ not by scanner, but by the moment when the verdict becomes mandatory.
The earlier the check triggers, the cheaper the fix — but the less context: locally there is no release policy, and in the pipeline there is no data on how the image will behave in the production environment. Therefore, in practice, the modes do not replace but complement each other.
| Option | When it fits | Limitations |
|---|---|---|
| One-time manual check | Incident analysis, audit of an already built image, reconnaissance before implementation | Covers a single snapshot of state; the result becomes outdated as vulnerability databases update |
| Control on the developer machine | Fast feedback before sending to the repository | No unified policy, database versions differ across everyone, the check is easy to disable |
| Check in the build pipeline | The main barrier: the build fails on critical findings before publication | Requires configured database updates and a reasonable threshold, otherwise builds slow down and people start bypassing them |
| Control at registry entry | A safeguard for third-party images and builds that bypass the pipeline | Blocks publication but does not tell the author what exactly to fix |
| Periodic sweep | Catches vulnerabilities disclosed after release and abandoned tags | Findings arrive retroactively — an owner is needed to close them by rebuilding |
The working scheme is a check in the pipeline as a mandatory barrier plus a regular scheduled registry sweep, using the same scanner so that verdicts match.
We keep the severity threshold and exception lists with a review date next to the build description: without a date, an exception quickly turns into a permanent blind spot.
Stages of implementing vulnerability control in a team
Implementing vulnerability control is not installing a scanner, but changing the build process: the check must be where fixing takes minutes, not days. We go step by step — from analyzing the current registry to handing over the regulations to the team.
-
Audit of the current build and registry. We analyze base images, rebuild frequency, the number of tags, and the age of layers. Even here, it is clear where the bulk of findings comes from.
-
Control scheme. We define checkpoints: during build, when sending to the registry, before rollout. The specific scanner (Trivy, Grype) is secondary here — more important is where the check is placed and which severity level blocks release and which only gives a warning.
-
Setting thresholds and exceptions. We set the threshold by severity, not by the total number of findings. Each exception has an owner and a review date; otherwise, the exception list eventually overrides the check itself.
-
Check on staging. We run it on a copy of the registry, compare the result with a manual review of several images, and measure the false-positive rate before it reaches the production environment. Check on real builds.
Several releases run in warning mode: the team receives reports, and release is not blocked. This is how rules are tuned rather than work being slowed down.
-
Handover of regulations and training. We hand over a document: what to do when a finding appears, how to fix it, how to file an exception, who is responsible for base images.
Then thresholds and exceptions are reviewed on a schedule — abandoned base images and outdated exceptions produce the most noise in reports.
Access policies, reports, and update regulations
Docker image scanning brings benefit not through a report, but through a set of artifacts that live in the repository and work without our involvement. Below is what remains with the team: configurations, the launch scheme, response rules, and documents for developers.
Settings are stored alongside code and versioned, so checks on the local machine, during image build, and on a schedule follow the same rules. Trivy policies are described declaratively and transferred between environments without edits.
- Check configurations — policy files with thresholds: which severity level stops the build, and which is only recorded in the report.
- Control scheme — where the check runs: before merge, during image build, at night on a schedule. And how the build behaves if vulnerability databases are unavailable.
- Response policy — remediation deadlines by severity level, who decides whether to release an image with an open finding, and how overdue items are escalated.
- Exception list — a record for each deviation: justification, owner, review date. A finding without a fix lives with a deadline rather than being forgotten.
- Base layer update regulations — how often the image is rebuilt on a fresh base, how compatibility is checked, and what rollback looks like.
- Build reports — what is visible for each build: new package, author of the change, tag history, without running the scanner manually.
- Team instructions — guides: what to do when a check triggers, how to file an exception, where to look for a disputed finding.
Case study: vulnerability window reduced from weeks to a day
The client is a product team with daily releases: 25–30 builds per week, and almost all went to production without checks.
A critical vulnerability in the base image lived in production from one to two weeks, and they learned about it from an external notification rather than from their own environment.
Incident analysis each time began with the question "which image is actually in production right now."
We embedded the check into the build pipeline: Trivy scans image layers and dependency manifests at the stage where rollout can still be stopped.
The blocking rule was configured not by the total number of findings, but by levels — the build fails only on critical and high severity with a confirmed exploitation path; the rest goes to a task list with a review date.
Metrics before and after: the vulnerability window shrank from 11–14 days to 18–24 hours, because updating the base image automatically rebuilds dependent services.
The false-positive rate fell from 40% to 8% — due to the exception file that we maintain together with the team, rather than "configured once and forgotten." Manual review decreased from 6 hours per week to 40 minutes: the engineer looks only at what actually requires a decision.
Incident analysis now proceeds by the component list with versions from the report, not by logs blindly.
What to do if the image registry is already deployed?
If the registry is already deployed, there is no need to migrate or rebuild it: the scanner connects to it as an ordinary source and reads manifests and layers through the same software interface used by deployment.
The registry remains operational, and the check becomes another step of the build pipeline — after image build and before tag publication.
We start with report mode: the scanner analyzes images silently and stores results in a separate repository, without blocking anything.
Over several deployments, statistics on real dependencies accumulate — it becomes visible which vulnerabilities come from the base image, which are pulled in by the application, and which are already closed by an update. Based on this picture, we configure the severity levels at which the build stops.
Migration without stopping deployments is built on a parallel pass: old tags remain available, new ones pass the check, and blocking is first enabled only for critical findings in our layers.
Base images where there are no fixes yet go into the exception list with a review date at the first stage — deployments do not stop, but the debt is not hidden.
Compatibility with the current build is ensured by the fact that scanning changes neither the build tool nor the layer structure: it is enough to add a step and grant the scanner read access to the registry.
The layer cache continues to work, build time increases by tens of seconds, and on unchanged layers it almost does not grow. We keep the check policy in a file next to the build description and version it — rollback is done with a single change.
Then it remains to expand coverage: connect the remaining repositories to the same rules and gradually remove exceptions. The registry is already deployed — what changes is not it, but the moment at which we learn about a vulnerability.
False positives and slow builds: common doubts
A scanner that returns hundreds of lines on the first run stops being read within a week — not because it is bad, but because the report has no priority.
Signal appears after three settings: a filter by severity and availability of a fixed version, filtering out unreachable code, and a short exception list with justification and a review date. After that, only a few records remain, and each requires a decision.
Build time is addressed by caching: the result for an unchanged layer is reused, and the vulnerability database is updated by a separate job. The check is attached to the image build, not to every commit, and stops the pipeline only at the agreed severity level.
A vulnerability in the base layer is a question of responsibility boundaries: the distribution inside the base image is updated by the template owner, and application dependencies by the service team.
The regulations fix who closes each category and by when; otherwise, the finding hangs between teams.
The scanner reports hundreds of vulnerabilities, only a few are dangerous — how do we separate them?
We filter by three criteria: severity, availability of a fixed version upstream, and reachability of the vulnerable code from the application. The remainder goes into the exception list with an owner and a review date — an exception without a deadline turns into a forgotten hole.
Will the check slow down the build and rollout — by how much?
The main time is taken by the first scan and updating the vulnerability database; after that, the result for unchanged layers is taken from cache. The threshold is configurable: we block critical issues with an available fix; the rest is a notification in the report.
Let's discuss the task: what we clarify on the first call
The first call is not a presentation, but gathering inputs: we ask questions so that the scope estimate and implementation plan are based on your infrastructure, not on average figures.
Full access to the production environment is not needed — the build scheme, registry, and current rules are enough.
- How the build pipeline is arranged: where images are built, how many services, who owns the base layers.
- What is already in the registry: how many tags per service, how far back history is stored, whether there is a cleanup policy — the time of the first full scan depends on this.
- Which scanners are used now (Trivy, Grype, Snyk) and at what stage — locally, on the build server, or already in the cluster.
- What exactly should stop the build: only critical levels, availability of a fixed version, vulnerabilities in executable layers.
- Requirements for reports and access: export format (SBOM, SARIF), where results go, read access to the registry without write permission.
- Who on your team is responsible for updating base images — without an owner of the process, the blocking rule is quickly disabled.
In response, we send an estimate of the scope of work, a step-by-step implementation plan with rollback points, and acceptance criteria: what share of vulnerabilities the first pass closes, how the pipeline behaves if the scanner fails, and what to do with images that are already in the registry. Describe the task — we will return with an estimate and a plan.







