A dependency manifest records the packages a project wants, usually in a broad or abstract form. A lockfile records the exact resolved package set, including pinned versions and, in some ecosystems, the transitive dependencies needed to recreate the environment. Manifests express intent. Lockfiles enforce repeatability, which is why they matter for security and debugging.
Why This Matters for Security Teams
For Python projects, the manifest versus lockfile distinction is not just packaging hygiene. It determines whether development, CI, and production are all using the same dependency graph. When the manifest is broad, the resolver can change packages over time, and that can alter behaviour, break builds, or introduce vulnerable transitive dependencies without any source code change. A lockfile narrows that ambiguity and gives security teams a stable artifact to review, compare, and reproduce.
This matters most for software supply chain risk, where dependency drift can hide malicious or simply incompatible updates. A manifest alone is usually not enough to prove what was actually installed, while a lockfile can support integrity checks, incident investigation, and controlled patching. That is why dependency governance should sit alongside change management, not inside package management alone. Current guidance from the NIST Cybersecurity Framework 2.0 aligns with this need for repeatable, controlled software delivery.
In practice, many security teams encounter dependency risk only after a build breaks or a package is already exploitable, rather than through intentional dependency review.
How It Works in Practice
The manifest is the human-authored request. In Python, that may be project metadata and dependency specifiers in pyproject.toml, or older files such as requirements definitions. It tells the installer what the project needs, often using version ranges like minimum versions or compatible release operators. That flexibility is useful during development because it allows upgrades within a supported band.
The lockfile captures the result of resolution. It pins exact versions, and in some tooling it also records hashes, markers, source indexes, and full transitive dependencies. That makes the environment reproducible for developers, CI pipelines, and incident response. When a lockfile is committed and enforced, two builds should resolve to the same dependency set, assuming the same platform and markers.
- Use the manifest to express intent and compatibility requirements.
- Use the lockfile to freeze the resolved graph for repeatable installs.
- Review both when patching, because a safe top-level update can still alter transitive risk.
- Prefer hash-checked installs where the toolchain supports them, especially for release builds.
For security teams, the operational value is provenance: the manifest says what was allowed, and the lockfile shows what was actually chosen. That distinction helps with vulnerability triage, since a scanner can confirm whether a flagged package is really deployed or just theoretically admissible. It also improves rollback confidence because a prior lockfile can be restored to recreate a known-good state. These controls tend to break down in environments that regenerate dependency locks on every build with multiple package indexes, because resolution can vary by network availability, platform markers, or index precedence.
Common Variations and Edge Cases
Tighter dependency control often increases maintenance overhead, requiring organisations to balance reproducibility against developer speed and upgrade cadence. That tradeoff is especially visible in Python because tooling is not fully standardised across workflows. There is no universal standard for lockfiles in Python yet, so different tools handle pinning, hashing, and transitive capture in different ways.
Some projects keep only a manifest for libraries, while applications maintain both a manifest and a lockfile. That split is common when a package is meant for reuse and should stay flexible, but an application deployment needs deterministic installs. In regulated or high-assurance environments, current guidance suggests treating the lockfile as a release artifact with review and change control, not as disposable build output.
Edge cases also appear when platform-specific dependencies, extras, or environment markers are involved. A lockfile generated on one operating system may not be fully interchangeable with another if the dependency set changes by interpreter version or operating system. Secrets in package registries, private indexes, and internal mirrors add another layer of risk, because the integrity of the lockfile depends on the trustworthiness of the source that resolved it. The practical lesson is to align the lock strategy with the deployment model, not with the developer workstation.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
MITRE ATLAS and OWASP Agentic AI Top 10 address the attack and risk surface, while NIST CSF 2.0, NIST AI RMF and NIST AI 600-1 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| NIST CSF 2.0 | PR.IP-1 | Repeatable software builds depend on controlled configuration and change processes. |
| NIST AI RMF | Supply chain integrity and provenance map to AI-risk style governance principles. | |
| MITRE ATLAS | Dependency poisoning and tampering are analogous supply chain attack paths. | |
| OWASP Agentic AI Top 10 | Agentic systems often inherit Python dependency risk through tool and library supply chains. | |
| NIST AI 600-1 | GenAI app stacks rely on reproducible libraries, models, and tool dependencies. |
Check that dependency resolution and source trust are monitored for tampering and malicious packages.
Related resources from NHI Mgmt Group
- What is the difference between lockfile based dependency scanning and graph based dependency visibility?
- What is the difference between manifest-based dependency discovery and full dependency-tree resolution?
- What is the difference between managing user access and NHI access for AI projects?
- What is the difference between automating dependency updates and granting them blind trust?