---
title: "Policy Configuration Levels"
description: "The verification policy system supports multiple levels of policy configuration, allowing fine-grained control over which policies are applied to which credentials and presentations. This document explains how policies…"
stack: "Enterprise Stack (commercial) — version 0.21.0"
stack_version: "0.21.0"
stack_comparison: https://docs.walt.id/community-vs-enterprise.md
canonical_url: https://docs.walt.id/enterprise-stack/services/verifier2-service/policies/configuration
generated: 2026-07-20
---
# Policy Configuration Levels

The verification policy system supports multiple levels of policy configuration, allowing fine-grained control over which policies are applied to which credentials and presentations. This document explains how policies can be configured at different scopes based on the implementation in the verifier libraries.

## Policy Configuration Structure

Policies are organized into a hierarchical structure

```kotlin
data class DefinedVerificationPolicies(
    /** Policies to run on the presentations (VP-level) */
    val vp_policies: VPPolicyList? = null,
    
    /** Policies to run on all credentials (Global VC-level) */
    val vc_policies: VCPolicyList? = null,
    
    /** Policies to run on specific credential query IDs (Specific VC-level) */
    val specific_vc_policies: Map<String, VCPolicyList>? = null
)
```

## Policy Levels Explained

### 1. VP-Level Policies (`vp_policies`)

**Scope:** Applied to Verifiable Presentations themselves, before credential extraction.

**Purpose:** Validate presentation-level properties such as:
- Presentation signature (holder binding)
- Audience matching
- Nonce validation
- Presentation format-specific checks (e.g., SD hash for SD-JWT, device auth for mdoc)

**When Applied:** 
- First in the verification flow
- Applied to each presentation in the `vp_token` response
- Format-specific: policies are organized by presentation format (`jwt_vc_json`, `dc+sd-jwt`, `mso_mdoc`)

**Example Configuration:**
```json
{
  "vp_policies": {
    "jwt_vc_json": [
      "jwt_vc_json/audience-check",
      "jwt_vc_json/nonce-check",
      "jwt_vc_json/envelope_signature"
    ],
    "dc+sd-jwt": [
      "dc+sd-jwt/audience-check",
      "dc+sd-jwt/nonce-check",
      "dc+sd-jwt/kb-jwt_signature",
      "dc+sd-jwt/sd_hash-check"
    ],
    "mso_mdoc": [
      "mso_mdoc/device-auth",
      "mso_mdoc/issuer_auth",
      "mso_mdoc/issuer_signed_integrity",
      "mso_mdoc/mso"
    ]
  }
}
```

**Default Behavior:** If not specified, default policies are applied based on the presentation format:
- `jwt_vc_json`: audience-check, nonce-check, envelope_signature
- `dc+sd-jwt`: audience-check, nonce-check, kb-jwt_signature, sd_hash-check
- `mso_mdoc`: device-auth, device_key_auth, issuer_auth, issuer_signed_integrity, mso

