Dependency Firewall GA
# Executive Summary
Dependency Firewall prevents risky dependencies from entering builds and ensures only signed artifacts reach production. The MVP blocks package downloads/uploads based on vulnerability thresholds, license policies, and malicious package detection, plus requires signature verification for container images. This unblocks $500K+ ARR (Rafael, FDA-regulated customers) and closes competitive gaps vs Nexus Firewall/Snyk.
**MVP Scope:**
* Block package downloads from registries (during builds) and uploads to registries based on policies
* Direct dependency validation via PMDB + Malicious Packages DB (no transitive dependencies)
* Container image signature verification on upload/download
* Configurable policies: vulnerability thresholds (critical/high/medium/low), license restrictions, malicious package blocking
* Audit logging with error messages in build jobs
* YAML configuration file
# Description
**Problem:** GitLab detects vulnerabilities post-download, but cannot prevent risky packages from being downloaded. Organizations need registry-level blocking for malicious packages, vulnerable dependencies, license violations, and unsigned artifacts. This is blocking Rafael (1,050-user deal), T-Mobile (Gemnasium deprecation), and FDA-regulated customers.
**Solution:** Block package downloads/uploads and enforce container image signatures at the registry level. Teams configure policies via YAML: vulnerability thresholds, license allow/deny lists, malicious package blocking, and signature requirements. Each policy supports warn/block/both modes. Direct dependencies only.
**Impact:** Over $23M in ACV of customers requesting this capability. Unblocks deals, prevents churn, improves win rate vs Nexus/Snyk. Core SSCS add-on capability addressing EO 14028 and EU Cyber Resilience Act requirements.
### Phased Rollout Across Existing and New Registry Systems
The Dependency Firewall MVP will be implemented across two distinct registry architectures to maximize customer value and manage technical complexity:
**Phase 1: GitLab Package Registry & Container Registry (Existing)**
* **Timeline:** FY27-Q1 - FY27-Q2
* **Scope:** npm, Maven, PyPI, NuGet, and other formats supported by the existing Package Registry
* **Implementation approach:** Intercept package downloads/uploads at the registry API layer
* **Rationale:** Lower risk, proven architecture, immediate value for existing customers.
**Phase 2: Unified Artifact Management Virtual Registries (New)**
* **Timeline:** FY27-Q2 - FY27-Q3 (dependent on Unified Artifact Management MVP completion)
* **Scope:** Virtual registries for Maven, npm, Docker, PyPI, NuGet with upstream proxying
* **Implementation approach:** Integrate firewall policies into virtual registry request interception hooks (TBD by EM @mmishaev )
* **Rationale:** Enables firewall enforcement at organization level, Enable firewall for new Artifact offering to drive adoption.
* Also aim to support upstream proxy scenarios where packages are cached before reaching end users - by introducing policies verification before fetching into the cache
# Business Goals and Metrics
## Business Impact and Investment Justification
**Strategic Alignment:** Core SSCS add-on capability for FY27 enabling supply chain security monetization.
**Expected Outcomes:** Unblock $500K+ ARR, prevent T-Mobile churn, improve competitive win rate vs Nexus/Snyk, enable Premium/Ultimate upsell.
**Investment Rationale:** Lost deals to competitors + customer churn without this capability. Prerequisite for SSCS add-on launch.
## Success Metrics
| Metric Type | Metric | Target | Timeline | Owner |
|-------------|--------|--------|----------|-------|
| **Adoption** | Projects with Dependency Firewall enabled | 100 projects | 6 months post-GA | SSCS PM |
| **Coverage** | Direct dependencies blocked | 1,000+ packages | 12 months | SSCS PM |
| **Performance** | Registry request latency increase (p95) | \<100ms overhead | Ongoing | Engineering |
| **Business Impact** | SSCS add-on adoption rate | 20% of Ultimate | 12 months | Product Leadership |
| **Leading Indicator** | Beta customer satisfaction | \\\>8/10 | During beta | SSCS PM |
# User Stories and Use Cases
## Primary Personas
* **Security Engineer:** Enforces supply chain security policies, manages compliance
* **DevSecOps Lead:** Balances security with developer productivity
* **Compliance Officer:** Ensures license compliance, maintains audit trails
* **Developer:** Consumes packages, needs clear guidance when blocked
## User Stories
1. **As a Security Engineer**, I want to block packages with critical vulnerabilities from being downloaded, so risky dependencies don't enter our codebase.
* Acceptance: Configure thresholds, downloads blocked when exceeded, clear error with CVEs
* **Priority:** P0
2. **As a Compliance Officer**, I want to enforce license policies automatically, so we don't use GPL-licensed packages in proprietary software.
* Acceptance: Configure deny/allow lists, downloads/uploads blocked for denied licenses, audit log
* **Priority:** P0
3. **As a DevSecOps Lead**, I want to require signed container images in production, so we ensure artifact integrity.
* Acceptance: Require signature verification, unsigned images blocked on upload/download, clear errors
* **Priority:** P0
4. **As a Developer**, I want clear error messages when a package is blocked, so I understand why and can find alternatives.
* Acceptance: Error shows package, version, violation, CVEs/license, policy update instructions
* **Priority:** P0
5. **As a Security Engineer**, I want to block known malicious packages automatically.
* Acceptance: Enable malicious blocking, query Malicious Packages DB, block with explanation
* **Priority:** P0
## Feature Requirements
### Configuration File
**Location:** `.gitlab/dependency-firewall.yml`
yaml
\`dependency_firewall: mode: block # Options: warn, block, both
policies: vulnerabilities: mode: block thresholds: critical: 0 high: 5 medium: 10 low: 100
```
licenses:
mode: block
deny: [GPL-2.0, GPL-3.0, AGPL-3.0]
allow: [MIT, Apache-2.0, BSD-3-Clause]
malicious_packages:
mode: block
enabled: true
```
artifact_signing: container_images: require_signature: true mode: block\`
### Package Download Enforcement
**Trigger:** Build downloads package from registry
**Process:** Intercept request → query PMDB + Malicious DB → evaluate policies → block/warn → log
**Error Format:**
\`Dependency Firewall blocked: lodash@4.17.20 Reason: 2 critical vulnerabilities (max: 0)
- CVE-2020-8203, CVE-2021-23337 Action: Update policy or choose alternative\`
### Package Upload Enforcement
**Trigger:** Package uploaded to registry
**Process:** Intercept upload → query PMDB + Malicious DB → evaluate policies → block/warn → log
### Container Image Signature Verification
**Upload:** Verify signature on push → block unsigned if required → log
**Download:** Verify signature on pull (deployment) → block unsigned → log
**Error Format:**
`Dependency Firewall blocked: myapp:v1.2.3 Reason: Signature verification failed Action: Sign image or update policy`
### Audit Log
**Fields:** Timestamp, action (download_blocked/upload_blocked/signature_failed), package/image, policy violated, violation details, user/job context, mode
# User Experience
## Key User Journeys
**Journey 1: Developer Build with Blocked Package**
1. Developer pushes code → pipeline runs
2. Build downloads dependencies → system queries PMDB
3. Package has 2 critical CVEs (threshold: 0) → download blocked
4. Build fails with error showing CVEs → developer updates to fixed version → build succeeds
**Journey 2: Security Engineer Configures License Policy**
1. Create `.gitlab/dependency-firewall.yml` → configure deny list \[GPL-2.0, GPL-3.0\]
2. Set mode to `warn` → monitor audit logs → validate
3. Change mode to `block` → GPL packages now blocked
**Journey 3: Container Image Signing Enforcement**
1. Configure `require_signature: true`
2. Developer pushes unsigned image → blocked
3. Developer signs image → upload succeeds
4. Deployment pulls signed image → verified, proceeds
## Dependency Firewall — Permissions
All permissions follow GitLab's additive custom roles model — they can be granted to any base role (Guest+) via custom role assignment to enable use cases like a "Security Analyst" role without requiring Maintainer or Owner access.
<table>
<tr>
<th>Custom Permission</th>
<th>Description</th>
<th>Developer</th>
<th>Maintainer</th>
<th>Owner</th>
</tr>
<tr>
<td>
**Policy Management (SPP)**
</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>
`read_dependency_firewall_policy`
</td>
<td>View dependency firewall policy configuration in the SPP</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>
`propose_dependency_firewall_policy`
</td>
<td>Submit firewall policy changes via merge request in the SPP</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>
`manage_dependency_firewall_policy`
</td>
<td>Create, edit, and delete firewall policies in the SPP</td>
<td></td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>
`merge_dependency_firewall_policy`
</td>
<td>Merge firewall policy MRs to enforce changes</td>
<td></td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>
`manage_security_policy_link`
</td>
<td>Link/unlink SPP to target groups and projects (existing permission)</td>
<td></td>
<td></td>
<td>✓</td>
</tr>
<tr>
<td>
`manage_dependency_firewall_scope`
</td>
<td>Define which projects/groups a firewall policy applies to</td>
<td></td>
<td></td>
<td>✓</td>
</tr>
<tr>
<td>
**Enforcement (Target Project)**
</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>
`download_package_with_firewall`
</td>
<td>Download packages from registry, subject to firewall enforcement</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>
`upload_package_with_firewall`
</td>
<td>Upload packages to registry, subject to firewall enforcement</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>
`push_container_image_with_firewall`
</td>
<td>Push container images, subject to signing enforcement</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>
`pull_container_image_with_firewall`
</td>
<td>Pull container images, subject to signing enforcement</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>
`override_dependency_firewall_block`
</td>
<td>Override a specific firewall block for a package (with audit trail)</td>
<td></td>
<td></td>
<td>✓</td>
</tr>
<tr>
<td>
**Observability**
</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>
`read_dependency_firewall_job_log`
</td>
<td>View firewall block/warn messages in CI/CD build output</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>
`read_dependency_firewall_audit`
</td>
<td>View firewall audit events for own package operations</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>
`read_dependency_firewall_audit_all`
</td>
<td>View all firewall audit events across the project/group</td>
<td></td>
<td></td>
<td>✓</td>
</tr>
<tr>
<td>
`export_dependency_firewall_audit`
</td>
<td>Export firewall audit events via audit event streaming</td>
<td></td>
<td></td>
<td>✓</td>
</tr>
<tr>
<td>
**Quarantine (GA)**
</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>
`read_dependency_firewall_quarantine`
</td>
<td>Browse list of packages blocked by firewall policies</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>
`admin_dependency_firewall_quarantine`
</td>
<td>Approve, release, reject, or permanently block quarantined packages</td>
<td></td>
<td>✓</td>
<td>✓</td>
</tr>
<tr>
<td>
`manage_dependency_firewall_quarantine_settings`
</td>
<td>Configure quarantine behavior (auto-reject rules, retention)</td>
<td></td>
<td></td>
<td>✓</td>
</tr>
<tr>
<td>
**Custom Permissions**
</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>
`manage_dependency_firewall_policy`
</td>
<td colspan="4">Create, edit, delete firewall policies without Maintainer role</td>
</tr>
<tr>
<td>
`read_dependency_firewall_audit`
</td>
<td colspan="4">View all firewall audit events without Owner role</td>
</tr>
<tr>
<td>
`admin_dependency_firewall_quarantine`
</td>
<td colspan="4">Approve/reject quarantined packages without Maintainer role</td>
</tr>
<tr>
<td>
`override_dependency_firewall_block`
</td>
<td colspan="4">Override a specific block for a package (with audit trail)</td>
</tr>
</table>
# Out of Scope
* Transitive dependency analysis
* Package allow/deny lists by name
* Quarantine workflow with approval
* Dedicated UI for policy management
* Package formats beyond TBD scope
* Dependency Proxy integration
* OSSF Scorecard integration
* Multi-project policy inheritance
* Historical reporting dashboard
# Licensing and Pricing
**Tier:** SSCS Add-on (Premium/Ultimate) **Pricing:** Flat add-on fee, no usage billing
# Open Questions
1. **Package format support:** Which formats for MVP? (npm, Maven, PyPI, etc.)
2. **Configuration file location:** Project root vs `.gitlab/` folder?
3. **License policy logic:** Support deny-only, allow-only, or both? Default behavior?
4. **Performance SLAs:** Target \<100ms overhead acceptable?
5. **PMDB query model:** Real-time or cached? Caching strategy?
6. **Signature standard:** Cosign, Notary v2, or multiple?
7. **Policy precedence:** If vulnerability warns but malicious blocks, what happens?
8. **Offline/airgap support:** How to handle self-managed without PMDB access?
# Dependencies
**Team Dependencies:**
* Vulnerability Research: PMDB + [Malicious Packages DB API access](https://gitlab.com/groups/gitlab-org/-/epics/20341)
* Package Registry Team: Request interception hooks
* Container Registry Team: Signature verification integration
* SSCS team - [Provenance & Attestation for container images](https://gitlab.com/groups/gitlab-org/-/epics/19697)
* Security Team: Policy engine security review
* Compliance Team: Audit log validation
**Technical Dependencies:**
* PMDB API availability
* Malicious Packages DB API
* Package/Container Registry hook points
* Audit logging infrastructure
# Risks and Mitigations
* **Risk:** PMDB latency impacts build times | **Impact:** High | **Mitigation:** Aggressive caching, strict timeouts, load testing
* **Risk:** Package format decision delays development | **Impact:** Medium | **Mitigation:** Prioritize npm/Maven early
* **Risk:** Self-managed offline can't access PMDB | **Impact:** High | **Mitigation:** Document limitation, plan offline solution for future
* **Risk:** Signature standard selection delays implementation | **Impact:** Medium | **Mitigation:** Choose Cosign early in design
* **Risk:** Vulnerability Research team bandwidth | **Impact:** High | **Mitigation:** Align on API requirements early, escalate resource needs
## Technical Requirements
### Backend
* Policy evaluation engine (thresholds, licenses, malicious detection)
* Registry request interceptor (download/upload hooks)
* PMDB/Malicious DB query service
* Signature verification service
* Audit logging
### Performance
* Registry latency: \<100ms overhead (p95)
* PMDB query timeout: 5s
* Policy evaluation: \<50ms
### Infrastructure
* SaaS, Self-managed, Dedicated support
* Feature flag for gradual rollout
* SSCS add-on SKU check
### Monitoring
* Registry latency alerts (p95 \>200ms)
* PMDB query failure alerts (\>5%)
* Policy violation tracking
### \*\*Below is the old version of this Epic\*\*
### ~~What is the dependency firewall~~
~~It's your first line of defense when downloading packages from the Internet. The goal is to:~~
~~At a high level that's what we want to build.~~
* ~~Prevent malicious packages from entering your software supply chain~~
* \~\~Check each new package against your GitLab \~\~[~~policy~~](https://docs.gitlab.com/ee/user/application_security/policies/)
* ~~Quarantine packages for review before they are available~~
* ~~Give you a way to easily manage quarantined packages~~
### ~~MVC proposal:~~
### ~~Create a new security policy called `dependency proxy policy`.~~
~~Where does one set up these policies?~~
\~\~https://docs.gitlab.com/ee/user/application_security/policies/\\\~\\\~\\\~\\\~\\\\\\\~\\\\\\\~\\\\\\\~\\\\\\\~ provides a way to create policies for a given project. This would be a new type of policy.\~\~
* ~~Policies will have a name and description.~~
* ~~Policies will have rules.~~
* ~~Policies will have actions.~~
* ~~The trigger for these rules will be when a new package is downloaded using the dependency proxy.~~
~~NOTE: We will only trigger policies for newly downloaded items.~~
#### ~~What does a policy do~~
~~A policy can do two things `warn` and `fail`. For the MVC, I propose focusing on the warning. A user can set up a dependency proxy policy that will warn them when certain conditions are met.~~
* ~~The warnings can be limited to the log files for the MVC.~~
~~For the MVC, the rule can be:~~
1. ~~When `Security scan`~~
2. ~~Select Scanners (dependency or container scanning)~~
3. ~~With `No exceptions` that finds `Any` vulnerabilities matching~~
4. ~~`Critical` severity~~
~~For the MVC, the action will be:~~
1. ~~Add a warning to the pipeline logs~~
~~Beyond the MVC we can add:~~
1. ~~Support for other level vulnerabilities.~~
2. ~~Add a warning to the package registry UI list view~~
3. ~~Rules to quarantine packages when rules are met.~~
4. ~~The ability to CRUD the quarantine.~~
5. ~~Consider adding a new type of warning to the security vulnerability report~~
### ~~Further details~~
1. ~~Rules that are `warn` only can leverage a background job. Rules that `fail` will need to be handled by the web request.~~
2. ~~We need to understand if it's possible to scalably rely on the GitLab Advisory Database for this.~~
3. ~~Rules handled by a background job can have an extended scope (examples: we can inspect the package information but also open the archive to get the metadata, inspect it or even run scanners on the code source (for those formats where a code source is available)).~~
~~Rules handled within the web request need to be:~~
1. ~~fast~~
2. ~~scalable~~
~~This will limit what we can do in these cases.~~
epic