GitLab's Dependency Firewall blocks bad packages before a CI job installs them
GitLab put Dependency Firewall into early access with policies for malicious status, severity, license and package age across six package managers. The check is meant to run while the CI job still holds its credentials, according to a dev.to write-up.
The Engineer · Build desk
Premium and Ultimate customers can use it on GitLab.com and Self-Managed. Public-index jobs sit outside the gate. A minimum-age rule blocks the newest version a critical fix needs. A one-person bypass can become a 3am bottleneck. AI coding agents add dependencies, often unreviewed.
- capability Premium and Ultimate customers Can use the firewall on both GitLab.com and GitLab Self-Managed, claim 3
- constraint Jobs using a public index Sit outside the gate; teams should confirm every job resolves packages through a supported registry, claim 15
- cost Teams shipping urgent patches A minimum-age rule blocks the newest version, which is the one a critical fix needs, claim 12
- constraint Bypass holders A bypass only one person can grant turns into a 3am bottleneck when a hotfix trips the age policy, claim 13
- exposure AI coding agents Add dependencies on their own, often unreviewed; a typosquat can reach a merge request nobody reads, claim 11
| Who | How | Kind | Claim |
|---|---|---|---|
| Premium and Ultimate customers | Can use the firewall on both GitLab.com and GitLab Self-Managed | capability | 3 |
| Jobs using a public index | Sit outside the gate; teams should confirm every job resolves packages through a supported registry | constraint | 15 |
| Teams shipping urgent patches | A minimum-age rule blocks the newest version, which is the one a critical fix needs | cost | 12 |
| Bypass holders | A bypass only one person can grant turns into a 3am bottleneck when a hotfix trips the age policy | constraint | 13 |
| AI coding agents | Add dependencies on their own, often unreviewed; a typosquat can reach a merge request nobody reads | exposure | 11 |
What happened
- The GitLab blog says Premium and Ultimate customers can use the firewall on GitLab.com and on GitLab Self-Managed.
- Each policy runs in warn mode, which logs matches and lets the build continue, or block mode, which stops the pipeline; a logged bypass lets a designated user or token proceed.
- It integrates with GitLab Artifact Central as well as with external Sonatype Nexus Repository and JFrog Artifactory registries.
- In June 2026, GitLab researchers found five malicious PyPI packages, four of them typosquats of Flask, Requests and NumPy, that ran at install time and stole CI/CD credentials.
Why it matters
- exposure A job that installs straight from a public index never meets the gate, so teams have to confirm every job resolves through a supported registry before trusting the policy.
- constraint The minimum-age rule blocks the newest version by design, which is exactly the version a critical patch is.
- decision Teams must pick who holds the bypass before turning on blocking, because a single holder becomes a 3am bottleneck and bypass tokens are credentials themselves.
- precedent AI agents add dependencies that reach merge requests unread, so a policy gate covers a case human diff review does not.
The placement matters because of how installs work. Code that runs during pip install executes inside the job and can use any token, cloud credential or deploy key the job has access to, according to the dev.to write-up [9]. A scanner that reports it afterwards is useful for reconstructing the incident, but by then the secrets have left [10]. Rotating them is where the response gets expensive, and someone usually gets paged to do it [10].
The write-up does not say where the firewall intercepts the install. The registry integrations [4] suggest it sits at the registry. That is our inference. It would put the policy where Sonatype and JFrog already sell curation products, inside the repository manager [19]. What GitLab adds, on this account, is one policy layer that also fronts those third-party registries [4].
The write-up's author suggests an order of work. Start every policy in warn mode, leave it running through an ordinary week of pipelines, then review what it would have stopped [17]. The license and severity policies are the ones most likely to flag dependencies a team already ships [17]. Move the malicious-status policy to block first, because it has the fewest legitimate matches and does the most damage if it misses [18].
Teams without a registry-level gate usually stack smaller controls. Renovate's minimumReleaseAge setting delays update pull requests until a release has aged [20]. That is the same idea as GitLab's age policy, applied when the update is proposed instead of when it is installed [20]. Lockfiles with hashes, such as pip install --require-hashes and npm ci, keep an artifact from changing under you [21]. They do nothing about a malicious package that was pinned on purpose [21].
Coverage has two limits. The malicious-status check depends on how up to date GitLab's malware advisory database is, and ecosystems outside the six listed managers are not covered yet [16]. GitLab says more package managers are coming [5]. The write-up reports no detection rates or false-positive counts, and the June PyPI case [8] shows what the feature targets, not how much of it the policies catch.
What to watch
- Whether GitLab adds package managers beyond npm, pip, Poetry, Maven, Gradle and Bundler, as it says it will.
- Whether GitLab publishes detection or false-positive figures for the malware advisory database match.
- Whether GitLab documents where the firewall intercepts the install for jobs that do not resolve through a supported registry.
Clarity's read
What the record supports and how the coverage leans. The claims behind it follow.
Reality
- Evidence45
- Adoption
- Insufficient
- Hype gap−10
- Incentives
- Insufficient
- Confidence55
Claim ledger
Ranked by verification strength, evidence, and original report placement.
- [1]
GitLab introduced Dependency Firewall in early access at its Transcend event; it is a policy layer that blocks malicious, vulnerable and non-compliant packages before they reach a build.
- [2]
Most dependency scanning reports on a package after a job has already installed it; the firewall is meant to stop the package before install, while the job still holds its credentials and nothing hostile has executed.
- [3]
Per the GitLab blog, the firewall is available to Premium and Ultimate customers on both GitLab.com and GitLab Self-Managed.
- [4]
The firewall works with GitLab Artifact Central and with external registries from Sonatype Nexus Repository and JFrog Artifactory.
- [5]
Supported package managers at launch are npm, pip, Poetry, Maven, Gradle and Bundler, and GitLab says more are coming.
- [6]
Policies can match on malicious status (from GitLab's malware advisory database), vulnerability severity, license type (allow or deny list) and package age (a minimum age before a package can enter a build).
- [7]
Each policy runs in warn mode, which records what it would have caught and lets the build continue, or block mode, which stops the pipeline on a match and reports the reason; a logged bypass lets a designated user or token proceed anyway.
- [8]
In June 2026, GitLab researchers found five malicious PyPI packages, four of them typosquats of Flask, Requests and NumPy; the packages ran at install time and stole CI/CD credentials.
- [9]
A package that executes during pip install runs inside the job, with whatever tokens, cloud credentials and deploy keys that job can reach.
- [10]
A scanner that flags such a package in a report afterwards is useful for the incident timeline, but the secrets are already gone; rotating them is the expensive part of the response and usually means paging someone.
- [11]
GitLab notes that AI coding agents now add open source dependencies on their own, often unreviewed, so a typosquat a human reviewer might catch in a diff can reach a merge request nobody reads line by line.
- [12]
The package-age policy works against urgent patches: when a critical fix lands, the version needed is by definition the newest one, and a minimum-age rule will block it.
- [13]
A bypass that only one person can grant will turn into a 3am bottleneck the first time a hotfix trips the age policy.
- [14]
Bypass tokens are credentials and should be scoped, rotated and have their bypass log reviewed.
- [15]
A job that installs straight from a public index is outside the gate, so during early access teams should confirm every job resolves packages through a supported registry.
- [16]
Malicious-status matching is only as current as GitLab's malware advisory database, and ecosystems outside the six listed package managers are not covered yet.
- [17]
The write-up advises starting every policy in warn mode, running it across a normal week of pipelines and reading what it would have blocked; license and severity policies are the likeliest to match dependencies already shipped.
- [18]
The malicious-status policy should move to block first, because it has the fewest legitimate matches and the most damage if it misses.
- [19]
Sonatype and JFrog both sell curation products that sit in the repository manager; pre-install gating is not new to the package-registry market.
- [20]
Renovate's minimumReleaseAge setting delays update pull requests until a release has aged, the same idea as GitLab's age policy applied at proposal time instead of at install time.
- [21]
Lockfiles with hashes (pip install --require-hashes, npm ci) make an install reproducible and stop an artifact changing under you, but do nothing about a malicious package that was pinned on purpose.
- [22]
Six package managers are supported at launch.
Get this ledger inside ChatGPT. Ask about any of our stories and the answer brings its figure, each claim’s verdict and the sources. Free, no account.
Sources
1 independent publisher whose own reporting we read for this story.
- dev.toGitLab's Dependency Firewall moves package policy in front of the build
1 article · October 15, 2026
Topics and entities
Follow any of these and your For You feed starts watching them — no settings page required.