A pull request gate for an ML repo should block new reachable critical vulnerabilities, hardcoded secrets, unpinned or unhashed dependency changes in production code, and unreviewed model artifacts. It should warn, not block, on lower severity findings and on old issues the change did not introduce.
Principles before rules
A gate that blocks everything gets bypassed. A gate that blocks nothing is theater. Block on what the pull request introduced, and keep the rule list short enough that a developer can say it from memory.
A starter rule set
| Rule | Action | Why |
|---|---|---|
| New critical or high vulnerability that is reachable | Block | Code can call it |
| Secret or provider key in the diff | Block | Keys leak through history |
| Production dependency added without a pin | Block | Floating versions change under you |
| Model artifact added or changed without a recorded source | Block | Provenance gap |
| Pickle based model file added | Warn or block | Loading one can run code |
| New copyleft license in a shipped component | Warn | Needs legal review |
| Existing medium issues | Observe | Not introduced here |
Notes on the less obvious rules
Pins and hashes. pip's hash checking mode verifies downloads against hashes you record locally, and it requires every requirement to be pinned with == or a URL. A gate can check that production requirements carry hashes. That protects against a package being swapped after you reviewed it.
Model files. The safetensors format was designed to store tensors safely as opposed to pickle. Preferring it, and recording where each artifact came from, is a cheap rule. OWASP's supply chain guidance says to use models from verifiable sources and verify integrity with signatures and file hashes.
Block versus observe. Start in observe mode for two weeks, read what would have been blocked, then turn on blocking for the rules nobody argues with. See evaluating gates: block, warn or observe.
Give developers a way through
Offer an exception path: a named approver, a reason, and an expiry date. Exceptions without expiry become permanent.
Try it yourself
Open the gate demo and watch a pull request fail, then see what the developer is shown. Look for whether the message names the rule and the fix.
Click through it at your own pace, or open it full screen.
A short note on Safeguard
Safeguard supports policies and gates on pull requests, along with SBOM and dependency scanning. Try a free scan at gold.safeguard.sh/scan.
Quick check
Should the gate block on every high severity finding?
Block on new, reachable ones. Blocking on inherited findings stalls unrelated work.
Is hash checking practical for ML stacks?
Yes, with a lock tool that writes hashes for you. Binary wheels differ by platform, so list the hashes for each target platform.
Sources
Last reviewed: 19 October 2026.