Safeguard
Security Guides•

Should Airflow workers be able to reach PyPI at run time?

Some Airflow task types install packages at run time, which needs outbound access. Why that widens risk, and how to move installs to build time.

Safeguard Security Team
3 min read

Preferably not. Run-time installs mean every task start trusts a package index and whatever it serves that day. Move installs to build time, use a private mirror if you must install at run time, and restrict worker egress to that mirror only.

Where run-time installs happen

The Airflow best practices page says that for the virtualenv task type, "The workers need to have access to PyPI or private repositories to install dependencies." The environment is created per task run, which adds time and network overhead on each execution.

Other places do the same thing without announcing it. A bootstrap script that runs pip on container start does it. So does a task that shells out to install a helper. Search your repositories for pip install inside DAG files and entrypoints.

Why it matters

A build-time install happens once, in a pipeline you control, where you can scan, pin and record the result. A run-time install happens many times, on machines that usually hold credentials to your warehouse and storage.

The concrete risks are plain:

  • A package version can change between two runs of the same DAG if it is not pinned.
  • The worker needs outbound access to the internet, which also gives any compromised task a way to send data out.
  • An outage or removal at the index breaks your schedule.
  • Your inventory shows the declared list but not what was actually installed on a given day.

Options, from strongest to weakest

  1. Prebuilt environment. Airflow's external Python task type uses a pre-existing immutable environment, so nothing is installed at start. The docs say it avoids PyPI access at run time and is easier to vet.
  2. Prebuilt container image. Each task runs an image built and scanned upfront. The docs note the image must be ready upfront.
  3. Private mirror. If you still install at run time, point workers at an internal index and allow no other outbound destinations. Keep the mirror's contents under review, because a mirror copies whatever you pull into it.
  4. Direct internet access. The weakest option. If you must use it, pin every package version and treat the worker network as exposed.

A rollout plan

  1. Find run-time installs. Search for pip install in DAGs, entrypoints and operator arguments.
  2. Pick one DAG with a stable package set and move it to a prebuilt environment.
  3. Add the build to CI so the environment is scanned on every change.
  4. Tighten worker network rules to allow only your mirror or nothing.
  5. Repeat, DAG by DAG.

What to log

Keep the build record: package list, versions, build date and the image digest or environment hash. When an advisory lands, you can answer "which jobs ran this version" from records rather than memory.

Safeguard's SBOM and dependency scanning can check those prebuilt environments and images against known advisories, and its policies and gates can block a build that includes a flagged package. The free scan at https://gold.safeguard.sh/scan is a quick way to try it.

Quick check

Is a private mirror enough on its own?

It limits where installs come from, but a mirror holds whatever was pulled in. You still need to review and pin what goes into it.

Does a prebuilt environment mean no flexibility?

It does limit changes. The Airflow docs say you cannot add dependencies to the existing environment, so you rebuild it when needs change.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.