Map each finding to the package that declares the dependency, then map that package to an owner. CODEOWNERS is the usual source, a manifest field or a service catalogue is the alternative. Always define a fallback owner, because shared and orphaned code is where findings stall.
Start with the path
A scan result in a monorepo has a path: the manifest or lockfile that declared the vulnerable library. Everything else follows from that path. If your tool reports only a package name and version, you cannot route. Check that results include the file.
Three sources of ownership
| Source | Strength | Weakness |
|---|---|---|
| CODEOWNERS | Already maintained for reviews | Written for review, may be coarse |
| Metadata in each manifest | Lives next to the code | Needs a convention and a check |
| Service catalogue | Includes on call and escalation | A separate system to keep current |
What the CODEOWNERS docs say
GitHub's documentation says the file can live in the .github folder, the root or the docs folder, and the first found is used. The last matching pattern takes precedence, so order matters. Owners are users or teams in the form at-name or at-org-slash-team, and they need explicit write access. Multiple owners for one pattern must be on the same line, or only the last mentioned applies. Lines with invalid syntax are skipped, and the file must be under 3 MB or it is not loaded.
For routing, those details become checks. Run a lint that fails on invalid lines, since skipped lines mean silent gaps. Look for packages that match no pattern.
Also see CODEOWNERS for a monorepo and last match wins.
Handle the hard cases
- Shared libraries. Route to the library owner, and notify the consumers. The fix lands once and helps everyone.
- Transitive findings. Route to the owner of the package that brought it in, not the owner of the library.
- Unowned packages. Route to a platform or security group by default, and report the count of unowned packages as a metric.
- Generated code. Route to whoever owns the generator.
What to include in the ticket
A finding the owner can act on contains the vulnerable library and version, the fixed version, the manifest path, the chain that introduced it, and whether the vulnerable code is reachable. Without the last item, many tickets get closed as not applicable, after someone spends an hour finding out.
Measure it
Track time from finding to first owner response, and the share of findings that were reassigned. High reassignment means the ownership map is wrong, not that people are lazy.
Safeguard applies reachability analysis so tickets carry that signal, and supports policies and gates in the pipeline. Try the free scan at https://gold.safeguard.sh/scan.
Try it yourself
In the demo, open a finding and look at the context that would go into a ticket for an owner.
Click through it at your own pace, or open it full screen.
Quick check
Which CODEOWNERS pattern applies when several match?
The last matching pattern takes the most precedence.
Who owns a transitive finding?
The owner of the package that brought the dependency in.
Sources
Last reviewed: 19 October 2026.