Third-party Python packages are incredibly useful, but every dependency introduces potential supply-chain risk. Private repositories, vulnerability scanning, dependency pinning, and stricter reviews can help, yet they may also add friction for developers. For teams running many Python services, what approach works in practice? Do you mainly use public package registries with automated safeguards, maintain an internal mirror, or rely on a curated set of approved libraries?
5 Answers
Use a delay or approval process for newly published versions, and avoid upgrading automatically the moment a release appears. Some teams also enforce minimum package age, known-vulnerability checks, and pinned transitive dependencies. The exact definition of a safe dependency usually comes from a combination of vulnerability databases, maintainer activity, package provenance, usage in the codebase, and internal policy.
A conservative option is to minimize dependencies altogether: prefer the standard library and well-established, actively maintained projects when they provide something you genuinely need. Some organizations go further by copying approved packages into an internal repository rather than installing directly from a public index. It reduces the attack surface, although it requires more maintenance and may not be practical for every team.
Many larger organizations operate a controlled package repository that mirrors public registries. Packages are scanned or reviewed before being made available internally, and teams can use approved versions instead of downloading directly from the public index. This adds some setup, but it keeps the normal installation workflow fairly familiar.
A practical baseline is to use lockfiles with hashes, run tools such as pip-audit in CI, and generate an SBOM for each build. Pinning makes it harder for a package to change underneath you, while automated scanning keeps developers from having to perform manual checks for every dependency update. More intensive review can be reserved for packages involved in authentication, secrets, or other sensitive production paths.
It can also help to make nonessential dependencies optional. If a package is rejected by a security check or becomes unavailable, a service may be able to disable that feature or use a simpler fallback while keeping its core functionality running. This does not replace scanning, pinning, or provenance checks, but it limits the operational impact of a dependency problem.

The main challenge is deciding whether a finding matters. Prioritizing dependencies that are actually reachable in the application can reduce unnecessary upgrades, especially when the alternative is a breaking major-version change.