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.
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:
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
}
}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.
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"}
}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
}
}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
}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
}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"warn decision instead of deny for policies that should generate alerts without blocking installs. Warnings appear in the dashboard and in webhook notifications.Policies are evaluated at two points in the package lifecycle:
deny, the publish is rejected or the package is quarantined (depending on configuration).allow, the package is published normally.npm install, dotnet add package, or docker pull.deny, the install is blocked with a clear error message.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 signedWhen 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.
| Mode | Publish Result | Install Result |
|---|---|---|
| Reject | 403 Forbidden — publish fails | N/A (package not in registry) |
| Quarantine | 202 Accepted — package stored but flagged | 403 Forbidden — blocked by quarantine |
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"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.
The dashboard also provides a policy testing interface: