Secure Software Development / Advanced: components, evidence, and response / Lesson 13
Build a component inventory for dependency decisions
Identify what ships, how it is used, and what evidence is needed before deciding advisory applicability.
On this page
Lesson goals
- Distinguish declared, resolved, built, and deployed component inventories.
- Separate component identity, advisory applicability, and remediation priority.
Ask which software the inventory describes
A manifest declares intended dependencies; a lockfile records resolved choices under a package managerโs model; an artifact inventory describes what a build contains. The deployed system can differ again because of packaging, optional components, or later configuration. Name the scope and revision of each inventory. In the workshop service, a development-only formatter and a bundled document parser have different exposure paths. Neither should be classified solely from a package name. An inventory supports investigation, but it does not prove that every component is safe, licensed correctly, reachable, or configured securely.
Preserve enough identity to avoid a false match
Component identity can require ecosystem, namespace, name, version, source, and artifact relationship. Two similarly named packages from different ecosystems are not automatically the same component. The first program compares explicit synthetic identities without querying an advisory feed. It intentionally uses exact versions and no version-range algorithm. Real ecosystems have different version semantics, backports, and vendor packaging rules, so do not compare versions as arbitrary strings or apply one homemade parser everywhere. Use an approved ecosystem-aware tool and preserve its assumptions when evaluating actual records.
component = {"ecosystem":"lab-python", "name":"schedule-reader", "version":"2.4.1"}
advisory_case = {"ecosystem":"lab-python", "name":"schedule-reader", "version":"2.4.1"}
other = {"ecosystem":"lab-java", "name":"schedule-reader", "version":"2.4.1"}
def same_identity(left, right):
return all(left[key] == right[key] for key in ("ecosystem", "name", "version"))
assert same_identity(component, advisory_case) is True
assert same_identity(component, other) is False
print("synthetic component identities distinguished")
synthetic component identities distinguished
The complete program checks two exact-match decisions. Package and advisory names are fictional and imply no real vulnerability. No package resolution, installation, advisory lookup, or version-range evaluation occurs.
Record relationships and use context
An SBOM format can represent components and relationships, but a useful review still needs to know which artifact and build it describes. The JSON example is deliberately a custom classroom inventory, not a valid SPDX document. It distinguishes direct application use from a transitive parser relationship and retains an unknown runtime-use status. Unknown should trigger investigation rather than automatic safety or confirmed exploitability. A complete SBOM may be generated by approved tooling, yet its completeness and correspondence to the shipped artifact must still be assessed under the chosen process.
{"format":"classroom-inventory-v1","artifact":"workshop-service-lab","sourceRevision":"lab-revision-8","components":[{"name":"schedule-reader","version":"2.4.1","relationship":"direct","runtimeUse":"confirmed-in-model"},{"name":"text-decoder","version":"1.6.0","relationship":"transitive-of-schedule-reader","runtimeUse":"unknown"}]}
This non-runnable data is not SPDX syntax and is not produced by a scanner. It contains invented components only. The unknown status deliberately preserves a missing fact instead of asserting vulnerability or safety.
Separate applicability from urgency
An advisory match asks whether the component and affected conditions apply. Prioritization then considers exposure, business impact, known relevant evidence, available mitigation, and the cost of leaving uncertainty unresolved. A severity label alone does not answer all those questions. Conversely, absence of demonstrated reachability is not proof of absence, especially when the inventory is incomplete. Record the reasoning and owner for an applicability decision. Use synthetic examples in learning and official maintainer records for actual cases; do not fabricate a real advisory identifier or claim a package is affected without checking its authoritative source.
Verify the artifact after a dependency change
Updating a declaration does not prove that the resolved or shipped component changed. Verify the approved lock and artifact inventory, then run meaningful compatibility and security regressions at the affected boundary. Check whether the repair also needs configuration or code changes. Preserve the old finding and the actual replacement evidence instead of closing it because an update command completed. This course performs no package updates or installs. Its local identity model teaches the reasoning needed to request precise evidence and to avoid substituting inventory administration for verified remediation.
Common errors and fixes
A similarly named package is marked affected
- Why it happens
- Ecosystem and component identity were omitted.
- How to fix it
- Compare authoritative identity and affected conditions.
- Prevent it next time
- Preserve namespace, source, version, and artifact scope.
A declaration update closes the finding
- Why it happens
- Resolved and shipped content were not checked.
- How to fix it
- Verify the actual artifact and relevant behavior after the change.
- Prevent it next time
- Tie remediation evidence to a build revision.
Unknown runtime use is called not affected
- Why it happens
- Missing evidence is mistaken for absence.
- How to fix it
- Investigate the usage boundary and record uncertainty.
- Prevent it next time
- Require supported rationale for applicability decisions.
Check your understanding
1. A lockfile lists a fixed component but the old parser remains bundled. Is remediation complete?
Show worked solution
No. Determine which artifact contains the old parser and why packaging retained it. Verify the replacement in the actual approved build inventory and run affected behavior checks. The lockfile is one input, not proof of the contents delivered to users.
2. Why is a component inventory not a vulnerability report?
Show worked solution
It describes identified components and relationships within a stated scope. Vulnerability applicability requires authoritative affected conditions and usage context, while priority also needs impact and exposure reasoning. Keep those records linked but distinct so incomplete identity or usage does not silently become a safety claim.
Key takeaways
- Inventory scope and artifact identity matter.
- Advisory applicability and remediation priority are separate decisions.
- Verify shipped content after a dependency change.