# /issue Endpoint

ESS supports an [authorization mechanism based on Access Requests and Grants](https://docs.inrupt.com/security/authorization/access-requests-grants). The Access Requests and Access Grants include the specific access mode (e.g. **`Read`**, **`Write`**, **`Append`**), the resources to access, etc.

{% hint style="warning" %}
**Important**

* An Access Request for a [Container](https://docs.inrupt.com/reference/glossary#container), by default, also applies to the Container’s descendants, unless explicitly specified otherwise in the request (See [inherit: false](#input-access-request-shape)).
* An Access Grant for a Container, by default, also applies to the Container’s descendants, unless explicitly specified otherwise in the grant (See [inherit: false](#input-access-request-shape)).
  {% endhint %}

ESS serializes the Access Requests and Grants as [Verifiable Credentials (VCs)](https://docs.inrupt.com/reference/glossary#verifiable-credential) and provides an endpoint that issues Access Requests and Grants as VCs.

## `/issue` Endpoint

The ESS [Access Grant Service](https://docs.inrupt.com/ess/latest/services/service-access-grant) provides an endpoint for issuing Access Requests and Grants as VCs. By default, it takes this form:

```json
https://vc.<ESS Domain>/issue
```

{% hint style="info" %}
**Note**

To access the **`/issue`** endpoint:

* Users must 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).
* For Access Requests, users must use an application whose Client ID is allowed by the [**`INRUPT_VC_CLIENT_ID_ALLOW_LIST_SOLIDACCESSREQUEST`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_client_id_allow_list_solidaccessrequest) setting.
* For Access Grants, users must use an application whose Client ID is allowed by the [**`INRUPT_VC_CLIENT_ID_ALLOW_LIST_SOLIDACCESSGRANT`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_client_id_allow_list_solidaccessgrant) setting.
  {% endhint %}

The ESS Access Grant Service’s **`/issue`** endpoint (also referred to as the Issuer on this page) implements the issuer portion of the [VC API specification](https://w3c-ccg.github.io/vc-api/#issue-credential).

{% hint style="info" %}
The [VC API specification](https://w3c-ccg.github.io/vc-api/#issue-credential) is in Draft status. Features based on draft specifications are subject to change.
{% endhint %}

## Access Request VCs

To acquire a VC for an Access Requests, clients can send their requests to the Issuer endpoint (**`/issue`**).

<table data-header-hidden><thead><tr><th width="161.00640869140625"></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>/issue</code></strong></td></tr><tr><td>Payload</td><td>Access Request object that conforms to the <a href="#input-access-request-shape">ESS Access Request Shape</a>.</td></tr></tbody></table>

### Input: Access Request Shape

ESS defines two shapes (shown below in JSON-LD representation) for an Access Request.

The first shape defines a particular data subject and location, if these values are known:

```json
{
  "credential": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://schema.inrupt.com/credentials/v2.jsonld"
    ],
    "credentialSubject": {
      "hasConsent": {
        "mode": <Access Mode URL | Array of Access Mode URLs>,
        "hasStatus": "https://w3id.org/GConsent#ConsentStatusRequested",
        "isConsentForDataSubject": <Resource Owner WebID>,
        "forPersonalData": <Resource URL | Array of Resource URLS>,
        "inherit": <Optional. true|false>
      }
    }
  }
}
```

The second shape defines a location template with or without a particular data subject:

```json
{
  "credential": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://schema.inrupt.com/credentials/v2.jsonld"
    ],
    "credentialSubject": {
      "hasConsent": {
        "mode": <Access Mode URL | Array of Access Mode URLs>,
        "hasStatus": "https://w3id.org/GConsent#ConsentStatusRequested",
        "template": <URL Template | Array of URL Templates>,
        "isConsentForDataSubject": <Optional. Resource Owner WebID>,
        "inherit": <Optional. true|false>
      }
    }
  }
}
```

{% hint style="success" %}
Added in version 2.7.0
{% endhint %}

A URL template is formatted according to [RFC 6570](https://datatracker.ietf.org/doc/html/rfc6570), such as: **`https://{+storage}/data`**. A template will be used by a client library to insert a particular storage root when creating an Access Grant.

Access Requests sent to the endpoint must conform to these shapes. That is, specific to the Issuer:

* **`@context`** must include the [ESS Access Grant VC Context ](https://docs.inrupt.com/ess/latest/services/service-access-grant/access-grant-vc-jsonld-context)**`"https://schema.inrupt.com/credentials/v2.jsonld"`** and the standard VC context **`"https://www.w3.org/2018/credentials/v1"`**.

{% hint style="info" %}
**Note**

The [ESS Access Grant VC Context](https://docs.inrupt.com/ess/latest/services/service-access-grant/access-grant-vc-jsonld-context) can be found at **`"https://schema.inrupt.com/credentials/v2.jsonld"`**.
{% endhint %}

* **`credentialSubject.hasConsent`**
  * Must include:

    <table data-header-hidden><thead><tr><th width="243.7982177734375"></th><th></th></tr></thead><tbody><tr><td><strong><code>mode</code></strong></td><td><p>Set to a single <a href="../../../../../reference/glossary#acl">ACL</a> Mode or an array of ACL Modes where the Modes are:</p><ul><li><strong><code>"Read"</code></strong></li><li><strong><code>"Write"</code></strong></li><li><strong><code>"Append"</code></strong></li></ul></td></tr><tr><td><strong><code>hasStatus</code></strong></td><td>Set to the following <a href="https://w3id.org/GConsent">https://w3id.org/GConsent</a> status: <strong><code>"ConsentStatusRequested"</code></strong>.</td></tr><tr><td><strong><code>isConsentForDataSubject</code></strong></td><td>Set to the WebID of the resource owner. This is optional if the <code>template</code> property is used.</td></tr></tbody></table>
  * Must include one, but not both, of the following:

    <div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>If a target resource is a <a href="../../../../../reference/glossary#container">Container</a>, the requested access, by default, encompasses both the Container and its descendants.</p><p>See the inherit field description (below).</p></div>

    <table data-header-hidden><thead><tr><th width="243.7982177734375"></th><th></th></tr></thead><tbody><tr><td><strong><code>forPersonalData</code></strong></td><td>Set to the URL of the target resource or an array of URLs if specifying multiple target resources.</td></tr><tr><td><strong><code>template</code></strong></td><td><p>Set to a URL template for a target resource or an array of URL templates if specifying multiple resources.</p><div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>A URL template can be used when a particular storage or resource owner is not known in advance. A client library will fill in these details when creating an Access Grant.</p></div></td></tr></tbody></table>
  * May include the optional:

    <table data-header-hidden><thead><tr><th width="245.90057373046875"></th><th></th></tr></thead><tbody><tr><td><strong><code>inherit</code></strong></td><td><p>Set to a boolean to determine whether the access request on a Container should also encompass the resources within the Container (i.e., the Container’s descendants). That is, set to:</p><ul><li><strong><code>true</code></strong> if the requested access on a Container encompasses both the Container and its descendants.</li><li><strong><code>false</code></strong> if the requested access on a Container is only for the Container itself.</li></ul><p>Default is <strong><code>true</code></strong>; i.e., if omitted, the access request on a Container encompasses both the Container and its descendants.</p></td></tr></tbody></table>

### Input: Additional Fields

The following fields are optional:

* **`credentialSubject.hasConsent.forPurpose`** field that contains the purpose for the access. For its value, specify a URL or an array of URLs indicating the purpose.
* **`credentialSubject.inbox`** is set to the URL of the requesting agent’s inbox. If included, the field can only have one inbox.
* **`credentialSubject.id`** field that contains the requesting agent’s WebID.

{% hint style="info" %}
Regardless of the **`credentialSubject.id`** field’s inclusion or its value in the request, the ESS Access Grant service issues a signed VC with the **`credentialSubject.id`** value set to the requesting agent’s WebID. That is, the Issuer overrides the field’s value if set. If unset, the Issuer adds the field.
{% endhint %}

* **`issuanceDate`** field that contains the start date and time when the requested access is to take effect; i.e., becomes valid.

  If omitted, the Issuer specifies the date and time it issues the VC.
* **`expirationDate`** field that contains the date and time at which the requested access expires; i.e., becomes invalid. This field value is compared with an expiration date calculated by the ESS Access Grant service and the earlier of the two dates is used.

  If **`expirationDate`** is included in the request and

  * ESS Access Grant service has **`INRUPT_VC_MAX_DURATION`** set,
    * The Issuer calculates a date based on the duration value and uses the earlier of the calculated date and the specified **`expirationDate`**.
  * ESS Access Grant service does not have **`INRUPT_VC_MAX_DURATION`** set,
    * The Issuer calculates the expiration date using **`P365D`** (365 days) as the duration, and uses the earlier of the calculated date and the specified **`expirationDate`**.

  If **`expirationDate`** is not included in the request and

  * ESS Access Grant service has **`INRUPT_VC_MAX_DURATION`** set,
    * The Issuer calculates the expiration date based on the duration value.
  * ESS Access Grant service does not have **`INRUPT_VC_MAX_DURATION`** set,
    * The Issuer uses a default value of **`P365D`** (365 days) for the **`expirationDate`**.

See also: [VC Issuer API (OpenAPI specification)](https://w3c-ccg.github.io/vc-api/issuer.html#operation/issueCredential)

## Access Grant VCs

The resource owner can deny or grant the Access Request. To acquire a VC for the Access Grants, clients can send the resource owner’s requests to the Issuer endpoint (**`/issue`**).

<table data-header-hidden><thead><tr><th width="153.0234375"></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>/issue</code></strong></td></tr><tr><td>Payload</td><td>Access Grant object that conforms to <a href="#input-access-request-shape">ESS Access Grant Shape</a>.</td></tr></tbody></table>

### Access Grant Effective Period

An active (i.e., not revoked) access grant is effective:

* Starting from its **`issuanceDate`** to its **`expirationDate`**, and
* While its **`credentialSubject.id`** (the grantor) remains a resource owner.

### Input: Access Grant Shape

ESS defines a shape constraint (shown below in JSON-LD representation) for the Access Grant:

```json
{
  "credential": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://schema.inrupt.com/credentials/v2.jsonld"
    ],
    "credentialSubject": {
      "providedConsent": {
        "mode": <Access Mode IRI | Array of Access Mode IRIs>,
        "hasStatus": "https://w3id.org/GConsent#ConsentStatusExplicitlyGiven",
        "forPersonalData": <ResourceIRI | Array of Resource IRIS>,
        "isProvidedTo": <WebID>,
        "verifiedRequest": <Optional. Granted Access Request IRI>,
        "inherit": <Optional. true|false>
      }
    }
  }
}
```

With the shape constraint, Access Grants sent to the endpoint must conform to the shape. That is, specific to the Issuer:

* **`@context`** must include the [ESS Access Grant VC Context](https://docs.inrupt.com/ess/latest/services/service-access-grant/access-grant-vc-jsonld-context); e.g., **`"https://schema.inrupt.com/credentials/v2.jsonld"`**.

{% hint style="info" %}
The [ESS Access Grant VC Context](https://docs.inrupt.com/ess/latest/services/service-access-grant/access-grant-vc-jsonld-context) can be found at **`"https://schema.inrupt.com/credentials/v2.jsonld"`**
{% endhint %}

* **`credentialSubject.providedConsent`**
  * Must include:

    <table data-header-hidden><thead><tr><th width="190.47796630859375"></th><th></th></tr></thead><tbody><tr><td><strong><code>mode</code></strong></td><td>Set to a single <a href="../../../../../reference/glossary#acl">ACL</a> Mode or an array of Modes; e.g., <strong><code>"Read"</code></strong> or <strong><code>[ "Read", "Write"]</code></strong>.</td></tr><tr><td><strong><code>hasStatus</code></strong></td><td>Must be set to the following <a href="https://w3id.org/GConsent">https://w3id.org/GConsent</a> value: <strong><code>"ConsentStatusExplicitlyGiven"</code></strong>.</td></tr><tr><td><strong><code>forPersonalData</code></strong></td><td><p>Set to the IRI of the target resource or an array of IRIs if specifying multiple target resources.</p><div data-gb-custom-block data-tag="hint" data-style="info" class="hint hint-info"><p>If a target resource is a <a href="../../../../../reference/glossary#container">Container</a>, the Access Grant, by default, encompasses both the Container and its descendants.<br><br>See the inherit field description (below).</p></div></td></tr><tr><td><strong><code>isProvidedTo</code></strong></td><td>Set to the WebID of the agent to whom access is being granted.</td></tr></tbody></table>
  * May include the optional:

    <table data-header-hidden><thead><tr><th width="190.343017578125"></th><th></th></tr></thead><tbody><tr><td><strong><code>inherit</code></strong></td><td><p>Set to a boolean to determine whether the Access Grant on a Container should also apply to the resources within the Container (i.e., the Container’s descendants). That is, set to:</p><ul><li><strong><code>true</code></strong> if the Access Grant on a Container applies to both the Container and its descendants.</li><li><strong><code>false</code></strong> if the Access Grant on a Container is only for the Container itself.</li></ul><p>Default is <strong><code>true</code></strong>; i.e., if omitted, the Access Grant on a Container applies to both the Container and its descendants.</p></td></tr><tr><td><strong><code>verifiedRequest</code></strong></td><td><p>Set to an Access Request IRI to trace which Access Request would be granted by the present Access Grant. The Access Request is validated by the server to enforce the following:</p><ol><li>The same Access Request has not been granted or denied already</li><li>The Access Request has not expired</li><li>The Access Request has not been revoked</li></ol><p>The Access Grant will only be issued if all of the above are true. After the Access Grant has been issued, the status of the Access Request will change from <strong><code>Pending</code></strong> to <strong><code>Granted</code></strong> at the <a href="../service-access-grant-query#status-values"><strong><code>/query</code></strong> endpoint</a>.<br></p><p>Note that <strong><code>verifiedRequest</code></strong> takes precedence over the legacy <strong><code>request</code></strong> predicate.</p></td></tr></tbody></table>

### Input: Additional Fields

The following fields are optional:

* **`credentialSubject.providedConsent.forPurpose`** field that contains the purpose for the access. For its value, specify a URL or an array of URLs indicating the purpose.
* **`issuanceDate`** field that contains the start date and time when the access grant is to take effect; i.e., becomes valid. The value can be in the future.

  If omitted, the Issuer specifies the date and time it issues the VC.
* **`expirationDate`** field that contains the date and time at which the access grant expires; i.e., becomes invalid. This field value is compared with an expiration date calculated by the ESS Access Grant service and the earlier of the two dates is used.

  If **`expirationDate`** is included in the payload and

  * ESS Access Grant service has [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) set,
    * The Issuer calculates a date based on the duration value and uses the earlier of the calculated date and the specified **`expirationDate`**.
  * ESS Access Grant service does not have [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) set,
    * The Issuer calculates the expiration date using **`P365D`** (365 days) as the duration, and uses the earlier of the calculated date and the specified **`expirationDate`**.

  If **`expirationDate`** is not included in the access grant and

  * ESS Access Grant service has [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) set,
    * The Issuer calculates the expiration date based on the duration value.
  * ESS Access Grant service does not have [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) set,
    * The Issuer uses a default value of **`P365D`** (365 days) for the **`expirationDate`**.

See also: [VC Issuer API (OpenAPI specification)](https://w3c-ccg.github.io/vc-api/issuer.html#operation/issueCredential)

## Access Denial VCs

The resource owner can deny or grant the Access Request. To acquire a VC for the Access Denial, clients can send the resource owner’s requests to the Issuer endpoint (**`/issue`**).

<table data-header-hidden><thead><tr><th width="153.0234375"></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>/issue</code></strong></td></tr><tr><td>Payload</td><td>Access Denial object that conforms to <a href="#input-access-request-shape">ESS Access Denial Shape</a>.</td></tr></tbody></table>

### Access Denial Effective Period

An active (i.e., not revoked) Access Denial is effective:

* Starting from its **`issuanceDate`** to its **`expirationDate`**, and
* While its **`credentialSubject.id`** (the grantor) remains a resource owner.

### Input: Access Denial Shape

ESS defines a shape constraint (shown below in JSON-LD representation) for the Access Denial:

```json
{
  "credential": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://schema.inrupt.com/credentials/v2.jsonld"
    ],
    "credentialSubject": {
      "providedConsent": {
        "mode": <Access Mode IRI | Array of Access Mode IRIs>,
        "hasStatus": "https://w3id.org/GConsent#ConsentStatusDenied",
        "forPersonalData": <ResourceIRI | Array of Resource IRIS>,
        "isProvidedTo": <WebID>,
        "verifiedRequest": <Optional. Denied Access Request IRI>
      }
    }
  }
}
```

With the shape constraint, Access Denials sent to the endpoint must conform to the shape. That is, specific to the Issuer:

* **`@context`** must include the [ESS Access Grant VC Context](https://docs.inrupt.com/ess/latest/services/service-access-grant/access-grant-vc-jsonld-context); e.g., **`"https://schema.inrupt.com/credentials/v2.jsonld"`**.

\*\*Note\*\*\ The \[ESS Access Grant VC Context]\(../../services/service-access-grant/access-grant-vc-jsonld-context.md) can be found at \*\*\`"<https://schema.inrupt.com/credentials/v2.jsonld"\\`\\*\\>\* {% endhint %\\}

* **`@context`** must include the [ESS Access Grant VC Context](https://docs.inrupt.com/ess/latest/services/service-access-grant/access-grant-vc-jsonld-context); e.g., **`"https://schema.inrupt.com/credentials/v2.jsonld"`**.

The following fields are optional:

* **`credentialSubject.providedConsent.forPurpose`** field that contains the purpose for the denied access. For its value, specify a URL or an array of URLs indicating the purpose.
* **`issuanceDate`** field that contains the start date and time when the Access Denial is to take effect; i.e., becomes valid. The value can be in the future.

  If omitted, the Issuer specifies the date and time it issues the VC.
* **`expirationDate`** field that contains the date and time at which the Access Denial expires; i.e., becomes invalid. This field value is compared with an expiration date calculated by the ESS Access Grant service and the earlier of the two dates is used.

  If **`expirationDate`** is included in the payload and

  * ESS Access Grant service has [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) set,
    * The Issuer calculates a date based on the duration value and uses the earlier of the calculated date and the specified **`expirationDate`**.
  * ESS Access Grant service does not have [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) set,
    * The Issuer calculates the expiration date using **`P365D`** (365 days) as the duration, and uses the earlier of the calculated date and the specified **`expirationDate`**.

  If **`expirationDate`** is not included in the access grant and

  * ESS Access Grant service has [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) set,
    * The Issuer calculates the expiration date based on the duration value.
  * ESS Access Grant service does not have [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) set,
    * The Issuer uses a default value of **`P365D`** (365 days) for the **`expirationDate`**.

See also: [VC Issuer API (OpenAPI specification)](https://w3c-ccg.github.io/vc-api/issuer.html#operation/issueCredential)

{% hint style="info" %}
**Note**\
The [ESS Access Grant VC Context](https://docs.inrupt.com/ess/latest/services/service-access-grant/access-grant-vc-jsonld-context) can be found at **`"https://schema.inrupt.com/credentials/v2.jsonld"`**
{% endhint %}

* **`credentialSubject.providedConsent`**
  * Must include:

    <table data-header-hidden><thead><tr><th width="190.47796630859375"></th><th></th></tr></thead><tbody><tr><td><strong><code>mode</code></strong></td><td>Set to a single <a href="../../../../../reference/glossary#acl">ACL</a> Mode or an array of Modes; e.g., <strong><code>"Read"</code></strong> or <strong><code>[ "Read", "Write"]</code></strong>.</td></tr><tr><td><strong><code>hasStatus</code></strong></td><td>Must be set to the following <a href="https://w3id.org/GConsent">https://w3id.org/GConsent</a> value: <strong><code>"ConsentStatusDenied"</code></strong>.</td></tr><tr><td><strong><code>forPersonalData</code></strong></td><td>Set to the IRI of the target resource or an array of IRIs if specifying multiple target resources.</td></tr><tr><td><strong><code>isProvidedTo</code></strong></td><td>Set to the WebID of the agent to whom access is being denied.</td></tr></tbody></table>
  * May include the optional:

    <table data-header-hidden><thead><tr><th width="190.343017578125"></th><th></th></tr></thead><tbody><tr><td><strong><code>verifiedRequest</code></strong></td><td><p>Set to an Access Request IRI to trace which Access Request would be denied by the present Access Denial. The linked Access Request is validated by the server to enforce the following:</p><ol><li>The same Access Request has not been granted or denied already</li><li>The Access Request has not expired</li><li>The Access Request has not been revoked</li></ol><p>The Access Denial will only be issued if all of the above are true. After the Access Denial has been issued, the status of the Access Request will change from <strong><code>Pending</code></strong> to <strong><code>Denied</code></strong> at the <a href="../service-access-grant-query#status-values"><strong><code>/query</code></strong> endpoint</a>.<br></p><p>Note that <strong><code>verifiedRequest</code></strong> takes precedence over the legacy <strong><code>request</code></strong> predicate.</p></td></tr></tbody></table>

### Input: Additional Fields

The following fields are optional:

* **`credentialSubject.providedConsent.forPurpose`** field that contains the purpose for the denied access. For its value, specify a URL or an array of URLs indicating the purpose.
* **`issuanceDate`** field that contains the start date and time when the Access Denial is to take effect; i.e., becomes valid. The value can be in the future.

  If omitted, the Issuer specifies the date and time it issues the VC.
* **`expirationDate`** field that contains the date and time at which the Access Denial expires; i.e., becomes invalid. This field value is compared with an expiration date calculated by the ESS Access Grant service and the earlier of the two dates is used.

  If **`expirationDate`** is included in the payload and

  * ESS Access Grant service has [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) set,
    * The Issuer calculates a date based on the duration value and uses the earlier of the calculated date and the specified **`expirationDate`**.
  * ESS Access Grant service does not have [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) set,
    * The Issuer calculates the expiration date using **`P365D`** (365 days) as the duration, and uses the earlier of the calculated date and the specified **`expirationDate`**.

  If **`expirationDate`** is not included in the access grant and

  * ESS Access Grant service has [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) set,
    * The Issuer calculates the expiration date based on the duration value.
  * ESS Access Grant service does not have [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) set,
    * The Issuer uses a default value of **`P365D`** (365 days) for the **`expirationDate`**.

See also: [VC Issuer API (OpenAPI specification)](https://w3c-ccg.github.io/vc-api/issuer.html#operation/issueCredential)

#### Output: Access Request, Grant and Denial VCs

When a credential payload is POSTed to the Issuer, a signed VC is returned with the following fields:

**`“@context”`**

The value is an array with the following values:

* **`"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`**

* The value is an object with the following fields and values:

  <table><thead><tr><th width="260.03692626953125">Field</th><th>Value</th></tr></thead><tbody><tr><td><strong><code>"id"</code></strong></td><td><p><strong><code>"https://vc.&#x3C;ESS Domain>/status/&#x3C;credential>#&#x3C;idx>"</code></strong></p><p>The URL of the revocation status for this VC.</p></td></tr><tr><td><strong><code>"revocationListCredential</code></strong></td><td><p><strong><code>"https://vc.&#x3C;ESS Domain>/status/&#x3C;credential>"</code></strong></p><p>The URL identifying the VC in the revocation list.</p></td></tr><tr><td><strong><code>"revocationListIndex</code></strong></td><td><p><strong><code>"&#x3C;idx>"</code></strong></p><p>The bit position (i.e., the index) of the VC’s revocation status.</p></td></tr><tr><td><strong><code>"type"</code></strong></td><td><strong><code>"RevocationList2020Status"</code></strong></td></tr></tbody></table>

For more information, see [RevocationList2020Status](https://w3c-ccg.github.io/vc-status-rl-2020/#revocationlist2020status).

**`credentialSubject`**

* The value is the object sent to the Issuer with the following modification:
* **`credentialSubject.id`** is set to the user posting to the Issuer.

**`id`**

* The value is the ID of the VC; i.e., the URL for the VC.

**`issuanceDate`**

* The value is the date and time the requested access is to take effect; i.e., becomes valid.
* If the field was included in the payload to the Issuer, the Issuer uses the input value.

  Otherwise, if the field was not part of the payload, the Issuer uses the date and time of issuance.

**`issuer`**

* The value is the ESS Access Grant Service URL; e.g., **`"https://vc.<ESS Domain>/"`**.

**`expirationDate`**

* The date and time at which the access request/grant expires; i.e., becomes invalid.

All issued Access Requests/Grants have an expiration date. To determine the **`expirationDate`** value, the Issuer:

* Calculates an expiration date based on the [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) value or **`P365D`** as the default duration value if the option is not set.
* If the payload specifies an **`expirationDate`** field, compares this specified value with the calculated value.
* Based on the comparison, uses the earlier of the two dates as the expirationDate.

**`proof`**

Adds the **`proof`** object with the following fields and values:

| Field                      | Value                                     |
| -------------------------- | ----------------------------------------- |
| **`"created"`**            | **`"<DateTimestamp>"`**                   |
| **`"domain"`**             | **`"solid"`**                             |
| **`"proofPurpose"`**       | **`"assertionMethod"`**                   |
| **`"proofValue"`**         | **`"<value>"`**                           |
| **`"type"`**               | **`"Ed25519Signature2020"`**              |
| **`"verificationMethod"`** | **`"https://vc.<ESS DOMAIN>/key/<key>"`** |

See [Ed25519 Signature 2020](https://w3c-ccg.github.io/lds-ed25519-2020/#ed25519-signature-2020) for description of the fields.

**`type`**

For Access Request VCs, the **`type`** field to an array with the following two values:

* **`"VerifiableCredential"`**
* **`"SolidAccessRequest"`**

For Access Grant VCs, the **`type`** field to an array with the following two values:

* **`"VerifiableCredential"`**
* **`"SolidAccessGrant"`**

See also:

* [VC Issue Credential API specification](https://w3c-ccg.github.io/vc-api/#issue-credential)
* [VC Issuer API (OpenAPI specification)](https://w3c-ccg.github.io/vc-api/issuer.html#operation/issueCredential)

## Example

### Access Request

{% hint style="info" %}
**Note**

Access to the Issuer endpoint (**`/issue`**) requires users to be authenticated.
{% endhint %}

The following example payloads meet the ESS’ [Access Request Shape](#input-access-request-shape) for the Issuer endpoint (**`/issue`**).

The following example assumes [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) is set to 90 days (**`P90D`**).

{% hint style="info" %}
**Tip**\
It is recommended that Access Request and Access Grants have an expiration.
{% endhint %}

The following payload is asking for read access to **`owliverowner`**’s resource **`https://storage.<ESS DOMAIN>/<owliversRootContainer>/some/private/data`**:

```json
{
  "credential": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://schema.inrupt.com/credentials/v2.jsonld"
    ],
    "credentialSubject": {
      "hasConsent": {
        "mode": [ "Read" ],
        "hasStatus": "ConsentStatusRequested",
        "isConsentForDataSubject": "https://id.<ESS DOMAIN>/owliverowner",
        "forPersonalData": [
          "https://storage.<ESS DOMAIN>/<owliversRootContainer>/getting-started/readingList/myList"
        ]
      }
    }
  }
}
```

When **`requestingrabbit`** posts the payload to the Issuer endpoint (**`issue`**), the Issuer returns an Access Request serialized as a signed VC:

```json
{
  "@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"
  ],
  "id": "https://vc.<ESS DOMAIN>/vc/296de1b0-380a-4b3c-8f8f-c23b96f55e2d",
  "type": [
    "VerifiableCredential",
    "SolidAccessRequest"
  ],
  "proof": {
    "type": "Ed25519Signature2020",
    "created": "2023-05-01T16:13:59.233Z",
    "domain": "solid",
    "proofPurpose": "assertionMethod",
    "proofValue": "xxxxxx........",
    "verificationMethod": "https://vc.<ESS DOMAIN>/key/xxxxx...."
  },
  "credentialStatus": {
    "id": "https://vc.<ESS DOMAIN>/status/y94G#0",
    "type": "RevocationList2020Status",
    "revocationListCredential": "https://vc.<ESS DOMAIN>/status/y94G",
    "revocationListIndex": "0"
  },
  "credentialSubject": {
    "id": "https://id.<ESS DOMAIN>/requestingrabbit",
    "hasConsent": {
      "mode": "Read",
      "forPersonalData": "https://storage.<ESS DOMAIN>/<owliversRootContainer>/getting-started/readingList/myList",
      "hasStatus": "ConsentStatusRequested",
      "isConsentForDataSubject": "https://id.<ESS DOMAIN>/owliverowner"
    }
  },
  "issuanceDate": "2023-05-01T16:13:59.044Z",
  "expirationDate": "2023-07-30T16:13:59.043962767Z",
  "issuer": "https://vc.<ESS DOMAIN>"
}
```

In the returned Access Request,

* The **`credentialSubject.id`** contains **`requestingrabbit`’s** WebID.
* The **`expirationDate`** is set to 90 days from issuance date (per [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) set to **`P90D`**).

### Access Grant

{% hint style="info" %}
**Note**

* Access to the Issuer endpoint (**`/issue`**) requires users to be authenticated.
  {% endhint %}

The following example payloads meet the ESS’ [Access Grant Shape](#input-access-grant-shape) for the Issuer endpoint (**`/issue`**).

The following example assumes [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) is set to 90 days (**`P90D`**).

{% hint style="info" %}
**Tip**

It is recommended that Access Request and Access Grants have an expiration.
{% endhint %}

The following payload grants **`requestingrabbit`** read access to **`owliverowner`**’s resource **`https://storage.<ESS DOMAIN>/<owliversRootContainer>/getting-started/readingList/myList`**:

```json
{
  "credential": {
    "@context": [
      "https://www.w3.org/2018/credentials/v1",
      "https://schema.inrupt.com/credentials/v2.jsonld"
    ],
    "credentialSubject": {
      "providedConsent": {
        "mode": ["Read"],
        "hasStatus": "ConsentStatusExplicitlyGiven",
        "forPersonalData": [
           "https://storage.<ESS DOMAIN>/<owliversRootContainer>/getting-started/readingList/myList"
         ],
        "isProvidedTo": "https://id.<ESS DOMAIN>/requestingrabbit"
      }
    }
  }
}
```

When the **`owliverowner`**, the resource owner, posts the payload to the Issuer endpoint (**`issue`**), the Issuer returns an Access Grant serialized as signed VC:

```json
{
  "@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"
  ],
  "id": "https://vc.<ESS DOMAIN>/vc/xxxxxx...",
  "type": [
    "VerifiableCredential",
    "SolidAccessGrant"
  ],
  "proof": {
    "type": "Ed25519Signature2020",
    "created": "2023-05-01T16:46:44.146Z",
    "domain": "solid",
    "proofPurpose": "assertionMethod",
    "proofValue": "xxxxxx........",
    "verificationMethod": "https://vc.<ESS DOMAIN>/key/xxxxx...."
  },
  "credentialStatus": {
    "id": "https://vc.<ESS DOMAIN>/status/VWTj#0",
    "type": "RevocationList2020Status",
    "revocationListCredential": "https://vc.<ESS DOMAIN>/status/VWTj",
    "revocationListIndex": "0"
  },
  "credentialSubject": {
    "id": "https://id.<ESS DOMAIN>/owliverowner",
    "providedConsent": {
      "mode": "Read",
      "forPersonalData": "https://storage.<owliversRootContainer>/getting-started/readingList/myList",
      "hasStatus": "ConsentStatusExplicitlyGiven",
      "isProvidedTo": "https://id.<ESS DOMAIN>/requestingrabbit"
    }
  },
  "issuanceDate": "2023-05-01T16:46:44.016Z",
  "expirationDate": "2023-07-30T16:46:44.016672206Z",
  "issuer": "https://vc.<ESS DOMAIN>"
}
```

In the returned Access Grant, the **`credentialSubject.id`** contains **`owliverowner`’s** WebID.

In the returned Access Grant,

* The **`credentialSubject.id`** contains **`owliverowner`**’s WebID.
* The **`expirationDate`** is set to 90 days from issuance date (per [**`INRUPT_VC_MAX_DURATION`**](https://docs.inrupt.com/ess/latest/services/service-access-grant/..#inrupt_vc_max_duration) set to **`P90D`**).
