# Create Access Requests/Grants

## `AccessGrantClient`

The **`inrupt-client-accessgrant`** module provides an [AccessGrantClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html) that interacts with the [ESS Access Grant Service](https://docs.inrupt.com/ess/latest/services/service-access-grant/) to create/verify/query/fetch Access Requests and Grants.

To interact with the service, the [AccessGrantClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html) has the following methods:

<table><thead><tr><th width="290.54296875">Method</th><th>Description</th></tr></thead><tbody><tr><td><a href="https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#requestAccess(com.inrupt.client.accessgrant.AccessRequest.RequestParameters)">AccessGrantClient.requestAccess</a></td><td>Creates Access Requests.</td></tr><tr><td><a href="https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#grantAccess(com.inrupt.client.accessgrant.AccessRequest)">AccessGrantClient.grantAccess</a></td><td>Creates Access Grants.</td></tr><tr><td><a href="https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#revoke(com.inrupt.client.accessgrant.AccessCredential)">AccessGrantClient.revoke</a></td><td>Updates the status of the Access Requests/Grantss to revoked.</td></tr><tr><td><a href="https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#query(com.inrupt.client.accessgrant.AccessCredentialQuery)">AccessGrantClient.query</a></td><td>Queries for Access Requests and Grants.</td></tr><tr><td><a href="https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#denyAccess(com.inrupt.client.accessgrant.AccessRequest)">AccessGrantClient.denyAccess</a></td><td>Creates Access Request denials.</td></tr><tr><td><a href="https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#verify(com.inrupt.client.accessgrant.AccessCredential)">AccessGrantClient.verify</a></td><td>Performs <a href="https://docs.inrupt.com/ess/latest/services/service-access-grant/service-access-grant-verifier/">validation checks</a> on Access Requests/Grantss, such as signature validation, date validation, etc.</td></tr></tbody></table>

To instantiate an [AccessGrantClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html), you need to pass in the URI of the ESS Access Grant Service. For example, the Access Grant service for Inrupt’s [PodSpaces](https://docs.inrupt.com/podspaces/podspaces) runs at **`https://vc.inrupt.com`**.

### Create an Access Request

An application can use [AccessGrantClient.requestAccess](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#requestAccess\(com.inrupt.client.accessgrant.AccessRequest.RequestParameters\)) to create an Access Request.

For example, a user visits an ExamplePrinter’s website which provides photo printing services. When the ExamplePrinter’s web application asks for the photos to print, the user enters the URLs of the photos that are located in the user’s Pod. To continue, the ExamplePrinter’s backend server uses [AccessGrantClient.requestAccess](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#requestAccess\(com.inrupt.client.accessgrant.AccessRequest.RequestParameters\)) to create Access Requests to read the photos.

#### 1. Instantiate the Requestor’s AccessGrantClient

To instantiate an [AccessGrantClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html), call the constructor with the following parameters:

<table><thead><tr><th width="221.8984375">Parameters</th><th>Descriptions</th></tr></thead><tbody><tr><td>Access Grant Service URI</td><td>The root URL of the ESS Access Grant service.</td></tr><tr><td>Authenticated Session</td><td>The authenticated session of the requestor.</td></tr></tbody></table>

For example, the following instantiates an [AccessGrantClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html) for ExamplePrinter using the Inrupt PodSpaces Access Grant Service URI and ExamplePrinter’s authenticated session:

```java
public class ExamplePrinterRequestingClass {

   private final URI PS_ACCESS_GRANT_URI = URI.create("https://vc.inrupt.com");
   private Session session;  // Session for ExamplePrinter.
   // ... Logic to initialize the ExamplePrinter's session has been omitted for brevity.

   private final AccessGrantClient accessgrantClient = new AccessGrantClient(PS_ACCESS_GRANT_URI)
         .session(session);

   // ...
   // ...

}
```

{% hint style="info" %}
In these examples, logic to initialize an authenticated session for ExamplePrinter has been omitted for brevity.
{% endhint %}

#### 2. Create the Access Request

To create an Access Request, call **`AccessRequest.requestAccess`** with the request details:

<table><thead><tr><th width="253.63671875">Parameters</th><th>Descriptions</th></tr></thead><tbody><tr><td>Resource Owner</td><td>The WebID of the agent who controls access to the requested resource(s).</td></tr><tr><td>Requested resource(s)</td><td>Resource(s) to which the access is being requested.</td></tr><tr><td>Requested access mode(s).</td><td><p>Requested access modes. Available modes are:</p><ul><li><code>"Read"</code>,</li><li><code>"Write"</code>, and</li><li><code>"Append"</code>.</li></ul></td></tr><tr><td>Optional. Purpose(s) for the request.</td><td>URI(s) indicating the stated purpose(s) for the request.</td></tr><tr><td>Optional (but Recommended) Expiration Date.</td><td><p>Expiration date of the Access Request and subsequent Access Grant, if approved.</p><p>ESS Access Grant Service may be <a href="https://docs.inrupt.com/ess/latest/services/service-access-grant/#cmdoption-agconfig-arg-INRUPT_VC_MAX_DURATION"><code>configured</code></a> to issue Access Requests and Grants with earlier expiration date.</p></td></tr></tbody></table>

The **`AccessRequest.requestAccess`** accepts:

* request details as [AccessRequest.RequestParameters](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessRequest.RequestParameters.html), which is a collection of the request parameters; or
* request details as individual parameters.

{% tabs %}
{% tab title="Request Parameters" %}
[AccessGrantClient.requestAccess(AccessRequest.RequestParameters)](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#requestAccess\(com.inrupt.client.accessgrant.AccessRequest.RequestParameters%20requestParams\)) accepts the Access Request details as [AccessRequest.RequestParameters](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessRequest.RequestParameters.html). To build the [AccessRequest.RequestParameters](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessRequest.RequestParameters.html) object, you can use [AccessRequest.RequestParameters.Builder](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessRequest.RequestParameters.Builder.html) and its methods.

For example, the following code uses:

* [AccessRequest.RequestParameters.Builder](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessRequest.RequestParameters.Builder.html) to specify the request details (i.e., the resource owner, the resources, the modes, the purposes, and the expiration); and
* ExamplePrinter’s instantiated AccessGrantClient to create the request (i.e., the requestor is ExamplePrinter).

<pre class="language-java"><code class="lang-java">public AccessRequest createReadRequest(List&#x3C;String> resourceURLs, String resourceOwner) {
    URI resourceOwnerURI = URI.create(resourceOwner);
    Set&#x3C;URI> resourcesURIs = resourceURLs.stream().map(URI::create).collect(Collectors.toSet());

    Set&#x3C;String> modes = Set.of("Read"); // Available modes are "Read", "Write", and "Append".

    Set&#x3C;URI> purposes = Set.of(
                URI.create("https://purpose.example.com/PhotoPrinting"),
                URI.create("https://purpose.example.com/ServiceProvision"));

    Instant currentInstant = Instant.now();
    Instant expiration = currentInstant.plus(30, ChronoUnit.MINUTES);

<strong>    AccessRequest.RequestParameters requestParams = AccessRequest.RequestParameters.newBuilder()
</strong><strong>            .recipient(resourceOwnerURI)
</strong><strong>            .resources(resourcesURIs)
</strong><strong>            .modes(modes)
</strong><strong>            .purposes(purposes)
</strong><strong>            .expiration(expiration)
</strong><strong>            .build();
</strong>
    AccessRequest accessRequest = accessgrantClient.requestAccess(requestParams).toCompletableFuture().join();

    return accessRequest;
}
</code></pre>

{% endtab %}

{% tab title="Individual Request Parameters" %}
[AccessGrantClient.requestAccess(URI recipient, Set\<URI> resources, Set\<String> modes, Set\<URI> purposes, Instant expiration)](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#requestAccess\(java.net.URI,java.util.Set,java.util.Set,java.util.Set,java.time.Instant\)) can accept the request details as individual parameters:

For example, the following code uses ExamplePrinter’s instantiated AccessGrantClient to create a Read request:

<pre class="language-java"><code class="lang-java">public AccessRequest createReadRequest(List&#x3C;String> resourceURLs, String resourceOwner) {
    URI resourceOwnerURI = URI.create(resourceOwner);
    Set&#x3C;URI> resourcesURIs = resourceURLs.stream().map(URI::create).collect(Collectors.toSet());

    Set&#x3C;String> modes = Set.of("Read"); // Available modes are "Read", "Write", and "Append".

    Set&#x3C;URI> purposes = Set.of(
                URI.create("https://purpose.example.com/PhotoPrinting"),
                URI.create("https://purpose.example.com/ServiceProvision"));

    Instant currentInstant = Instant.now();
    Instant expiration = currentInstant.plus(30, ChronoUnit.MINUTES);

<strong>    AccessRequest accessRequest = accessgrantClient.requestAccess(
</strong><strong>        resourceOwnerURI,
</strong><strong>        resourcesURIs,
</strong><strong>        modes,
</strong><strong>        purposes,
</strong><strong>        expiration).toCompletableFuture().join();
</strong>
    return accessRequest;
}
</code></pre>

{% endtab %}
{% endtabs %}

### Create an Access Grant

Resource owners can use their access management application to view Access Requests made to them and decide whether to grant the requested access or not. If the resource owner decides to grant an Access Request, the access management application can call [AccessGrantClient.grantAccess](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#grantAccess\(com.inrupt.client.accessgrant.AccessRequest\)) to create an Access Grant. Optionally, the application can also call [AccessGrantClient.verify](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#verify\(com.inrupt.client.accessgrant.AccessCredential\)) to verify the Access Request before displaying it to the user.

For example, the user (the resource owner) who visited ExamplePrinter’s website to print pictures can login to a trusted access management application. The access management application can display the Access Request made to the user by the ExamplePrinter. If the user decides to grant the requested access, the application can create an Access Grant. The access manage application has a backend server that uses various [AccessGrantClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html) methods, namely:

#### 1. Instantiate the Grantor’s AccessGrantClient

To instantiate an [AccessGrantClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html) for the grantor/resource owner, call the constructor with the following parameters:

<table><thead><tr><th width="235.71484375">Parameters</th><th>Descriptions</th></tr></thead><tbody><tr><td>Access Grant Service URL</td><td>The root URL of the ESS Access Grant service</td></tr><tr><td>Authenticated Session</td><td>The authenticated session of the user (the resource owner).</td></tr></tbody></table>

For example, the following instantiates an [AccessGrantClient](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html) using Inrupt PodSpaces Access Grant Service URI and the resource owner’s session:

<pre class="language-java"><code class="lang-java">public class AccessManagementAppRequestHandler {

   private final URI PS_ACCESS_GRANT_URI = URI.create("https://vc.inrupt.com");
   private Session userSession;  // Session for a resource owner.
   // ... Logic to initialize a session for a resource owner has been omitted for brevity.

<strong>   AccessGrantClient agClientForUser = new AccessGrantClient(PS_ACCESS_GRANT_URI)
</strong><strong>      .session(userSession);
</strong>
   // ...
   // ...

}
</code></pre>

#### 2. Get the Access Requests Made to the User

{% hint style="info" %}
The user can only retrieve Access Requests where the user is either the requestor (creator of the Access Request) or the resource owner (recipient of the Access Request).
{% endhint %}

If the Access Request’s id is known, the application can directly retrieve the Access Request using [AccessGrantClient.fetch](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#fetch\(java.net.URI,java.lang.Class\)) with the Access Request’s id.

The **`fetch`** operation can return expired or future Access Requests.

```java
// String requestID = "https://vc.{ESS DOMAIN}/vc/xxxxxx...";
AccessRequest accessRequest = agClientForUser.fetch(URI.create(requestID), AccessRequest.class)
      .toCompletableFuture()
      .join();
```

#### 3. Verify the Requested Access

To [verify the Access Request](https://docs.inrupt.com/ess/latest/services/service-access-grant/service-access-grant-verifier/), use [AccessGrantClient.verify](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#verify\(com.inrupt.client.accessgrant.AccessCredential\)), passing it the Access Request.

For example, the following example uses [AccessGrantClient.verify](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#verify\(com.inrupt.client.accessgrant.AccessCredential\)) to verify an Access Request, checking for errors and warning.

```java
// AccessRequest accessRequest = ...;

AccessCredentialVerification verification = agClientForUser.verify(accessRequest).toCompletableFuture().join();

if (verification.getChecks().isEmpty() || !verification.getErrors().isEmpty()) {
   // Handle invalid Access Request
}

if (!verification.getWarnings().isEmpty()) {
   // Handle warnings
}
```

#### 4. Create the Access Grant

For a valid Access Request, if the resource owner decides to grant the requested access, the application can call [AccessGrantClient.grantAccess](https://api.docs.inrupt.com/docs/developer-tools/api/java/inrupt-client/latest/com/inrupt/client/accessgrant/AccessGrantClient.html#grantAccess\(com.inrupt.client.accessgrant.AccessRequest\)), passing in the specific Access Request to grant.

For example:

```java
AccessGrant accessGrant = agClientForUser.grantAccess(accessRequest).toCompletableFuture().join();
```
