Manage Access Grants#
Upon receipt of an Access Request, resource owners can use an Access Management app to approve or deny the Access Request:
For an approved request, Inrupt’s Enterprise Solid Server (ESS) creates an Access Grant.
For a denied request, Inrupt’s Enterprise Solid Server (ESS) creates an Access Denial.
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 GrantsInrupt’s Enterprise Solid Server (ESS) provides support for Access Requests and Grants. ESS serializes the Access Requests and Grants as Verifiable Credentials (VCs).
Inrupt’s Authorization Management Component supports Access Request management. New as part of ESS 2.2
solid-client-access-grants
API#
Inrupt’s solid-client-access-grants library provides various functions for approving or denying Access Requests; for example:
Approves the request and returns an approved Access Grant, serialized as a signed Verifiable Credential. The Access Grants may be used to get access to specified resources. A server-side code can use the function to create the Grant. Note ESS uses ACP policy to enables the use of Access Grants for a resource. The approveAccessRequest function, by default, creates an ACP policy that enables the use of Access Grant. Starting in ESS 2.2, new Pods are created with default policies that enable the use of Access Grants; for deployments upgrading to 2.2, this change does not affect existing Pods. When using approveAccessRequest, you can specify
Important Starting in version 2.1 of ESS, an Access Request/Grant for a
Container applies both to the Container and its
descendants unless explicitly specified otherwise
with an Version 2.1.+ of
|
|
Denies the request and returns an Access Denial, serialized as a signed Verifiable Credential. A server-side code can use the function to deny the request. |
Granting Access#
The following implements the role of the Access Management app in the example introduced in Access Requests and Grants. The role of the Access Management app is to act as a trusted third-party in the Access Request flow.
The access requestor (e.g., ExamplePrinter) sends the Resource Owner
(e.g., snoringsue
) to the Resource Owner’s Access Management app.
Note
When sending resource owner to the Access Management app, the requestor adds the following query parameters:
id
of the Access Request (in the example, theid
of the Access Request VC), andredirectUrl
, the URL where the requestor expects the Access Management app to redirect the Resource Owner after the request has been granted or denied.
In order to approve or deny an Access Request:
The resource owner should log in to the Access Management app, if not already.
The Access Management app displays the Access Request (found in the
requestVc
parameter) to the Resource Owner. [1]The Resource Owner approves or denies the Access Request.
If the Resource Owner approves the request, the Access Management app uses approveAccessRequest to return the
id
of the Access Grant VC. When calling the function, the Access Management application can also include an optional modifications object (such as to specify a subset of the requested resources or permissions or set theinherit
flag).async function getApprovedGrantVC(accessRequestToApprove, resourceOwnerSession){ // Call `approveAccessRequest` to acquire a Verifiable Credential // for the approved Access Grant const accessGrant = await approveAccessRequest( accessRequestToApprove, undefined, // Optional modifications { updateAcr: false, // For Pods created on ESS 2.2+ fetch: resourceOwnerSession.fetch, // From the resource owner's (i.e., snoringsue's) authenticated session } ); }
If the Resource Owner denies the request, the Access Management app uses denyAccessRequest to return the
id
of the Access Denial VC.async function geAccessDenialVC(accessRequestToDeny, resourceOwnerSession){ // Call `denyAccessRequest` to create an Access Denial const accessDenial = await denyAccessRequest( accessRequestToDeny, { fetch: resourceOwnerSession.fetch, // From the resource owner's (i.e., snoringsue's) authenticated session } ); }
Once the user acts on a request, the Access Management app redirects the user to the requesting app using the
redirectUrl
parameter received earlier. Theid
of the Access Grant/Denial is added to the redirect URL. The requesting app can use getAccessGrantFromRedirectUrl to get the Access Grant.The requesting app can pass the
id
of the VC to getAccessGrant to retrieve the Access Grant.
Adding custom fields to an Access Grant#
Similar to Access Requests (see Use Access Grants to Access Resources), it can be useful to add application-specific information into an Access Grant.
Starting in version 3.2.0, @inrupt/solid-client-access-grants
supports adding
custom fields to an Access Grant. approveAccessRequest
has a new customFields
entry in its requestOverride
argument, 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 Grant. The custom fields from the Access Request being approved
are also propagated to the issued Access Grant, if not overridden by one of the
provided CustomField
overrides. A CustomField
override which value is undefined
will result in the custom field not being present in the Access Grant, even if
it was part of the 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.
async function getApprovedGrantVC(accessRequestToApprove, resourceOwnerSession){ // Call `approveAccessRequest` to acquire a Verifiable Credential // for the approved Access Grant const accessGrant = await approveAccessRequest( accessRequestToApprove, { // This adds a custom field to the issued Access Grant. // Custom fields from the Access Request will also be // present in the issued Grant. customFields: new Set([{ key: new URL("https://example.com/printer/confirmationId"), value: "my-confirmation-id" }]), }, { updateAcr: false, // For Pods created on ESS 2.2+ fetch: resourceOwnerSession.fetch } ); }
Querying for Access Grants#
Starting 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
Grants. To use query
for Access Grants, you can pass in
a AccessGrantFilter
object that specifies the query filter values (i.e., a
combination of the resource, creator, recipient, purpose, and type).
The AccessGrantFilter
object has the following fields:
Key |
Descriptions |
---|---|
|
The Access Credential type (in this case, |
|
Optional. Include a credential status in the query object. The following values are supported for Access Grants:
|
|
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
|
|
Optional. Include the recipient of the Access Request in the query filter. This is the resource owner. |
|
Optional. Include the resource in the query object. Use this filter to return Access Requests bound to a specific resource. |
|
Optional. Include a purpose in the query object. Use this filter to return Access Requests bound to a specific purpose. |
|
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:
|
|
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:
|
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 grants, given to ExamplePrinter, that provide access for a specific resource for the purpose of photo printing.
const page1 = await query({
type: "SolidAccessGrant",
status: "Active",
resource: new URL("https://storage.example.com/some/resource"),
purpose: new URL("https://purpose.example.com/PhotoPrinting"),
}, {
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:
const pages = paginatedQuery({
type: "SolidAccessGrant",
status: "Active",
resource: new URL("https://storage.example.com/some/resource"),
purpose: new URL("https://purpose.example.com/PhotoPrinting"),
}, {
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;
}