# Manage Access Requests

This page details how an agent can use Inrupt’s [solid-client-access-grants library](https://inrupt.github.io/solid-client-access-grants-js/) to request access to Pod Resources. This Access Request includes the specific access mode requested (e.g., read, write, append), the resources to access, etc.

{% hint style="info" %}
**Access Requests and Grants**

The following Inrupt products are available to support Access Requests and Grants:

* **`solid-client-access-grants`** library for managing Access Requests and Grants
* Inrupt’s Enterprise Solid Server provides support for [Access Requests and Grants](/security/authorization/access-requests-grants.md). ESS serializes the Access Requests and Grants as Verifiable Credentials.
* Inrupt’s [Authorization Management Component](/security/authorization/access-requests-grants.md#authorization-management-component-amc) supports Access Request management.
  {% endhint %}

### Requesting Access to Containers

Access Request and Grants for a [Container](/reference/glossary.md#container) applies both to the Container and its descendants unless explicitly specified otherwise in the request with an **`inherit: false`**.

To specify the **inherit** field in the request, **`@inrupt/solid-client-access-grants-js`** adds an **`inherit`** option to [issueAccessRequest](https://inrupt.github.io/solid-client-access-grants-js/functions/index.issueAccessRequest.html). Set **`inherit: false`** to create a request for the Container only.

### solid-client-access-grants API

Inrupt’s [solid-client-access-grants library](https://inrupt.github.io/solid-client-access-grants-js/) provides various functions for issuing Access Requests and exercising Access Grants; for example:

<table><thead><tr><th width="266.55078125">Key</th><th>Description</th></tr></thead><tbody><tr><td><a href="https://inrupt.github.io/solid-client-access-grants-js/functions/index.issueAccessRequest.html"><code>issueAccessRequest</code></a></td><td><p>Creates an Access Request, serialized as a signed <a href="/pages/7PKZaxnnUDGdJ8gPDOqL#verifiable-credential">Verifiable Credential</a>.</p><p>Server-side code can use the function to create Access Requests.</p></td></tr><tr><td><a href="https://inrupt.github.io/solid-client-access-grants-js/functions/index.redirectToAccessManagementUi.html">redirectToAccessManagementUi</a></td><td><p>Redirects the resource owners to their <a href="/pages/7PKZaxnnUDGdJ8gPDOqL#access-management-application">access management application</a> (e.g., Inrupt’s <a href="/pages/nzZgNhwDek5fJNZxuYts#authorization-management-component-amc">Authorization Management Component</a>).</p><p>The requestor code can use the function to redirect the resource owner to the access management application where the owner can grant or deny access. If called server-side, a <strong><code>redirectCallback</code></strong> must be passed in the options for the library to handle redirection depending on the Web framework.</p><p>The access management application returns the resource owners to the URL specified in the function call.</p></td></tr><tr><td><a href="https://inrupt.github.io/solid-client-access-grants-js/functions/index.getSolidDataset.html">getSolidDataset</a></td><td>Uses the Access Grants to retrieve a SolidDataset.</td></tr><tr><td><a href="https://inrupt.github.io/solid-client-access-grants-js/functions/index.saveSolidDatasetAt.html">saveSolidDatasetAt</a></td><td>Uses the Access Grants to save a SolidDataset.</td></tr><tr><td><a href="https://inrupt.github.io/solid-client-access-grants-js/functions/index.getFile.html">getFile</a></td><td>Uses the Access Grant to retrieve a file.</td></tr></tbody></table>

### Requesting Access

The following example implements the code for the access requestor (i.e., ExamplePrinter) in the example introduced in [Access Requests and Grants](/sdk/javascript-sdk/access-requests-and-grants.md).

To start the Access Request flow:

1. ExamplePrinter’s client-side code calls on its server-side application to create an Access Request.
2. The server-side application can use [issueAccessRequest](https://inrupt.github.io/solid-client-access-grants-js/functions/index.issueAccessRequest.html) to create an Access Request for the photos belonging to the **`resourceOwner`** (in this example, **`"https://id.example.com/snoringsue"`**);

   ```javascript
   async function requestAccessToPhotos(photosToPrint, resourceOwner){

     // ExamplePrinter sets the requested access (if granted) to expire in 5 minutes.
     let accessExpiration = new Date( Date.now() +  5 * 60000 );

     // Call `issueAccessRequest` to create an Access Request
     //
     const requestVC = await issueAccessRequest(
         {
            "access":  { read: true },
            "resources": photosToPrint,   // Array of URLs
            "resourceOwner": resourceOwner,
            "expirationDate": accessExpiration,
            "purpose": [ "https://example.com/purposes#print" ]
         },
         { fetch : session.fetch } // From the requestor's (i.e., ExamplePrinter's) authenticated session
     );
   }
   ```
3. After having received the Access Request, the requestor calls [redirectToAccessManagementUi](https://inrupt.github.io/solid-client-access-grants-js/functions/index.redirectToAccessManagementUi.html) to redirect the user to the user’s [access management application](/reference/glossary.md#access-management-application). Pass to the function:

   * the **`id`** of the request (in this example, the **`id`** of the Access Request VC) and
   * the URL to which the access management application should return the user after the Access Request has been granted or denied.

   The following example is for a client-side call, and it includes an optional **`fallbackAccessManagementUI`** option that specifies Inrupt’s [Authorization Management Component](/security/authorization/access-requests-grants.md#authorization-management-component-amc) as the default access management application.

   ```javascript
   // Call `redirectToAccessManagementUi` to redirect to
   // the user's access management app, defaulting to AMC if not set.
   // The user logs into the access management application and decides to grant or deny the request.

   redirectToAccessManagementUi(
      requestVC.id,
      "https://www.example.net/exampleprinter/returnwithgrantVC/",
      {
        fallbackAccessManagementUi: "https://amc.inrupt.com/accessRequest",
        fetch : session.fetch // From the requestor's (i.e., ExamplePrinter's) authenticated session
      }
   );
   ```

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

If the call is made on the server-side, also include the **`redirectCallback`** option.
{% endhint %}

4. At this point, the user is redirected away from the requesting app (e.g., ExamplePrinter app) to the user’s Access Management app, where they will either approve or deny the Access Request. The Access Management app will then redirect the user back to the URL provided in the call to [redirectToAccessManagementUi](https://inrupt.github.io/solid-client-access-grants-js/functions/index.redirectToAccessManagementUi.html).
5. Upon redirect, the URL will include add a query parameter with the id of the approved Access Grant. The requesting app can use [getAccessGrantFromRedirectUrl](https://inrupt.github.io/solid-client-access-grants-js/functions/index.getAccessGrantFromRedirectUrl.html) to get the Access Grant.

With an approved Access Grant, the requestor can access the resource. See [Use Access Grants to Access Resources](/sdk/javascript-sdk/access-requests-and-grants/use-access-grants-to-access-resources.md).

### Adding custom fields to an Access Request

Access Requests are based on a use-case-agnostic data model, and capture information about access to resources. However, it is also useful to be able to tie Access Requests and Access Grants into business-specific processes, which requires the core data model to have extension points.

**`@inrupt/solid-client-access-grants`** supports adding custom fields to an Access Request. **`issueAccessRequest`** has a new **`customFields`** option, accepting a set of **`CustomField`**. A **`CustomField`** is a key/value entry where the key MUST be a URL, and the value a literal (**`string`**, **`boolean`** or **`number`**). The provided values are embedded within the issued Access Request.

If an incorrect **`CustomField`** value is provided, **`AccessGrantError`** is thrown. Invalid **`CustomField`** definitions include not using a **`URL`** as a key, or not using a literal as a value. The TypeScript typing is provided as a guideline.

```javascript
async function requestAccessToPhotos(photosToPrint, resourceOwner){

   // requestVC will have the provided custom fields in addition
   // to the regular fields for Access Requests.
   const requestVC = await issueAccessRequest(
      {
         "access":  { read: true },
         "resources": photosToPrint,
         "resourceOwner": resourceOwner,
         "purpose": [ "https://example.com/purposes#print" ]
      },
      {
         fetch : session.fetch,
         // ExamplePrinter can add custom fields that are relevant
         // to its own application into the Access Request.
         customFields: new Set([{
            key: new URL("https://example.com/printer/orderId"),
            value: "my-order-id"
         }]),
      }
   );
}
```

### Querying for Access Requests

In **`@inrupt/solid-client-access-grants@v3.2.0`**, the application can use the **`query`** function to query for active (i.e., current and not expired) Access Requests made to a user. To use **`query`** for Access Requests, you can pass in a **`AccessRequestFilter`** object that specifies the query filter values (i.e., a combination of the resource, creator, recipient, purpose, and type).

The **`AccessRequestFilter`** object has the following fields:

<table><thead><tr><th width="163.56640625">Key</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>type</code></strong></td><td>The Access Credential type (in this case, <strong><code>SolidAccessRequest</code></strong>).</td></tr><tr><td><strong><code>status</code></strong></td><td><p>Optional. Include a credential status in the query object. The following values are supported for Access Requests:</p><ul><li><strong><code>Pending</code></strong> returns all Access Requests that have neither been granted, denied or canceled.</li><li><strong><code>Granted</code></strong> returns all Access Requests that have been granted by the resource owner.</li><li><strong><code>Denied</code></strong> returns all Access Requests that have been denied by the resource owner.</li><li><strong><code>Canceled</code></strong> returns all Access Requests that have been canceled by the requesting agent.</li></ul></td></tr><tr><td><strong><code>fromAgent</code></strong></td><td>Optional. Include the creator of the Access Request in the query filter. This is the requestor. In the example, the creator value is the ExamplePrinter’s WebID <strong><code>https://id.example.com/examplePrinter</code></strong>.</td></tr><tr><td><strong><code>toAgent</code></strong></td><td>Optional. Include the recipient of the Access Request in the query filter. This is the resource owner.</td></tr><tr><td><strong><code>resource</code></strong></td><td>Optional. Include the resource in the query object. Use this filter to return Access Requests bound to a specific resource.</td></tr><tr><td><strong><code>purpose</code></strong></td><td>Optional. Include a purpose in the query object. Use this filter to return Access Requests bound to a specific purpose.</td></tr><tr><td><strong><code>issuedWithin</code></strong></td><td><p>Optional. Include a time constraint on the issuance date in the query object. All matched credentials will have been issued within the provided duration value. Certain time constraints are available for use with this method, including:</p><ul><li><strong><code>P1D</code></strong> One day (<strong><code>DURATION.ONE_DAY</code></strong>)</li><li><strong><code>P7D</code></strong> Seven days (<strong><code>DURATION.ONE_WEEK</code></strong>)</li><li><strong><code>P1M</code></strong> One month (<strong><code>DURATION.ONE_MONTH</code></strong>)</li><li><strong><code>P3M</code></strong> Three months (<strong><code>DURATION.THREE_MONTH</code></strong>)</li></ul></td></tr><tr><td><strong><code>revokedWithin</code></strong></td><td><p>Optional. Include a time constraint on the revocation date in the query object. All matched credentials will have been revoked or canceled within the provided duration value. Certain time constraints are available for use with this method, including:</p><ul><li><strong><code>P1D</code></strong> One day (<strong><code>DURATION.ONE_DAY</code></strong>)</li><li><strong><code>P7D</code></strong> Seven days (<strong><code>DURATION.ONE_WEEK</code></strong>)</li><li><strong><code>P1M</code></strong> One month (<strong><code>DURATION.ONE_MONTH</code></strong>)</li><li><strong><code>P3M</code></strong> Three months (<strong><code>DURATION.THREE_MONTH</code></strong>)</li></ul></td></tr></tbody></table>

The result is paginated, so the agent may need to make multiple calls to the **`query`** function to get all of the Access Requests matching the provided filter.

The following example queries for active Access Requests made by ExamplePrinter for a given resource.

```javascript
const page1 = await query({
   type: "SolidAccessRequest",
   status: "Pending",
   fromAgent: new URL("https://id.example.com/ExamplePrinter"),
}, {
   fetch: session.fetch,
   queryEndpoint: new URL("https://vc.example.org/query"),
});
if (page1.next !== undefined) {
   const page2 = await query(page1.next, {
      fetch: session.fetch,
      queryEndpoint: new URL("https://vc.example.org/query"),
   });
}
```

**`paginatedQuery`** is a utility provided for iterating through the result pages:

```javascript
const pages = paginatedQuery({
    type: "SolidAccessRequest",
    status: "Pending",
    fromAgent: new URL("https://id.example.com/ExamplePrinter"),
 }, {
    fetch: session.fetch,
    queryEndpoint: new URL("https://vc.example.org/query"),
 });
let i = 0;
for await (const page of pages) {
    console.log(`Page ${i} has ${page.items.length} items.`)
    i += 1;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.inrupt.com/sdk/javascript-sdk/access-requests-and-grants/manage-access-requests.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
