Safeguard
Supply Chain•

What do Prefect pull steps run, and how do you keep them repeatable?

Prefect pull steps clone code and install requirements each time a deployment runs. A branch or loose requirements file means runs can differ. Pin both.

Safeguard Security Team
4 min read

A Prefect deployment's pull section holds instructions that run each time the deployment runs through a worker, such as cloning a Git repository and installing requirements. If those steps follow a branch and an unpinned requirements file, two runs of the same deployment can execute different code.

What the docs describe

The Prefect guide to the prefect.yaml file says the pull section is the most important part of the file. Its instructions execute each time a deployment in that folder is run through a worker. Typical steps include setting the working directory, a git clone step that clones the repository on the provided branch, and steps that pull a working directory from cloud storage.

A separate step installs dependencies from a requirements file in a chosen directory. A shell step can run commands, and the docs warn that enabling shell mode has security implications similar to using a shell in subprocess calls.

Where repeatability breaks

StepWhat can driftFix
Git clone on a branchThe branch moves with every mergeClone a tag or commit that you release deliberately
Requirements installLoose versions resolve to whatever is currentFully pinned file, ideally with hashes
Shell script stepAnything the script downloadsKeep scripts in the cloned repo and review them

Running on a branch is a deliberate choice for some teams: merge and the next run uses the new code. That is a real trade, since it removes a release gate. If you want one, use a tag, and protect who can move tags.

Credentials in pull steps

The same guide shows private repository cloning with a credentials block, and warns against putting tokens in the file as plain text, suggesting a Secret block instead. It also shows fetching a token from a key vault with a script and using that output in the clone step. Prefer the block or vault routes. A token in a YAML file ends up in Git history.

A short checklist

  1. Clone by tag or commit for production deployments.
  2. Pin every requirement, including transitive packages.
  3. Use blocks or a vault for repository credentials.
  4. Avoid shell steps unless you need them, and review any you keep.
  5. Record the commit and resolved package list for each run, so you can answer later which code ran.
  6. Limit who can edit the deployment file, since it controls what runs on your workers.

That last point is easy to miss. The deployment file is code that executes with the worker's permissions. Treat a change to it like a change to the flow itself.

See also pin Python dependencies in data projects and who can run code in Airflow: DAG authors and trust for a similar question in another orchestrator.

Try it yourself

Click through it at your own pace, or open it full screen.

Watch how a pull request is checked before merge. A gate like that on your deployment repository is how a changed requirements file gets reviewed.

Safeguard's policies and gates, and its dependency scanning, can run on that repository. Try the free scan at gold.safeguard.sh/scan.

Quick check

Is cloning a branch a security problem?

It is a release control choice. A branch runs whatever was last merged. If you want a gate between merge and production, clone a tag or commit.

Where should a private repository token live?

In a credentials or Secret block, or a key vault, as the Prefect docs show, not in the deployment file.

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.