# Server-Side VP Queries

This page explains how the Verifier Service allows you to create, retrieve, and delete Verifiable Presentation (VP) query configurations. A VP query configuration defines what credentials and fields a verifier requests from a user. These configurations live on the server side so they can be reused across multiple authorization flows.

***

## Overview

* VP query configurations are managed by the Verifier Service itself, not only by client code.
* Each configuration is stored as a JSON array of query parameters that specify which parts of a credential to request and any constraints on those values.
* Once created, a configuration is assigned a unique identifier and can be fetched or removed by its ID.
* **Optional issuer allow-list**: a configuration may also include `issuerAllowedDomains` (canonical HTTPS URLs) to restrict acceptable **issuer origins** during verification.

***

## Create VP Query Request

**Type**: `CreateVpQueryRequestDto`

### Request Body

* **`query`** (array of `VPQueryParams`, required) A non-empty array where each element defines a set of parameters for a Verifiable Presentation (VP) query. Each `VPQueryParams` element contains:
  * **`fields`** (array of `InputDescriptorField`, required) A list of descriptor fields specifying which parts of a credential to inspect and how to validate them. Each `InputDescriptorField` includes:
    * **`path`** (array of strings, required) One or more JSONPath expressions indicating where in the credential to extract a value.
    * **`filter`** (object, optional) A JSON Schema (Draft 7) that the extracted value(s) must conform to.
* **`issuerAllowedDomains`** (array of strings, optional) An **allow-list of canonical HTTPS URLs** used to restrict acceptable credential *issuers* at verification time.
  * Format: must include `https` scheme; optional `:port`; **no** query/fragment. Examples: `https://issuer.example.com`, `https://issuer.example.com:8443`, `https://issuer.example.com`
  * Normalization at runtime: host case-folded, trailing slashes trimmed, duplicates removed; **matching is by URL.origin**
  * If omitted or empty → **no issuer-domain restriction** (backward-compatible).

> Validation: each entry is checked against `HTTPS_CANONICAL_URL_REGEX`; invalid entries cause `400 Bad Request`.

**Example request body**

```json
{
  "query": [
    {
      "fields": [
        {
          "path": ["$.type"],
          "filter": { "type": "array", "contains": { "const": "IdentityCredential" } }
        }
      ]
    }
  ],
  "issuerAllowedDomains": [
    "https://issuer.example.com",
    "https://partners.example.org:8443"
  ]
}
```

***

## Controller Endpoints

All VP query–related endpoints are under the `/api/v1/verifier/vp-queries` path. Every endpoint requires a valid client‐secret bearer token for authentication.

1. **Create a VP Query Configuration**
   * **Method**: POST
   * **Path**: `/api/v1/verifier/vp-queries`
   * **Request Body**: A JSON object with:
     * `query` — non-empty array of VP query parameter sets (required)
     * `issuerAllowedDomains` — array of canonical HTTPS URLs (optional)
   * **Success Response (201 Created)**: Returns the newly created VP query configuration, including its ID, the full query array, optional `issuerAllowedDomains`, and the creation timestamp.
   * **Error Response (400 Bad Request)**: If `query` is missing/empty/invalid or any `issuerAllowedDomains` entry is not a canonical HTTPS URL.
2. **Retrieve All VP Query Configurations**
   * **Method**: GET
   * **Path**: `/api/v1/verifier/vp-queries`
   * **Success Response (200 OK)**: Returns a JSON array of all stored VP query configurations (each with its ID, query body, optional `issuerAllowedDomains`, and creation timestamp).
   * **Error Response (400 Bad Request)**: If something goes wrong with the request format.
3. **Retrieve a VP Query Configuration by ID**
   * **Method**: GET
   * **Path**: `/api/v1/verifier/vp-queries/{id}`
     * Replace `{id}` with the UUID of the configuration you want.
   * **Success Response (200 OK)**: Returns the single VP query configuration matching that ID, including `issuerAllowedDomains` if set.
   * **Error Response (400 Bad Request)**: If the provided ID is not a valid UUID.
   * **Error Response (404 Not Found)**: If no configuration exists with the given ID.
4. **Delete a VP Query Configuration by ID**
   * **Method**: DELETE
   * **Path**: `/api/v1/verifier/vp-queries/{id}`
     * Replace `{id}` with the UUID of the configuration you want to delete.
   * **Success Response (204 No Content)**: The specified configuration was successfully removed from the database.
   * **Error Response (400 Bad Request)**: If the provided ID is malformed.
   * **Error Response (404 Not Found)**: If no configuration exists with that ID.

***

## How `issuerAllowedDomains` is applied at runtime

* During VP verification, the Verifier passes the stored `issuerAllowedDomains` to its validators.
* For each VC issuer DID:
  1. The resolver extracts any advertised **LinkedDomains** (W3C DID service entries) and fetches `/.well-known/did-configuration.json` at each **origin** to validate **Domain Linkage Credentials**.
  2. The Verifier compares the **origin** set from `issuerAllowedDomains` with the issuer’s validated linked origins. If their **intersection is empty**, the VC is rejected per policy.
* Path entries in `issuerAllowedDomains` are accepted in configuration but do **not** change matching semantics (matching is by **origin** per the W3C Domain Linkage spec).

***

Because these VP queries live on the server side, you can standardize and manage them centrally rather than building the same query structure repeatedly in each client application.
