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