Dynamic Verification Policies with OPA and Rego

This guide provides comprehensive documentation for integrating Open Policy Agent (OPA) and Rego policies into a Verifier API. Learn how to define dynamic verification rules for verifiable credentials (VCs) using declarative policies.


Table of Contents

  1. Introduction
  2. Prerequisites
  3. Installation
  4. Policy Management
  5. Integration with Verifier API
  6. Examples
  7. Troubleshooting
  8. Conclusion

What is OPA?

Open Policy Agent (OPA) is an open-source policy engine that enables context-aware, dynamic authorization decisions. It uses the Rego language to define policies as code.

Key Concepts

  • Rego: Declarative query language for defining policies.
  • Verifiable Credentials (VCs): Digitally signed credentials that can be programmatically verified.
  • Dynamic Policies: Rules evaluated at runtime to verify credentials based on custom logic (e.g., checking specific claims).

Prerequisites

  • Basic understanding of JSON and REST APIs.
  • OPA server installed (Installation Guide).
  • Access to a Verifier API instance.

Installation

Step 1: Install OPA

Download and run OPA locally:

# For Linux
wget https://openpolicyagent.org/downloads/v0.46.1/opa_linux_amd64 -O opa
chmod +x opa

# For macOS (Homebrew)
brew install opa

# For Windows (Docker)
docker run -p 8181:8181 openpolicyagent/opa run --server

Step 2: Start OPA Server

./opa run --server
  • Default endpoint: http://localhost:8181

Step 3: Verify Installation

curl http://localhost:8181

Policy Management

Policy Structure

Policies are defined in Rego and stored in OPA. A policy consists of:

  • package: Namespace for the policy (e.g., vc.verification.test).
  • default allow: Default decision if no rules match.
  • Rules: Conditions that evaluate to true/false.

Example Policy

package vc.verification.example

default allow = false

# Allow if credential name matches parameter
allow if {
    input.parameter.name == input.credentialData.credentialSubject.achievement.name
}

Integration with Verifier API

Policy Configuration

Include policies in the Verifier API request under request_credentials.policies:

FieldDescription
policySet to "dynamic" for OPA-based policies.
policy_nameUnique identifier for the policy.
rules.regoInline Rego policy (or policy_url for remote policies).
argumentKey-value pairs passed to the policy for evaluation.
opa_serverOPA server URL (default: http://localhost:8181).
policy_queryOPA data query path (e.g., data.test.allow).

Workflow

  1. Verifier API sends the credential data and arguments to OPA.
  2. OPA evaluates the policy against the input.
  3. OPA returns allow: true or allow: false.
  4. Verifier API enforces the decision.

Examples

1. Single Condition

Goal: Verify the credential's name matches a specific value.

Request:

{
  "request_credentials": [
    {
      "format": "jwt_vc_json",
      "type": "OpenBadgeCredential",
      "policies": [
        {
          "policy": "dynamic",
          "args": {
            "policy_name": "name_check",
            "rules": {
              "rego": "package vc.verification\n\ndefault allow = false\n\nallow if input.parameter.name == input.credentialData.credentialSubject.name"
            },
            "argument": {
              "name": "JFF x vc-edu PlugFest 3 Interoperability"
            }
          }
        }
      ]
    }
  ]
}

2. Multiple Conditions (AND Logic)

Goal: Require both name and id to match.

Rego:

package vc.verification

default allow = false

allow if {
    input.parameter.name == input.credentialData.credentialSubject.name
    input.parameter.id == input.credentialData.credentialSubject.id
}

Request:

{
  "args": {
    "argument": {
      "name": "PlugFest 3",
      "id": "urn:uuid:ac254bd5-8fad-4bb1-9d29-efd938536926"
    }
  }
}

3. Remote Policy URL

Goal: Fetch a policy from a remote server.

Request:

{
  "args": {
    "policy_url": "http://example.com/policies/name_check.rego",
    "opa_server": "http://opa.example.com"
  }
}

Full example:

{
  "request_credentials": [
    {
      "format": "jwt_vc_json",
      "type": "OpenBadgeCredential",
      "policies": [
        {
          "policy": "dynamic",
          "args": {
            "policy_name": "waltid",
            "opa_server": "http://opa.example.com",
            "policy_query": "data",
            "rules": {
              "policy_url": "http://example.com/policies/name_check"
            },
            "argument": {
              "name": "JFF x vc-edu PlugFest 3 Interoperability"
            }
          }
        }
      ]
    }
  ]
}

For advanced use cases, explore OPA’s documentation.