Implement Dependency Firewall with OPA policies
This tutorial guides you through implementing Dependency Firewall in Harness Artifact Registry using Open Policy Agent (OPA) policies. Dependency Firewall acts as a security gatekeeper for your software supply chain, automatically evaluating artifacts against custom policies before they are cached in your upstream proxy registries.
You will learn how to create custom security policies using Rego (OPA's policy language), configure policy sets to enforce different security requirements, and monitor policy violations. By the end of this tutorial, you will have a working Dependency Firewall implementation that protects your organization from vulnerable, non-compliant, or outdated dependencies.
Before you begin
Make sure you have the following:
- Harness account with the Artifact Registry module enabled.
- Dependency Firewall feature flag (
HAR_DEPENDENCY_FIREWALL) enabled. Contact Harness Support to enable it. - Upstream proxy registry configured for package types such as npm or Maven. Go to Create an upstream proxy to set one up.
- Familiarity with policy as code concepts, your package manager ecosystem (npm, Maven, etc.), and software supply chain security principles.
- OPA and Rego experience is helpful but not required. This tutorial includes examples you can use directly.
Overview
In this tutorial, you will complete three main steps:
- Create policy and policy set: Define OPA policies using Rego and organize them into policy sets.
- Enable Dependency Firewall: Configure your upstream proxy registry to use the policy sets.
- Monitor and review: Fetch packages and view policy violations in the Dependency Firewall dashboard.
By following these steps, you will establish automated security controls that evaluate every artifact against your organization's compliance requirements before allowing them into your software supply chain.
Step 1: Create a policy and policy set
In this step, you will create an OPA policy written in Rego and configure a policy set that will be used to evaluate artifacts.
Create a policy
For this tutorial, you will create a license policy that blocks artifacts with non-compliant licenses from being cached in your registry. This helps maintain a secure software supply chain by ensuring only approved open-source licenses are used in your environment.
Harness provides a library of pre-written OPA policies specifically designed for Dependency Firewall. You can use these policies as-is or customize them to fit your organization's requirements. This can save time and provide a starting point for common security scenarios.

-
Create a new policy with the necessary details.
-
Add the following Rego policy code:
package upstreamFirewall
import future.keywords.in
import future.keywords.if
allowed_licenses_list := [
{"license": {
"value": "MIT",
"operator": "==",
}},
{"license": {
"value": ".*Apache.*",
"operator": "~",
}},
{"license": {
"value": ".*Eclipse.*",
"operator": "~",
}},
]
#### DO NOT CHANGE THE FOLLOWING SCRIPT ####
allowed_licenses := {x | x := allowed_licenses_list[_]}
allowed_license_values := [x | x := allowed_licenses_list[_].license.value]
deny[msg] {
item := violations[i]
msg := item.message
}
violations[v] {
res := input[i]
lic := res.licenses[j]
not is_license_allowed(lic)
v := {
"Blocked License": lic,
"Category": "License",
"Allowed Licenses": allowed_license_values,
"message": sprintf("License '%s' is not allowed for package '%s'", [lic, res.purl]),
}
}
license_matches(lic, allowed) if {
allowed.license.operator == "=="
lic == allowed.license.value
}
license_matches(lic, allowed) if {
allowed.license.operator == "~"
regex.match(allowed.license.value, lic)
}
is_license_allowed(lic) if {
some allowed in allowed_licenses
license_matches(lic, allowed)
}
How this policy works:
This policy uses flexible pattern matching to evaluate artifact licenses:
-
Allowed licenses with operators: Defines licenses using two matching strategies:
- Exact match (
==): For licenses that must match exactly (for example, "MIT"). - Regex match (
~): For license families using patterns (for example, ".Apache." matches "Apache-2.0", "Apache-1.1", etc.).
- Exact match (
-
License validation: The policy checks each artifact's license against the allowed list using the appropriate operator.
-
Violation details: Provides information about blocked licenses and the package they belong to.
Customization examples:
- Add exact match:
{"license": {"value": "BSD-3-Clause", "operator": "=="}} - Add pattern match:
{"license": {"value": ".*BSD.*", "operator": "~"}}(matches all BSD variants) - Block copyleft: Remove GPL patterns to restrict copyleft licenses
This flexible approach allows you to approve entire license families (like all Apache or Eclipse variants) without listing each version individually.
Test your policy
Before applying the policy, you can test it with sample input to verify it works as expected.
Test case 1: Policy violation (artifact with non-allowed license)
Input:
[
{
"purl": "pkg:npm/some-gpl-package@1.0.0",
"licenses": [
"GPL-3.0"
]
}
]
Expected result: Input failed policy evaluation
The policy will deny this artifact because:
- It has a "GPL-3.0" license which does not match any allowed pattern.
- The allowed patterns are: exact match for "MIT", regex match for ".Apache.", and regex match for ".Eclipse.".
- GPL-3.0 is a copyleft license that is not in the approved list.
Test case 2: Policy passes (artifact with allowed license)
Input:
[
{
"purl": "pkg:npm/lodash@4.17.21",
"licenses": [
"MIT"
]
}
]
Expected result: Input passed policy evaluation
The policy will allow this artifact because:
- It has a "MIT" license which matches the exact match rule (
==operator). - The license exactly matches the allowed value "MIT".
Create a policy set
A policy set is a collection of one or more policies that are evaluated together against artifacts. Policy sets allow you to group related security policies and apply them to the upstream proxy entity type.
Now that you have a policy, create a policy set to group and apply it:
- Create a new policy set with the following details:
- Id:
firewallset(or your preferred identifier) - Name:
firewall-set - Description: (optional) Add a description for your policy set
- Entity Type that this policy set applies to: Select Upstream Proxy
- On what event should the policy set be evaluated: Select On Evaluation
- Id:
The entity type must be set to Upstream Proxy for the policy set to work with Dependency Firewall. This ensures the policies are evaluated when artifacts are fetched from external sources through your upstream proxy registries.
-
Select Continue.
-
Select the policies you want to include in this policy set (for example, "firewall - license").
-
Select Apply, then select Finish.
-
Toggle the policy set to Enforced to activate it.
Once enforced, the policy set actively evaluates artifacts against the configured policies when they are fetched through upstream proxy registries.
Step 2: Enable Dependency Firewall on upstream proxy
Now that you have a policy set configured, enable Dependency Firewall on your upstream proxy registry. You can enable it when creating a new upstream proxy or configure it on an existing one.
Enable Dependency Firewall
-
Navigate to your upstream proxy registry (npm or Maven).
-
Go to the Configuration tab.
-
Locate the Dependency Firewall Configuration section.
-
Enable the Enable Dependency Firewall toggle.
-
Choose an enforcement mode:
-
Warn: Violations are logged but not blocking. Artifacts with policy violations are still cached in your registry. This mode is useful for testing policies before enforcing them.
-
Block: Violations block the package from being cached. Artifacts that violate policies are NOT cached in your upstream proxy registry and cannot be used in builds or deployments. This is the recommended mode for production environments.
-
-
Save your configuration.
Once enabled, the Dependency Firewall automatically evaluates all artifacts fetched from external sources against your configured policy sets before caching them in your upstream proxy registry.
Step 3: Fetch packages and view violations
Now that Dependency Firewall is enabled, you can fetch packages through your upstream proxy. The firewall automatically evaluates each package against your configured policies and logs any violations.
Use your package manager to fetch a package through your upstream proxy registry. The Dependency Firewall evaluates the package in real-time before caching it in your registry.
View evaluated packages
To review which packages have been evaluated by Dependency Firewall:
- Navigate to your upstream proxy registry in Harness.
- Go to the Dependency Firewall tab.
- You will see a list of evaluated packages with the following information:
- Package Name and Version: The artifact that was evaluated (for example,
requests 2.31.0). - Upstream Proxy: The proxy registry name (for example,
pythonproxy). - Status: Either
WarningorBlockeddepending on your enforcement mode and policy violations. - Evaluated At: Timestamp of when the evaluation occurred.
- Package Name and Version: The artifact that was evaluated (for example,
Artifact visibility depends on the evaluation result:
- Passed or Warning status: Artifacts are cached and visible in the Artifacts tab of your registry.
- Blocked status: Artifacts are NOT cached and only appear in the Dependency Firewall tab.
View violation details
To see detailed information about policy violations:
- In the Dependency Firewall tab, select a package with a
WarningorBlockedstatus. - The Violation Details panel displays:
Next steps
- Go to Dependency Firewall overview to understand the full architecture and concepts.
- Go to Configure policies and policy sets to explore additional policy patterns.
- Go to Open Policy Agent documentation to explore the Rego policy language in depth.