# /derive Endpoint

{% hint style="warning" %}
**Warning**\
As of ESS 2.3, this endpoint has been deprecated. Please use the **`/query`** endpoint instead.
{% endhint %}

ESS supports an [authorization mechanism based on Access Requests and Grants](https://docs.inrupt.com/security/authorization/access-requests-grants).

ESS serializes the access requests and grants as [Verifiable Credentials (VCs)](https://docs.inrupt.com/reference/glossary#verifiable-credential) and provides an endpoint that queries Access Requests/Grants VCs and returns the matching VCs in a [Verifiable Presentation (VP)](https://docs.inrupt.com/reference/glossary#verifiable-presentation).

## **`/derive`** Endpoint

The ESS [Access Grant Service](https://docs.inrupt.com/ess/latest/services/service-access-grant) provides an endpoint with the following URL:

```json
https://vc.<ESS DOMAIN>/derive
```

{% hint style="info" %}
Note\
Access to the **`/derive`** endpoint requires users to be authenticated. The endpoint supports the use of either [Solid-OpenID Connect (OIDC) access token](https://docs.inrupt.com/ess/latest/services/service-oidc) or [UMA token](https://docs.inrupt.com/ess/latest/services/service-uma).
{% endhint %}

To query for /derive Access Requests/Grants, clients can send a derivation request to the endpoint:

<table data-header-hidden><thead><tr><th width="136.02423095703125"></th><th></th></tr></thead><tbody><tr><td>Method</td><td><strong><code>POST</code></strong></td></tr><tr><td>Content-Type</td><td><strong><code>application/json</code></strong></td></tr><tr><td>Endpoint</td><td><strong><code>https://vc.&#x3C;ESS DOMAIN>/derive</code></strong></td></tr><tr><td>Payload</td><td>Derivation request object.</td></tr></tbody></table>

### Behavior

The ESS’ **`/derive`** endpoint implements the derive credential portion of the [VC API specification](https://w3c-ccg.github.io/vc-api/#derive-credential) with the following exceptions:

* ESS’ **`/derive`** endpoint returns a VP instead of a VC.
* ESS’ **`/derive`** endpoint, by default, **excludes** both expired VCs (i.e., VCs with **`expirationDate`** in the past) and future VCs (i.e., VCs with **`issuanceDate`** in the future). To override, see [options](#input-verifiable-credential).

The endpoint queries the *user-associated* Access Requests/Grants (regardless of revocation status) to return a VP that contains the matching Access Requests/Grants VCs.

* *User-associated* Access Requests are requests that have either:
  * The **`credentialSubject.id`** set to the user’s WebID (i.e., the request is created by the user); or
  * The **`credentialSubject.hasConsent.isConsentForDataSubject`** set to the user’s WebID (i.e., the request is made to the user).
* *User-associated* Access Grants are grants that have either:
  * The **`credentialSubject.id`** set to the user’s WebID (i.e., the grant is created by the user); or
  * The **`credentialSubject.providedConsent.isProvidedTo`** set to the user’s WebID (i.e., the grant is given to the user).

## Input: Verifiable Credential

The endpoint accepts a JSON document of the form:

```json
{
  "verifiableCredential": <VC to filter/query by>,
  "options": {
    "include": "ExpiredVerifiableCredential"
  }
}
```

<table><thead><tr><th width="219.98724365234375">Field</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>verifiableCredential</code></strong></td><td><p>Specify a filter Access Requests/Grants VC. The filter VC acts similarly to a “search-by-example” model and can be minimal (i.e., can be missing fields or have empty values such as an empty array, an empty document) or comprehensive. However, if any of the following field paths appear in the filter VC and are non-empty, ESS Access Grant Services uses these non-empty field paths to filter Access Requests/Grants VCs:</p><ul><li><a href="#id"><strong><code>id</code></strong></a></li><li><a href="#credentialsubject"><strong><code>credentialSubject</code></strong></a></li><li><a href="#type"><strong><code>type</code></strong></a></li><li><a href="#issuer"><strong><code>issuer</code></strong></a></li></ul></td></tr><tr><td><strong><code>options</code></strong></td><td><p><em>Optional</em>. Specify the <strong><code>"include": "ExpiredVerifiableCredential"</code></strong> option to include expired VCs and future VCs in the returned VP.</p><pre class="language-json"><code class="lang-json">"options": {
  "include": "ExpiredVerifiableCredential"
}
</code></pre><p><br>Omit to exclude the expired and future VCs.<br><br>If you specify a different option or value (such as <strong><code>"include": "ExpiredVerifiableCredentials"</code></strong> with an <strong><code>s</code></strong>), the endpoint ignores the option and excludes the expired and future VCs.</p></td></tr></tbody></table>

### Filter Paths

#### **`id`**

If the **`id`** field is present in the filter Access Requests/Grants VC, the ESS Access Grant Service considers the field for filtering user-associated Access Requests/Grants.

```json
"id": <value>
```

If the **`id`** (i.e., the URL) of an access request/grant is known, you can use the **`id`** filter field to return a specific Access Requests/Grants in the output.

A user can also directly fetch an Access Requests/Grants (if associated with the user) by its **`id`** (i.e., URL). If fetching directly, the returned object is the VC instead of a VP.

#### **`type`**

If the **`type`** field is present in the filter Access Requests/Grants VC, the ESS Access Grant Service considers the field for filtering user-associated Access Requests/Grants VCs.

```json
"type": <value(s)>
```

{% hint style="info" %}
**Note**\
If the **`type`** value is a non-empty array, matching VCs must include all elements in that array. The matching VCs can have additional elements in the array; that is, the matching VCs are not restricted to just the elements specified in the filter array.
{% endhint %}

You can use the **`type`** field to query specifically for access requests or specifically for access grants.

#### **For Access Requests**

To query for Access Requests, you can specify filter **`"type": [ "SolidAccessRequest" ]`** :

```json
"type": [ "SolidAccessRequest" ]
```

#### **For Access Grants**

To query for Access Grants, you can specify **`"type": [ "SolidAccessGrant" ]`** :

```json
"type": [ "SolidAccessGrant" ]
```

#### **`credentialSubject`**

If the **`credentialSubject`** field is present in the filter Access Requests/Grants VC, and is [not empty (i.e., it is not an empty document and contains at least one non-empty field path)](#empty-credentialsubject) , the ESS Access Grant Service considers the non-empty **`credentialSubject`** field paths to filter user-associated VCs.

```json
"credentialSubject": {
  "id": <value>,
  <"hasConsent"|"providedConsent">:  {
     //...
  }
}
```

#### **For Access Request VCs**

In Access Requests, the **`credentialSubject`** field contains an **`id`** field and a **`credentialSubject.hasConsent`** field. When querying for Access Requests, you can query by any non-empty combination of the fields.

```json
"credentialSubject": {
  "id": <value>,                            // The requestor's WebID
  "hasConsent": {
    "mode": <value or array of values>
    "hasStatus": <value>,
    "isConsentForDataSubject": <value>,     // The resource owner's WebID
    "forPersonalData": <value or array of values>,
    "forPurpose": <value or array of values>
  }
}
```

{% hint style="info" %}
**Note**\
For fields that can be a single value or an array of values,

* A single value is equivalent to an array with a single element.
* To filter by an array, matching VCs must include all elements in the provided array. However, the matching VCs can have additional elements in the array; that is, the matching VCs are not restricted to just the elements specified in the filter array.

That is:

* **`<field>: "foo"`** condition would match:
  * **`<field>: "foo"`**
  * **`<field>: [ "foo" ]`**
  * **`<field>: [ "foo", "other string" ]`**
* **`<field>: [ "foo" ]`** condition would match:
  * **`<field>: "foo"`**
  * **`<field>: [ "foo" ]`**
  * **`<field>: [ "foo", "other string" ]`**
    {% endhint %}

#### **For Access Grant VCs**

In Access Grants, the **`credentialSubject`** field contains an **`id`** field and a **`credentialSubject.providedConsent`** field. When querying for Access Grants, you can query by any non-empty combination of the fields.

```json
"credentialSubject": {
  "id": <value>,                   // The resource owner(grantor)'s WebID
  "providedConsent": {
    "mode":  <value or array of values>,
    "hasStatus": <value>,
    "isProvidedTo": <value>,       // The grant recipient's WebID
    "forPersonalData": <value or array of values>,
    "forPurpose": <value or array of values>
  }
}
```

{% hint style="info" %}
**Note**\
For fields that can be a single value or an array of values,

* To filter by an array, matching VCs must include all elements in their array. However, the matching VCs can have additional elements in the array; that is, the matching VCs are not restricted to just the elements specified in the filter array.

That is:

* **`<field>: "foo"`** (or **`<field>: ["foo"]`** ) condition would match:
  * **`<field>: "foo"`**
  * **`<field>: [ "foo" ]`**
  * **`<field>: [ "foo", "other string" ]`**
* **`<field>: [ "foo", "bar" ]`** condition would match:
  * **`<field>: [ "foo", "bar" ]`**
  * **`<field>: [ "foo", "bar", "something else" ]`**
    {% endhint %}

#### **Empty credentialSubject**

ESS Access Grant Service only considers non-empty **`credentialSubject`** field paths to filter user-associated Access Requests/Grants. Empty **`credentialSubject`** field paths are **not** considered as part of the filter. Examples of empty **`credentialSubject`** field paths are:

```json
"credentialSubject": {
}
```

```json
"credentialSubject": {
   "hasConsent": {}
}
```

```json
"credentialSubject": {
   "hasConsent": {
      "mode": [],
      "forPersonalData": []
   }
}
```

```json
"credentialSubject": {
   "providedConsent": { }
}
```

```json
"credentialSubject": {
   "providedConsent": {
       "mode": []
   }
}
```

#### **`issuer`**

If the **`issuer`** field is present in the filter Access Requests/Grants VC, the ESS Access Grant Service considers the field for filtering user-associated Access Requests/Grants VCs.

```json
"issuer": <value>
```

## Output: Verifiable Presentation

The **`/derive`** endpoint returns a Verifiable Presentation containing the matching Access Requests/Grants VCs:

<pre class="language-none"><code class="lang-none">
{
  "@context": [
    "https://www.w3.org/2018/credentials/v1",
    "https://w3id.org/security/data-integrity/v1",
    "https://w3id.org/security/suites/ed25519-2020/v1"
  ],
<strong>  "holder": "https://vc.&#x3C;ESS Domain>",
</strong><strong>  "type": "VerifiablePresentation",
</strong><strong>  "verifiableCredential": [
</strong><strong>    { // Matching access request/grant VC },
</strong><strong>    { // Matching access request/grant VC },
</strong><strong>    ...
</strong>  ]
}
</code></pre>

## Examples

ESS Access Grant Service performs a match on non-empty [**`id`**](#id), [**`credentialSubject`**](#credentialsubject) , [**`issuer`**](#issuer) , and [**`type`**](#type) field paths present in the filter VCs.

{% hint style="info" %}
**Note**\
In the following examples, the filters return user-associated Access Requests/Grants (both active and revoked) that match the filter field paths. Because the payload does not specify the [options: {“include”: “ExpiredVerifiableCredential” }](#input-verifiable-credential) , expired and future access requests/grants are excluded from the results.
{% endhint %}

### Example 1

The following filter queries for [user-associated Access Grants](#behavior) where **`owliverowner`** grants **`Read`** access to **`requestingrabbit`** .

```json
{
   "verifiableCredential": {
      "@context": [
        "https://www.w3.org/2018/credentials/v1",
        "https://schema.inrupt.com/credentials/v2.jsonld"
      ],
      "type": [
         "VerifiableCredential",
         "SolidAccessGrant"
      ],
      "credentialSubject": {
         "providedConsent": {
            "mode": [ "Read" ],
            "hasStatus": "ConsentStatusExplicitlyGiven",
            "isProvidedTo": "https://id.<ESS DOMAIN>/requestingrabbit"
          },
          "id": "https://id.<ESS DOMAIN>/owliverowner"
      }
   }
}
```

The filter’s **`verifiableCredential`** field contains the following non-empty fields for matching [user-associated Access Grants](#behavior):

* **`type`** that matches an array that includes both **`"VerifiableCredential"`** and **`"SolidAccessGrant"`** as elements, **AND**
* **`credentialSubject.providedConsent`**
  * **`.mode`** that matches the value **`"Read"`**, **AND**
  * **`.hasStatus`** that matches the value **`"ConsentStatusExplicitlyGiven"`** , **AND**
  * **`.isProvidedTo`** that matches the value **`"https://id.<ESS DOMAIN>/requestingrabbit"`** , **AND**
* **`credentialSubject.id`** that matches the value **`"https://id.<ESS DOMAIN>/owliverowner"`** .

For **`owliverowner`** or **`requestingrabbit`** , the endpoint returns a VP with the matching Access Grants.

For other users, the endpoint returns a VP with **no** matching Access Grants.

Or the field matches an array that includes the specified values as elements.

### Example 2

The following filter queries for [user-associated Access Grants](#behavior) that gives **`Write`** access to the specified resource.

```json
{
  "verifiableCredential": {
     "@context": [
       "https://www.w3.org/2018/credentials/v1",
       "https://schema.inrupt.com/credentials/v2.jsonld"
     ],
      "type": [
          "SolidAccessGrant"
     ],
     "credentialSubject": {
        "providedConsent": {
           "mode": "http://www.w3.org/ns/auth/acl#Write",
           "forPersonalData": [
             "https://storage.<ESS Domain>/<Root Container>/getting-started/readingList/myList"
           ]
        }
     }
  }
}
```

The filter’s **`verifiableCredential`** field contains the following non-empty fields for matching:

* **`type`** that matches **`"SolidAccessGrant"`** value as an element, **AND**
* **`credentialSubject.providedConsent`**
  * **`.mode`** that matches the value **`"http://www.w3.org/ns/auth/acl#Write"`**, **AND**
  * **`.forPersonalData`** that matches the value **`"https://storage.<ESS Domain>/<Root Container>/getting-started/readingList/myList"`**.

When the filter is posted to the **`/derive`** endpoint by either the resource owner of the reading list or by a user who has been granted access to that reading list:

* For the resource owner, the endpoint returns a VVP with all the matching Access Grants given by the resource owner for that resource (regardless of the recipients).
* For a user who is a recipient, the endpoint returns a VP with all the matching Access Grants given to the user for that resource.
* For other users, the endpoint returns a VP with **no** matching Access Grants.

Upon completion, the endpoint returns a VP with the matching VCs.

Or the field matches an array that includes the specified values as elements.

### Empty Filter Paths

ESS Access Grant service performs a match only on non-empty [**`id`**](#id), [**`credentialSubject`**](#credentialsubject) , [**`issuer`**](#issuer) , and [**`type`**](#type) field paths. Otherwise, the service returns all Access Requests/Grants associated with the user.

For example, when the following payloads are posted to the **`/derive`** endpoint:

* The filter’s **`verifiableCredential`** field is an empty document; i.e., the filter VC does not contain any of the fields used for matching:

  ```json
  {
    "verifiableCredential": { }
  }
  ```

  This would match all Access Requests VCs and Access Grants VCs associated with the user.
* The filter’s **`verifiableCredential`** contains **`type`** value of **`"VerifiableCredential"`** and empty values for the query field **`credentialSubject.hasConsent`** and no other filtering fields. As such, the filter VC does not have any non-empty matching filter paths

  ```json
  {
    "verifiableCredential": {
       "@context": [
         "https://www.w3.org/2018/credentials/v1",
         "https://schema.inrupt.com/credentials/v2.jsonld"
       ],
       "type": [
            "VerifiableCredential"
       ],
       "credentialSubject": {
         "hasConsent": { }
       }
    }
  }
  ```

  This would match all Access Requests VCs and Access Grants VCs associated with the user.
* The filter’s **`verifiableCredential`** contains **`type`** value of **`"VerifiableCredential"`** and an empty values for the query field **`credentialSubject.providedConsent`** and no other filtering fields:

  <pre class="language-json"><code class="lang-json">  {
      "verifiableCredential": {
         "@context": [
           "https://www.w3.org/2018/credentials/v1",
           "https://schema.inrupt.com/credentials/v2.jsonld",
           "https://w3id.org/security/data-integrity/v1",
           "https://w3id.org/vc-revocation-list-2020/v1",
           "https://w3id.org/vc/status-list/2021/v1",
           "https://w3id.org/security/suites/ed25519-2020/v1"
         ],
         "credentialStatus": {
           "id": "https://vc./status/VfaR#98",
           "revocationListCredential": "https://vc.&#x3C;ESS DOMAIN>/status/VfaR",
           "revocationListIndex": "98",
           "type": "RevocationList2020Status"
         },
  <strong>       "credentialSubject": {
  </strong><strong>         "providedConsent": { }
  </strong><strong>       },
  </strong><strong>       "type": [  "VerifiableCredential" ]
  </strong><strong>    }
  </strong>  }
    
  </code></pre>

Upon completion, the endpoint returns a VP with the matching VCs; in this case, all Access Requests VCs and Access Grants VCs associated with the user.

The [VC API specification](https://w3c-ccg.github.io/vc-api/#derive-credential) is in Draft status. Features based on draft specifications are subject to change.