**Available Policies:**
- [Available Policies (VP)](https://docs.walt.id/enterprise-stack/services/verifier2-service/policies/available-policies.md#available-policies-vp)

---

### 2. Global VC-Level Policies (`vc_policies`)

**Scope:** Applied to **all credentials** extracted from all presentations, regardless of which query they satisfy.

**Purpose:** Enforce universal credential requirements such as:
- Signature verification
- Expiration checks
- Not-before validation
- Issuer allowlists
- Schema validation
- Webhook verification

**When Applied:**
- After presentations are validated and credentials are extracted
- Applied to every credential in parallel
- Runs regardless of which DCQL query the credential satisfies

**Example Configuration:**
```json
{
  "vc_policies": [
    "signature",
    "expiration",
    "not-before",
    {
      "policy": "allowed-issuer",
      "allowed_issuer": ["did:example:trusted-issuer"]
    },
    {
      "policy": "schema",
      "schema": {
        "type": "object",
        "properties": {
          "credentialSubject": {
            "type": "object"
          }
        }
      }
    }
  ]
}
```

**Default Behavior:** If not specified, defaults to `["signature"]` (signature verification only).

**Available Policies:**
- [Available Policies (VC)](https://docs.walt.id/enterprise-stack/services/verifier2-service/policies/available-policies.md#available-policies-vc)

---

### 3. Specific VC-Level Policies (`specific_vc_policies`)

**Scope:** Applied to credentials that satisfy **specific DCQL credential queries**, identified by query ID.

**Purpose:** Enforce credential-type-specific or query-specific requirements such as:
- Schema validation for specific credential types
- Issuer restrictions for specific credential queries
- Custom validation rules for particular credential formats
- Field-specific regex patterns

**When Applied:**
- After global VC policies
- Only to credentials that match the specified query ID
- Allows different policies for different credential types in the same session

**Example Configuration:**
```json
{
  "specific_vc_policies": {
    "identity_credential": [
      {
        "policy": "schema",
        "schema": {
          "type": "object",
          "required": ["credentialSubject"],
          "properties": {
            "credentialSubject": {
              "type": "object",
              "required": ["name", "email"]
            }
          }
        }
      },
      {
        "policy": "allowed-issuer",
        "allowed_issuer": ["did:example:identity-issuer"]
      }
    ],
    "drivers_license": [
      {
        "policy": "vical",
        "vical": "<base64-encoded-vical-data>",
        "enableDocumentTypeValidation": true,
        "enableRevocation": true
      }
    ],
    "age_verification": [
      {
        "policy": "regex",
        "path": "$.credentialSubject.age",
        "regex": "^[0-9]{1,3}$"
      }
    ]
  }
}
```

**Available Policies:**
- [Available Policies (Specific VC)](https://docs.walt.id/enterprise-stack/services/verifier2-service/policies/available-policies.md#available-policies-specific-vc)

---

## Policy Execution Flow

The verification engine executes policies in the following order:

```
1. Parse vp_token → Extract presentations
   ↓
2. VP-Level Policies (vp_policies)
   - Validate presentation signatures, audience, nonce
   - Format-specific checks (SD hash, device auth, etc.)
   ↓
3. Extract credentials from validated presentations
   ↓
4. Global VC-Level Policies (vc_policies)
   - Applied to ALL credentials in parallel
   ↓
5. Specific VC-Level Policies (specific_vc_policies)
   - Applied to credentials matching specific query IDs
   ↓
6. Aggregate results and determine overall success
```

**Key Points:**
- Policies at each level run **in parallel** (using coroutines)
- If any policy fails, the overall verification may fail (depending on configuration)
- Results are collected and aggregated into `Verifier2PolicyResults`
- The `overallSuccess` flag requires all policies at all levels to succeed

---

## Complete Example

Here's a complete example showing all policy levels:

```json
{
  "dcql_query": {
    "credentials": [
      {
        "id": "identity_credential",
        "format": "jwt_vc_json",
        "claims": [...]
      },
      {
        "id": "drivers_license",
        "format": "mso_mdoc",
        "meta": {
          "doctype_value": "org.iso.18013.5.1.mDL"
        }
      }
    ]
  },
  "policies": {
    "vp_policies": {
      "jwt_vc_json": [
        "jwt_vc_json/audience-check",
        "jwt_vc_json/nonce-check",
        "jwt_vc_json/envelope_signature"
      ],
      "mso_mdoc": [
        "mso_mdoc/device-auth",
        "mso_mdoc/issuer_auth",
        "mso_mdoc/mso"
      ]
    },
    "vc_policies": [
      "signature",
      "expiration",
      "not-before",
      {
        "policy": "allowed-issuer",
        "allowed_issuer": [
          "did:example:trusted-issuer-1",
          "did:example:trusted-issuer-2"
        ]
      }
    ],
    "specific_vc_policies": {
      "identity_credential": [
        {
          "policy": "schema",
          "schema": {
            "type": "object",
            "required": ["credentialSubject"],
            "properties": {
              "credentialSubject": {
                "type": "object",
                "required": ["name", "email"]
              }
            }
          }
        },
        {
          "policy": "regex",
          "path": "$.credentialSubject.email",
          "regex": "^.+@example\.com$"
        }
      ],
      "drivers_license": [
        {
          "policy": "vical",
          "vical": "<base64-encoded-vical>",
          "enableDocumentTypeValidation": true,
          "enableRevocation": true
        }
      ]
    }
  }
}
```

**What happens:**
1. **VP Policies:** 
   - JWT VC JSON presentations are validated for audience, nonce, and signature
   - mdoc presentations are validated for device auth, issuer auth, and MSO validity

2. **Global VC Policies:**
   - ALL credentials (both identity and drivers license) are checked for:
     - Signature validity
     - Expiration status
     - Not-before validity
     - Issuer is in the trusted list

3. **Specific VC Policies:**
   - Credentials matching `identity_credential` query additionally checked for:
     - Schema compliance (must have credentialSubject with name and email)
     - Email format matches `@example.com` pattern
   - Credentials matching `drivers_license` query additionally checked for:
     - VICAL trust anchor validation
     - Document type validation
     - Revocation status

---

## Policy Result Structure

Results are collected into `Verifier2PolicyResults`:

```kotlin
data class Verifier2PolicyResults(
    val vpPolicies: Map<String, Map<String, VPPolicy2.PolicyRunResult>>,
    val vcPolicies: List<CredentialPolicyResult>,
    val specificVcPolicies: Map<String, List<CredentialPolicyResult>>
) {
    val overallSuccess: Boolean =
        vpPolicies.all { it.value.all { it.value.success } } &&
        vcPolicies.all { it.success } &&
        specificVcPolicies.values.all { policies -> policies.all { it.success } }
}
```

The `overallSuccess` property requires **all policies at all levels** to succeed for the verification to be considered successful.

---

## Use Cases

### Use Case 1: Basic Verification
Apply only essential checks to all credentials:
```json
{
  "vc_policies": ["signature", "expiration"]
}
```

### Use Case 2: Format-Specific Requirements
Different policies for different credential types:
```json
{
  "vc_policies": ["signature"],
  "specific_vc_policies": {
    "mdoc_credential": [
      {"policy": "vical", "vical": "..."}
    ],
    "jwt_credential": [
      {"policy": "schema", "schema": {...}}
    ]
  }
}
```

### Use Case 3: Strict Verification
Comprehensive checks at all levels:
```json
{
  "vp_policies": {...},  // All presentation checks
  "vc_policies": [
    "signature",
    "expiration",
    "not-before",
    {"policy": "allowed-issuer", "allowed_issuer": [...]}
  ],
  "specific_vc_policies": {
    "each_query": [
      {"policy": "schema", "schema": {...}}
    ]
  }
}
```

---

## Configuration via API

When creating a verification session via the API (`POST /verification-session/create`), policies are specified in the `policies` field of `VerificationSessionSetup`:

```json
{
  "flow_type": "cross_device",
  "core_flow": {
    "dcql_query": {...},
    "policies": {
      "vp_policies": {...},
      "vc_policies": [...],
      "specific_vc_policies": {...}
    }
  }
}
```

If policies are not specified, defaults are applied:
- **VP policies:** Format-specific defaults (see VP-Level Policies section)
- **VC policies:** `["signature"]` (signature verification only)
- **Specific VC policies:** `{}` (empty, no specific policies)
