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
| Step | What can drift | Fix |
|---|---|---|
| Git clone on a branch | The branch moves with every merge | Clone a tag or commit that you release deliberately |
| Requirements install | Loose versions resolve to whatever is current | Fully pinned file, ideally with hashes |
| Shell script step | Anything the script downloads | Keep 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
- Clone by tag or commit for production deployments.
- Pin every requirement, including transitive packages.
- Use blocks or a vault for repository credentials.
- Avoid shell steps unless you need them, and review any you keep.
- Record the commit and resolved package list for each run, so you can answer later which code ran.
- 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
- Prefect YAML deployment guide, Prefect documentation, fetched 19 October 2026.
Last reviewed: 19 October 2026.