Docs/Security/Dependency Firewall

Dependency Firewall

The DepAegis Dependency Firewall uses an Open Policy Agent (OPA) policy engine to enforce rules about which packages are allowed into your organization. Define policies in Rego to block vulnerable, improperly licensed, or unsigned packages — before they reach your build pipeline.

What is the Dependency Firewall?

The Dependency Firewall is a policy evaluation layerthat sits between the package registry and your consumers. Every package publish and install request is evaluated against your organization’s policies in real time.

Unlike simple allow/deny lists, the firewall uses a full policy engine (OPA) with a expressive policy language (Rego). This lets you write rules based on:

Policy Engine (OPA/Rego)

DepAegis embeds an Open Policy Agent (OPA) runtime and evaluates policies written in Rego. Policies are stored per-organization and versioned. Each policy receives a JSON document describing the package being evaluated and must return a decision: allow, deny, or warn.

The input document provided to every policy evaluation contains:

{
  "action": "install",
  "package": {
    "name": "@myorg/ui-components",
    "version": "1.2.3",
    "ecosystem": "npm"
  },
  "vulnerabilities": [
    { "cve": "CVE-2025-1234", "severity": "high" }
  ],
  "licenses": ["MIT"],
  "signing": {
    "signed": true,
    "provenance_level": "SLSA_LEVEL_2"
  },
  "sbom": {
    "component_count": 12,
    "has_cyclonedx": true
  }
}

Built-in Policies

DepAegis ships with four built-in policies that can be enabled with a single toggle. You can use these as-is or extend them with custom rules.

Block Vulnerable Packages

Blocks packages with known vulnerabilities at or above a configurable severity threshold. By default, packages with Critical or High vulnerabilities are blocked.

package depaegis.firewall

import future.keywords.in

default allow := false

allow if {
    not has_critical_or_high_vulnerability
}

has_critical_or_high_vulnerability if {
    some vuln in input.vulnerabilities
    vuln.severity in {"critical", "high"}
}

Block by License Type

Prevents packages with disallowed licenses from being installed. Useful for organizations that need to avoid copyleft licenses (GPL, AGPL) or restrict to an allowlist.

package depaegis.firewall

import future.keywords.in

default allow := false

allowed_licenses := {"MIT", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "ISC"}

allow if {
    every license in input.licenses {
        license in allowed_licenses
    }
}

Block Unsigned Packages

Blocks packages that are not digitally signed. This ensures that every package in your registry has been signed by a trusted source, preventing tampering and supply chain attacks.

package depaegis.firewall

default allow := false

allow if {
    input.signing.signed == true
}

Block Packages Without Provenance

Blocks packages that lack a SLSA provenance attestation. This ensures that packages were built by a trusted CI/CD pipeline and have not been tampered with after build.

package depaegis.firewall

default allow := false

minimum_provenance_level := "SLSA_LEVEL_2"

allow if {
    input.signing.provenance_level == minimum_provenance_level
}

Writing Custom Rego Policies

You can write custom policies to enforce organization-specific rules. Custom policies are uploaded through the dashboard or the API and are evaluated alongside (or instead of) the built-in policies.

package depaegis.firewall

import future.keywords.in

# Block packages from non-approved scopes
default allow := false

approved_scopes := {"@myorg", "@partner-org"}

allow if {
    scope := split(input.package.name, "/")[0]
    scope in approved_scopes
}

# Warn if a package has more than 50 transitive dependencies
warn if {
    input.sbom.component_count > 50
    not has_critical_vulnerability
}

has_critical_vulnerability if {
    some vuln in input.vulnerabilities
    vuln.severity == "critical"
}

Upload a custom policy via the API:

curl -X PUT \
  -H "Authorization: Bearer $DEPAEGIS_TOKEN" \
  -H "Content-Type: text/plain" \
  --data-binary @policy.rego \
  "https://app.depaegis.com/api/v1/organizations/myorg/policies/custom-firewall"
Use the warn decision instead of deny for policies that should generate alerts without blocking installs. Warnings appear in the dashboard and in webhook notifications.

Policy Evaluation Flow

Policies are evaluated at two points in the package lifecycle:

On Publish

  1. A package is pushed to DepAegis.
  2. The package is scanned for vulnerabilities and an SBOM is generated.
  3. The policy engine evaluates the package against all active policies.
  4. If any policy returns deny, the publish is rejected or the package is quarantined (depending on configuration).
  5. If all policies return allow, the package is published normally.

On Install

  1. A consumer requests a package via npm install, dotnet add package, or docker pull.
  2. The policy engine evaluates the request against all active policies.
  3. If any policy returns deny, the install is blocked with a clear error message.
  4. If policies return warn, the install proceeds but a warning is logged.
# Install blocked by firewall policy
$ npm install @myorg/unsigned-pkg
npm ERR! 403 Forbidden - Blocked by policy "block-unsigned":
  Package is not digitally signed

Quarantine Behavior

When a policy denies a package at publish time, DepAegis can either reject the publish entirely (returning a 403 to the publisher) or accept and quarantine the package (making it visible in the dashboard but blocking installs). The behavior is configurable per policy.

ModePublish ResultInstall Result
Reject403 Forbidden — publish failsN/A (package not in registry)
Quarantine202 Accepted — package stored but flagged403 Forbidden — blocked by quarantine

Override and Exception Management

Sometimes a policy needs to be bypassed for a specific package or version. DepAegis supports policy exceptions:

# Create a policy exception
curl -X POST \
  -H "Authorization: Bearer $DEPAEGIS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "policy": "block-vulnerable",
    "package": "@myorg/legacy-lib",
    "version": "3.0.0",
    "reason": "Legacy dependency, migration in progress (JIRA-4521)",
    "expiresAt": "2026-09-30"
  }' \
  "https://app.depaegis.com/api/v1/organizations/myorg/policy-exceptions"
Policy exceptions are audited. All exceptions are visible in the organization’s activity log, including who created the exception, the justification, and the expiry date.

Policy Testing

Before activating a new policy, test it against your existing packages to understand its impact. DepAegis provides a dry-run mode that evaluates a policy without enforcing it:

# Dry-run a policy against all packages in the organization
curl -X POST \
  -H "Authorization: Bearer $DEPAEGIS_TOKEN" \
  -H "Content-Type: text/plain" \
  --data-binary @policy.rego \
  "https://app.depaegis.com/api/v1/organizations/myorg/policies/dry-run"

The dry-run response returns a list of packages that would be denied or warned, along with the policy evaluation details, so you can adjust the policy before going live.

Testing in the Dashboard

The dashboard also provides a policy testing interface:

  1. Navigate to Organization → Policies.
  2. Click New Policy and paste your Rego code.
  3. Click Test to run the policy against a sample of recent packages.
  4. Review the results: how many packages pass, how many would be blocked or warned.
  5. Activate the policy when you are satisfied with the results.