A package named in the news can sit in five places: your source code, your CI system, your container images, your developers' laptops and production. A scoping grid lists those places, the evidence for each, and an owner, so your answer to "are we affected" covers everywhere and not just the repository you thought of first.
Why a repository search is not enough
The usual first move is to search the main repository for the package name. That finds source and lockfiles. It misses a lot.
- A CI job might install a tool globally that is not in any lockfile.
- A container image might carry a copy of the package from a base layer.
- A developer might have installed the package on a laptop while experimenting.
- A production host might run an older build than the repository suggests.
If you answer "not affected" after checking only source, you may be right about source and wrong about the company.
The grid
| Environment | Where the package could be | Evidence to collect | Typical owner |
|---|---|---|---|
| Source | Manifests and lockfiles in every repository, including old branches | Search results with commit and file | Engineering leads |
| CI | Install steps, global tools, caches, runner images | Job logs inside the window, cache contents | Platform or DevOps |
| Images | Application layers and base layers | Image inventory or scan output with image digest | Platform or security |
| Laptops | Local installs, global tools, editors | Self report from developers, package list output | Each developer, collected by a lead |
| Production | Running builds, serverless bundles, edge functions | Deployed artifact version, release record | Service owners |
Copy this into the ticket and fill one row per environment. An empty row is a question, not a result.
Step by step
- Write the question. Package name, ecosystem, bad versions, window start and end. If you do not have a window yet, see the post on building the exposure window.
- Assign each row to one person. Shared ownership means nobody checks.
- Set a time for each row. Source can often be answered in minutes. Laptops take hours because they need replies from people.
- Collect evidence, not opinions. "I think we do not use it" is not evidence. A search result with a timestamp is.
- Record the verdict per row. Use three values: not present, present but not in the bad version or window, present and exposed.
- Roll up. The overall answer is the worst row, and you list every row so a reader can see how you got there.
A worked example
Imagine a story names version 4.2.0 of a templating library as malicious, live for six hours on a Monday. Here is how the grid fills in.
- Source: the search finds the library in the web app, pinned to 4.1.7, and in an internal tool, with a caret range and a lockfile resolving 4.2.0. The internal tool is a hit.
- CI: the internal tool's pipeline ran once during the six hours. The log shows a fresh install of 4.2.0. Exposed.
- Images: the internal tool is deployed as an image built from that run. The image inventory shows 4.2.0 inside the image.
- Laptops: four developers work on the internal tool. Two reply that they ran the project locally on Monday. One of them installed 4.2.0.
- Production: the internal tool is running that image.
The roll up is "exposed": one pipeline, one image, one production deployment and one laptop. The web app is clear. Because the grid made the environments explicit, nobody overlooked the laptop or assumed the web app's clean result covered the internal tool.
Handling the awkward rows
Laptops are hard because you depend on people. Send one short, specific message: the package name, the bad versions, one command to run, and where to reply. Ask for a reply even from people who think they are fine, so silence is not read as safe. A reply of "ran it, version X" is data.
Old branches and archived repositories often hide old lockfiles. If your scope says "every repository", include archived ones, since a build can still be triggered from them.
Third party environments such as a vendor's hosted build or a contractor's machine belong in the grid too. If you cannot check them, add a row for them and ask the owner to confirm.
Keeping the grid useful
Reuse it. Once you have a version for your company, make it a template in your incident folder. The next time news arrives, you spend your effort on the checks, not on remembering the places.
Review the grid after each use. If you found a package somewhere you had not expected, add that place as a permanent row.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how every component and version gets an entry, which gives you evidence for the source and images rows.
Safeguard's asset discovery and SBOM inventory help populate the source and image rows, so the grid starts from a list rather than from memory.
Quick check
Is a clean repository search enough to say we are not affected?
No. It covers the source row only. CI, images, laptops and production can hold the package without it appearing in any repository.
How do I handle laptops without surveilling developers?
Ask for a self report with one clear command and a reply deadline. You get the evidence without needing access to personal machines.
Who decides the overall answer?
The incident lead or ticket owner. The roll up is the worst row, with every row listed so the reasoning is visible.
Last reviewed: 19 October 2026.