A developer runs pip install. Another team uses uv sync. A third uses Poetry. They all pull Python dependencies, but a security rule configured in one client does not automatically apply to the others.
If you want to stop a disallowed package before it reaches a developer machine or CI runner, the important question is where each client gets its packages. pip, uv, and Poetry can use a configured package index. Pointing them at a controlled PyPI proxy gives your team one place to apply package policy.
That control has a boundary. Direct Git dependencies, local files, and requests sent to another index will not pass through the proxy unless you separately account for those routes.
What Can You Block Before Installation?
A known malicious package, a version with a known vulnerability, and a newly published version with limited assessment information are different problems.
You can explicitly deny a package or version. You can block known vulnerabilities above your workspace’s threshold. You can also use a release grace period to hold back versions that were published recently.
ShieldedStack applies those rules when a package request reaches its proxy. Its Trust Then Verify and Verify Then Trust modes determine what happens when there are not enough current facts to assess the requested version.
Why Not Just Scan in CI?
A scanner can identify vulnerable dependencies in a project, and a CI check can stop a build or pull request. You should keep those controls.
But a developer might install a dependency locally before opening a pull request. A CI runner might fetch dependencies before its scanner step runs. A later finding can tell you about the problem, but it cannot prevent the earlier download.
A dependency firewall acts at a different point. It evaluates a package request before delivering the package to the client.
Configure pip
For a quick test, set pip’s index URL to your ShieldedStack PyPI endpoint:
python -m pip install \
--index-url "https://your-proxy.example/simple/" \
example-packageUse your actual workspace endpoint and authentication settings in place of the example URL. You can configure the index persistently for developer machines and CI rather than passing it on every command. pip also supports the PIP_INDEX_URL environment variable.
Configure uv
uv supports a default package index in pyproject.toml:
text[[tool.uv.index]]
name = "company-pypi"
url = "https://your-proxy.example/simple/"
default = trueReplace the example URL with your ShieldedStack PyPI endpoint. Keep credentials out of the committed file and configure authentication separately. Setting this index as the default replaces uv’s implicit PyPI default.
For a temporary test, you can also use uv’s --default-index option or its UV_DEFAULT_INDEX environment variable.
Configure Poetry
Add your ShieldedStack PyPI endpoint as a primary Poetry source:
poetry source add \
--priority=primary \
company-pypi \
https://your-proxy.example/simple/When a project has a primary source, Poetry disables its implicit PyPI source. Poetry stores source configuration in the project’s pyproject.toml, so check that the resulting change is included in your normal review.
Check the Other Installation Paths
Once the three clients use the intended index, review the ways a project could still fetch dependencies elsewhere:
piprequirements and install commands using--extra-index-url,--find-links, direct URLs, or Git references.uvprojects defining additional indexes or package-specific sources.Poetryprojects defining other package sources or source-specific dependencies.
Check developer setup instructions and CI configuration as well as project files. The goal is to know which package requests reach the proxy and which need a different control.
Decide What to Do With New Versions
A package with no known vulnerability is not necessarily a package with a current assessment. Your workspace needs to decide how to handle that uncertainty.
When the publish date is known, a release grace period prevents a version inside the configured window from being allowed unless an explicit rule overrides it. If the publish date is unknown, Trust Then Verify may allow the request after its known checks. Verify Then Trust requires sufficiently current facts before allowing an otherwise unknown request.
That is the practical difference between detecting a problem later and making a policy decision when a package is requested. You can keep your scanner for dependencies already in use while using ShieldedStack to govern PyPI packages requested through the proxy.
ShieldedStack lets teams apply that policy across pip, uv, and Poetry without requiring every Python project to adopt the same client.