# Access Control Policies

The following page provides an overview of [Access Control Policies (ACP)](https://docs.inrupt.com/security/authorization/acp) as well as examples using `@inrupt/solid-client` library’s ACP-specific APIs.

### Access Control Policy (ACP)

While Access Grants are the main way users grant access to data on thier Pods, application developers can make use of ACPs to create more complex authorization schemes for resources on Pods. ACPs are the foundational language by which authorization is expressed in Solid.

With [Access Control Policies (ACP)](/security/authorization.md#acp), Pod owners can define Policies that determine access for their Pod’s resources.

* Each resource has an associated Access Control Resource (ACR).
* The ACR contains the Policies that determine authorization decisions for its associated resource.
* The Policies determine access for Pod resources. A policy statement consists of:
  * Matcher statements that specify conditions that must be satisfied for the Policy to take effect.
  * Access mode statements that specify which access modes are allowed and/or denied to the agent(s) satisfying the Matcher statements.

#### Access Control Resource (ACR)

Every [Resource](/reference/glossary.md#resource) has an associated Access Control Resource (ACR). The ACR specifies the Policies that apply to the resource; these Policies determine the access to the resource.

If the resource is a [Container](/reference/glossary.md#container) (analogous to a folder in a file system), you can also specify default Member Policies in the Container’s ACR. A Container’s Default Member Policies apply to resources (contained in the Container) that do not have their own ACP policies explicitly defined.

If a resource has no Policies that apply to it (neither explicitly for the resource nor implicitly through default Member Policies), the resource is inaccessible. However, the Pod owner and other agents with access to modify the resource’s ACR can add new Policies to provide access to the resource.

For examples on adding policies to a resource’s ACR, see [Examples](#examples).

#### Policies

Policies determine access for Pod resources.

{% hint style="info" %}
Policies are Things in [Structured Data (RDF Resources)](https://docs.inrupt.com/developer-tools/javascript/client-libraries/structured-data/) terminology and are identified by their URL, generally of the form `{ACR URL}#{policy-name}`. See also [URL as Identifiers](/reference/rdf/structured-data-rdf-resources.md).
{% endhint %}

A policy consists of:

* Matcher statements that specify conditions that must be satisfied for the Policy to take effect.
* Access mode statements that specify which access modes are allowed and/or denied to the agent(s) satisfying the Matcher statements.

> If
>
> < allOf | anyOf > (Matcher(s)) evaluates to true, **AND**
>
> < allOf | anyOf | noneOf > (Matcher(s)) evaluates to true, **AND**
>
> …
>
> Then
>
> <**allow** (AccessMode(s)) | **deny** (AccessMode(s)) | **allow** (AccessMode(s)) **AND** **deny** (AccessMode(s)) >

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

The noneOf() expression excludes matches from the allOf() and anyOf() expressions; i.e., you can use the noneOf() expression to refine the allOf() and anyOf() matches.

Because the noneOf() expression acts as a **secondary/supplementary** filter to the allOf() and anyOf() expressions, a Policy statement with only a noneOf() condition cannot be satisfied.

For examples on defining and applying policies to a resource, see [Examples](#examples).
{% endhint %}

#### Matcher Statements

> < allOf | anyOf > (Matcher(s)) evaluate to true, **AND**
>
> < allOf | anyOf | noneOf > (Matcher(s)) evaluates to true, **AND**
>
> …

**Matchers**

Matchers specify the conditions under which the Access Policy applies.

ESS supports the following types of Matchers:

**`allOf`, `anyOf`, `noneOf` Operators**

A policy specifies its matchers in `allOf()`, `anyOf()`, and `noneOf()` operator expressions.

For examples on adding matchers and policies, see [Examples](#examples).

#### ACP Access Modes

> <**allow** (AccessMode(s)) | **deny** (AccessMode(s)) | **allow** (AccessMode(s)) **AND** **deny** (AccessMode(s))>

**Access Modes**

Access Modes describe the permissions (i.e., access) that are allowed or denied for a resource.

The `@inrupt/solid-client`’s ACP APIs handle `<Access Modes>` specification as an object of the form:

```javascript
{ read: <boolean>, append: <boolean>, write: <boolean> }
```

The available Access Modes are:

**`allow`, `deny` Expressions**

A policy statement specifies its access modes in `allow(Access Modes)` or `deny(Access Modes)` expressions:

For examples on adding matchers and policies, see [Examples](#examples).

#### Evaluating Access

An agent is granted an access mode for a resource if:

* The agent satisfies a Policy that `allows` the access mode for the resource, **and**
* The agent does not satisfy any Policy that `denies` that access mode for the resource.

If **no** “allow access” policy is satisfied for a resource, then that resource is inaccessible to the agent. That is, an unsatisfied “deny access” policy does not confer access.

For examples on adding matchers and policies, see [Examples](#examples).

### CRUD Operations and ACP Modes

To create a resource, the user requires either an Append or Write access.

Note

* The creation operation creates the resource and updates the content of the **parent** Container with the new resource’s metadata.
* Although, a [Container](/reference/glossary.md#container) is itself a [SolidDataset](/reference/glossary.md#soliddataset), the table separates out the access for the Container and SolidDataset.

### API and Solid Server Support

Inrupt’s `solid-client` library provides various ACP-specific functions to manage ACP policies.

Inrupt’s [Enterprise Solid Server (ESS)](https://docs.inrupt.com/ess/latest/introduction) provides support for ACP.

To access and use ACP-specific functions compatible with ESS, import `acp_ess_2`.

```javascript
import { acp_ess_2 } from "@inrupt/solid-client";
```

ESS includes changes to ACP in line with the [Editor’s Draft of Access Control Policy](https://solid.github.io/authorization-panel/acp-specification/). These changes have the following implications for the ACP-specific APIs:

* Matchers replace Rules. As such, various `*Rule*` APIs have been deprecated.
* ACP no longer supports `Group` matching (where `Group` is identified by its own URL). As such, various `*Group*` APIs have been deprecated.
* Access Policies and Matchers can only be defined in an ACR. In addition,

  * ACRs must directly link to a Resource,
  * Access Controls and member Access Controls must link to Policies, and
  * Policies must link to Access Modes and Matchers they use.

  As such, you can no longer save unused ACP elements. Concretely, it means that Policies and Matchers must all be defined in an ACR.

### Examples

#### Create Policy to Match Agents and Clients

The following example sets up an `app-friends-policy` that allow Read and Write access to any Agent that satisfies the `match-app-friends` Matcher conditions; namely, Agents whose WebID matches one of the specified WebIDs and is using an application whose Client Identifier matches the specified Client IDs. When verifying against a policy that specifies a Client Application Matcher, the user must be logged in. A Policy that specifies a Client Application Matcher but no Agent Matcher does not match any agent.

```javascript
import { handleIncomingRedirect, login, fetch, getDefaultSession } from '@inrupt/solid-client-authn-browser';
import { acp_ess_2, asUrl } from "@inrupt/solid-client";


// ... Various logic, including login logic, omitted for brevity.
// ...


async function setupPolicyToMatchAgentsAndClients(resourceURL) {

  const agentsToMatch = [ "https://id.example.com/chattycarl", "https://id.example.com/busybee" ];
  const clientIDsToMatch = [ "https://myapp.example.net/appid" ];

  try {
    // 1. Fetch the SolidDataset with its Access Control Resource (ACR).
    let resourceWithAcr = await acp_ess_2.getSolidDatasetWithAcr(
      resourceURL,            // Resource whose ACR to set up
      { fetch: fetch }       // fetch from the authenticated session
    );

    // 2. Initialize a new Matcher.
    let appFriendsMatcher = acp_ess_2.createResourceMatcherFor(
      resourceWithAcr,
      "match-app-friends"
    );

    // 3. For the Matcher, specify the Agent(s) to match.
    agentsToMatch.forEach(agent => {
      appFriendsMatcher = acp_ess_2.addAgent(appFriendsMatcher, agent);
    })

    // 4. For the Matcher, specify the Client ID(s) to match.
    clientIDsToMatch.forEach(clientID => {
      appFriendsMatcher = acp_ess_2.addClient(appFriendsMatcher, clientID);
    })

    // 5. Add the Matcher definition to the Resource's ACR.
    resourceWithAcr = acp_ess_2.setResourceMatcher(
      resourceWithAcr,
      appFriendsMatcher
    );

    // 6. Create a Policy for the Matcher.
    let appFriendsPolicy = acp_ess_2.createResourcePolicyFor(
      resourceWithAcr,
      "app-friends-policy",
    );

    // 7. Add the appFriendsMatcher to the Policy as an allOf() expression.
    // Since using allOf() with a single Matcher, could also use anyOf() expression

    appFriendsPolicy = acp_ess_2.addAllOfMatcherUrl(
      appFriendsPolicy,
      appFriendsMatcher
    );

    // 8. Specify the access modes (e.g., allow Read and Write).
    appFriendsPolicy = acp_ess_2.setAllowModes(appFriendsPolicy,
      { read: true, write: true }
    );

    // 9. Apply the Policy to the resource.
    resourceWithAcr = acp_ess_2.addPolicyUrl(
      resourceWithAcr,
      asUrl(appFriendsPolicy)
    );

    // 10. Add the Policy definition to the resource's ACR. 
    resourceWithAcr = acp_ess_2.setResourcePolicy(
      resourceWithAcr,
      appFriendsPolicy
    );

    // 11. Save the modified ACR for the resource.
    const updatedResourceWithAcr = await acp_ess_2.saveAcrFor(
      resourceWithAcr,
      { fetch: fetch }          // fetch from the authenticated session
    );

  } catch (error) {
    console.error(error.message);
  }
}
```

**Details**

In particular, the example uses:

1. [acp\_ess\_2.getSolidDatasetWithAcr](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getsoliddatasetwithacr) to retrieve the SolidDataset with its ACR.

   ```javascript
   let resourceWithAcr = await acp_ess_2.getSolidDatasetWithAcr(
     resourceURL,            // Resource whose ACR to set up
     { fetch: fetch }       // fetch from the authenticated session
   );
   ```

   To specify policies for files with other structures (such as .pdf or .jpeg files), use [acp\_ess\_2.getFileWithAcr](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getfilewithacr) instead.
2. [acp\_ess\_2.createResourceMatcherFor](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#createresourcematcherfor) to initialize the Matcher that will be used by the policy.

   ```javascript
   let appFriendsMatcher = acp_ess_2.createResourceMatcherFor(
     resourceWithAcr,
     "match-app-friends"
   );
   ```

   When saved, the Matcher URL will be `{ACR URL}#match-app-friends`.
3. [acp\_ess\_2.addAgent](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#addagent) to specify the [WebID](about:blank/reference/glossary/#term-WebID) of the agent(s) to match:

   ```javascript
   agentsToMatch.forEach(agent => {
     appFriendsMatcher = acp_ess_2.addAgent(appFriendsMatcher, agent);
   })
   ```
4. [acp\_ess\_2.addClient](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#addclient) to specify the [Client ID](about:blank/authenticate-client/#authenticate-client-identifier-document) of the application(s) to match.

   ```javascript
   clientIDsToMatch.forEach(clientID => {
     appFriendsMatcher = acp_ess_2.addClient(appFriendsMatcher, clientID);
   })
   ```
5. [acp\_ess\_2.setResourceMatcher](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#setresourcematcher) to store the new matcher definition to the ACR:

   ```javascript
   resourceWithAcr = acp_ess_2.setResourceMatcher(
     resourceWithAcr,
     appFriendsMatcher
   );
   ```
6. [acp\_ess\_2.createResourcePolicyFor](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#createresourcepolicyfor) to initialize the policy:

   ```javascript
   let appFriendsPolicy = acp_ess_2.createResourcePolicyFor(
     resourceWithAcr,
     "app-friends-policy",
   );
   ```

   When saved, the policy URL will be `{ACR URL}#app-friends-policy`.
7. [acp\_ess\_2.addAllOfMatcherUrl](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#addallofmatcherurl) to add the matcher to the policy.

   ```javascript
   // Since using allOf() with a single Matcher, could also use anyOf() expression

   appFriendsPolicy = acp_ess_2.addAllOfMatcherUrl(
     appFriendsPolicy,
     appFriendsMatcher
   );
   ```
8. [acp\_ess\_2.setAllowModes](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#setallowmodes) to specify that the policy allows `Read` and `Write` modes:

   ```javascript
   appFriendsPolicy = acp_ess_2.setAllowModes(appFriendsPolicy,
     { read: true, write: true }
   );
   ```
9. [acp\_ess\_2.addPolicyUrl](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#addpolicyurl) to apply the new policy to the resource:

   ```javascript
   resourceWithAcr = acp_ess_2.addPolicyUrl(
     resourceWithAcr,
     asUrl(appFriendsPolicy)
   );
   ```
10. [acp\_ess\_2.setResourcePolicy](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#setresourcepolicy) to store the new policy definition to the ACR:

    ```javascript
    resourceWithAcr = acp_ess_2.setResourcePolicy(
      resourceWithAcr,
      appFriendsPolicy
    );
    ```
11. [acp\_ess\_2.saveAcrFor](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#saveacrfor) to save the modified ACR.

    ```javascript
    const updatedResourceWithAcr = await acp_ess_2.saveAcrFor(
      resourceWithAcr,
      { fetch: fetch }          // fetch from the authenticated session
    );
    ```

#### Make a Resource Public: Create Public Policy for a Resource

The following example uses the ACP-specific APIs to set up a `public-policy` that allows Read access to the public (i.e., everyone) for a resource.

```javascript
import { handleIncomingRedirect, login, fetch, getDefaultSession } from '@inrupt/solid-client-authn-browser';
import { acp_ess_2 } from "@inrupt/solid-client";

// ... Various logic, including login logic, omitted for brevity.
// ...

async function setupPublicReadPolicyForResource(resourceURL) {
  try {
    // 1. Fetch the SolidDataset with its Access Control Resource (ACR).
    let resourceWithAcr = await acp_ess_2.getSolidDatasetWithAcr(
      resourceURL,              // Resource for which to set up the policies
      { fetch: fetch }          // fetch from the authenticated session
    );

    // 2. Create a Matcher for the Resource.
    let resourcePublicMatcher = acp_ess_2.createResourceMatcherFor(
      resourceWithAcr,
      "match-public"  // Matcher URL will be {ACR URL}#match-public
    );

    // 3. Specify that the matcher matches the Public (i.e., everyone).
    resourcePublicMatcher = acp_ess_2.setPublic(resourcePublicMatcher);

    // 4. Add Matcher to the Resource's ACR.
    resourceWithAcr = acp_ess_2.setResourceMatcher(
      resourceWithAcr,
      resourcePublicMatcher,
    );

    // 5. Create the Policy for the Resource.
    let resourcePolicy = acp_ess_2.createResourcePolicyFor(
      resourceWithAcr,
      "public-policy",  // Policy URL will be {ACR URL}#public-policy
    );

    // 6. Add the Public Matcher to the Policy as an allOf() expression.
    resourcePolicy = acp_ess_2.addAllOfMatcherUrl(
      resourcePolicy,
      resourcePublicMatcher
    );

    // 7. Specify the access modes for the Policy.
    resourcePolicy = acp_ess_2.setAllowModes(
      resourcePolicy,
      { read: true, append: false, write: false },
    );

    // 8. Apply the Policy to the Resource.
    resourceWithAcr = acp_ess_2.addPolicyUrl(
       resourceWithAcr,
       asUrl(resourcePolicy)
     );

    // 9. Add the Policy definition to the Resource's ACR. 
    resourceWithAcr = acp_ess_2.setResourcePolicy(
       resourceWithAcr,
       resourcePolicy,
    );

    // 10. Save the ACR for the Resource.
    const updatedResourceWithAcr = await acp_ess_2.saveAcrFor(
      resourceWithAcr,
      { fetch: fetch }          // fetch from the authenticated session
    );
  } catch (error) {
    console.error(error.message);
  }
}
```

**Details**

In particular, the example uses:

1. [acp\_ess\_2.getSolidDatasetWithAcr](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getsoliddatasetwithacr) to retrieve the SolidDataset (the SolidDataset can be a Container) with its ACR.

   ```javascript
   let resourceWithAcr = await acp_ess_2.getSolidDatasetWithAcr(
     resourceURL,              // Resource for which to set up the policies
     { fetch: fetch }          // fetch from the authenticated session
   );
   ```

   To specify policies for files with other structures (such as .pdf or .jpeg files), use [acp\_ess\_2.getFileWithAcr](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getfilewithacr) instead.
2. [acp\_ess\_2.createResourceMatcherFor](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#createresourcematcherfor) to initialize the Matcher that will be used by the policy.

   ```javascript
   let resourcePublicMatcher = acp_ess_2.createResourceMatcherFor(
     resourceWithAcr,
     "match-public"  // Matcher URL will be {ACR URL}#match-public
   );
   ```

   When saved, the Matcher URL will be `{ACR URL}#match-public`.
3. [acp\_ess\_2.setPublic](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#setpublic) to specify that the matcher is a Public matcher; i.e., matches everyone.

   ```javascript
   resourcePublicMatcher = acp_ess_2.setPublic(resourcePublicMatcher);
   ```
4. [acp\_ess\_2.setResourceMatcher](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#setresourcematcher) to store the matcher definition to the ACR:

   ```javascript
   resourceWithAcr = acp_ess_2.setResourceMatcher(
     resourceWithAcr,
     resourcePublicMatcher,
   );
   ```
5. [acp\_ess\_2.createResourcePolicyFor](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#createresourcepolicyfor) to initialize the policy for the Resource:

   ```javascript
   let resourcePolicy = acp_ess_2.createResourcePolicyFor(
     resourceWithAcr,
     "public-policy",  // Policy URL will be {ACR URL}#public-policy
   );
   ```

   When saved, the policy URL will be `{ACR URL}#public-policy`.
6. [acp\_ess\_2.addAllOfMatcherUrl](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#addallofmatcherurl) to add the matcher to the policy.

   ```javascript
   resourcePolicy = acp_ess_2.addAllOfMatcherUrl(
     resourcePolicy,
     resourcePublicMatcher
   );
   ```
7. [acp\_ess\_2.setAllowModes](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#setallowmodes) to specify the access modes for the policy:

   ```javascript
   resourcePolicy = acp_ess_2.setAllowModes(
     resourcePolicy,
     { read: true, append: false, write: false },
   );
   ```
8. [acp\_ess\_2.addPolicyUrl](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#addpolicyurl) to apply the new policy to the resource:

   ```javascript
   resourceWithAcr = acp_ess_2.addPolicyUrl(
      resourceWithAcr,
      asUrl(resourcePolicy)
    );
   ```
9. [acp\_ess\_2.setResourcePolicy](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#setresourcepolicy) to store the new policy definition to the ACR:

   ```javascript
   resourceWithAcr = acp_ess_2.setResourcePolicy(
      resourceWithAcr,
      resourcePolicy,
   );
   ```
10. [acp\_ess\_2.saveAcrFor](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#saveacrfor) to save the modified ACR.

    ```javascript
    const updatedResourceWithAcr = await acp_ess_2.saveAcrFor(
      resourceWithAcr,
      { fetch: fetch }          // fetch from the authenticated session
    );
    ```

#### View Policies and Matchers for a Resource

The following example uses the ACP-specific APIs to view the ACP policies for a resource.

```javascript
import { handleIncomingRedirect, login, fetch, getDefaultSession } from '@inrupt/solid-client-authn-browser';
import { acp_ess_2, solidDatasetAsTurtle } from "@inrupt/solid-client";

// ... Various logic, including login logic, omitted for brevity.

async function viewResourceACR(resourceURL) {

  try {
    // 1. Fetch the SolidDataset with its Access Control Resource (ACR).
    const resourceWithAcr = await acp_ess_2.getSolidDatasetWithAcr(
      resourceURL,
      { fetch: fetch }            // fetch from the authenticated session
    );

    // 2a. Get the Access Control Resource (ACR)
    const myACR = await getSolidDataset(
      acp_ess_2.getLinkedAcrUrl(resourceWithAcr),
      { fetch: fetch }
    );
    
    // 2b. Output (formatted as Turtle) its policies and matchers details.
    console.log(solidDatasetAsTurtle(myACR));

    // 3a. Get all policies from the ACR to process policies.
    const myResourcePolicies = acp_ess_2.getResourcePolicyAll(resourceWithAcr);

    // Loop through each policy for processing.
    myResourcePolicies.forEach(policy => {
      //... 
    });

    // 3b. Get a specific policy from the ACR.
    const specificPolicy = acp_ess_2.getResourcePolicy(
      resourceWithAcr,
      "specify-the-name-of-policy-to-get"
    );

    // 4a. Get all matchers from the ACR to process matchers.
    const myResourceMatchers = acp_ess_2.getResourceMatcherAll(resourceWithAcr)

    // Loop through each matcher for processing.
    myResourceMatchers.forEach(matcher => {
      // ... 
    });

    // 4b. Get a specific matcher from the ACR.
    const specificMatcher = acp_ess_2.getResourceMatcher(
      resourceWithAcr,
      "specify-the-name-of-matcher-to-get"
    );


  } catch (error) {
      console.error(error.message);
  }
}
```

**Details**

In particular, the example uses:

1. [acp\_ess\_2.getSolidDatasetWithAcr](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getsoliddatasetwithacr) to retrieve the SolidDataset (the SolidDataset can be a Container) with its ACR.

   ```javascript
   const resourceWithAcr = await acp_ess_2.getSolidDatasetWithAcr(
     resourceURL,
     { fetch: fetch }            // fetch from the authenticated session
   );
   ```

   To specify policies for files with other structures (such as .pdf or .jpeg files), use [acp\_ess\_2.getFileWithAcr](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getfilewithacr) instead.
2. [getSolidDataset](https://inrupt.github.io/solid-client-js/modules/resource_solidDataset.html#getsoliddataset) with [getLinkedAcrUrl](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getlinkedacrurl) to retrieve the ACR.

   ```javascript
   const myACR = await getSolidDataset(
     acp_ess_2.getLinkedAcrUrl(resourceWithAcr),
     { fetch: fetch }
   );
   ```

   Once you retrieve the ACR as a SolidDataset, you can use [solidDatasetAsTurtle](https://inrupt.github.io/solid-client-js/modules/formats.html#soliddatasetasturtle) to format ACR as [Turtle](https://www.w3.org/TR/turtle/).

   ```javascript
   console.log(solidDatasetAsTurtle(myACR));
   ```
3. [acp\_ess\_2.getResourcePolicyAll](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getresourcepolicyall) to get the policies from the resource’s ACR.

   ```javascript
   const myResourcePolicies = acp_ess_2.getResourcePolicyAll(resourceWithAcr);

   // Loop through each policy for processing.
   myResourcePolicies.forEach(policy => {
     //... 
   });
   ```

   To view a specific policy, you can use [acp\_ess\_2.getResourcePolicy](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getresourcepolicy):

   ```javascript
   const specificPolicy = acp_ess_2.getResourcePolicy(
     resourceWithAcr,
     "specify-the-name-of-policy-to-get"
   );
   ```
4. [acp\_ess\_2.getResourceMatcherAll](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getresourcematcherall) to get all matchers from the resource’s ACR.

   ```javascript
   const myResourceMatchers = acp_ess_2.getResourceMatcherAll(resourceWithAcr)

   // Loop through each matcher for processing.
   myResourceMatchers.forEach(matcher => {
     // ... 
   });
   ```

   To view a specific matcher, you can use [acp\_ess\_2.getResourceMatcher](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getresourcematcher):

   ```javascript
   const specificMatcher = acp_ess_2.getResourceMatcher(
     resourceWithAcr,
     "specify-the-name-of-matcher-to-get"
   );
   ```

#### Delete Existing Policy for a Resource

The following example deletes an existing Policy for a resource.

Tip

To view existing Policies for a resource, see [View Policies and Matchers for a Resource](#view-policies-and-matchers-for-a-resource).

```javascript
import { handleIncomingRedirect, login, fetch, getDefaultSession } from '@inrupt/solid-client-authn-browser';
import { acp_ess_2 } from "@inrupt/solid-client";

// ... Various logic, including login logic, omitted for brevity.

async function deletePolicyForResource(resourceURL, policyName) {

  try {

    // 1. Fetch the SolidDataset with its Access Control Resource (ACR).
    let resourceWithAcr = await acp_ess_2.getSolidDatasetWithAcr(
      resourceURL,           // Resource whose policy you want to delete
      { fetch: fetch }       // fetch from the authenticated session
    );

    // 2. Remove the Policy definition from the ACR
    resourceWithAcr = acp_ess_2.removeResourcePolicy(resourceWithAcr, policyName);

    // 3. Save the ACR for the Resource.
    const updatedResourceWithAcr = await acp_ess_2.saveAcrFor(
      resourceWithAcr,
      { fetch: fetch }          // fetch from the authenticated session
    );

  } catch (error) {
    console.error(error.message);
  }
}
```

**Details**

In particular, the example uses:

1. [acp\_ess\_2.getSolidDatasetWithAcr](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getsoliddatasetwithacr) to retrieve the SolidDataset (the SolidDataset can be a Container) with its ACR.

   ```javascript
   let resourceWithAcr = await acp_ess_2.getSolidDatasetWithAcr(
     resourceURL,           // Resource whose policy you want to delete
     { fetch: fetch }       // fetch from the authenticated session
   );
   ```

   To specify policies for files with other structures (such as .pdf or .jpeg files), use [acp\_ess\_2.getFileWithAcr](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getfilewithacr) instead.
2. [acp\_ess\_2.removeResourcePolicy](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#removeresourcepolicy) to delete the Policy definition from the ACR:

   ```javascript
   resourceWithAcr = acp_ess_2.removeResourcePolicy(resourceWithAcr, policyName);
   ```

   [acp\_ess\_2.removeResourcePolicy](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#removeresourcepolicy) can also accept the Policy URL or the Policy itself instead of the Policy name.
3. [acp\_ess\_2.saveAcrFor](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#saveacrfor) to save the modified ACR.

   ```javascript
   const updatedResourceWithAcr = await acp_ess_2.saveAcrFor(
     resourceWithAcr,
     { fetch: fetch }          // fetch from the authenticated session
   );
   ```

#### Modify Existing Matcher for a Resource

The following example continues from an earlier example. Specifically, the example modifies the `match-app-friends` created in [Create Policy to Match Agents and Clients](#create-policy-to-match-agents-and-clients) to remove one of the Agents from the match list.

Tip

To view existing Matchers for a resource, see [View Policies and Matchers for a Resource](#view-policies-and-matchers-for-a-resource).

```javascript
import { handleIncomingRedirect, login, fetch, getDefaultSession } from '@inrupt/solid-client-authn-browser';
import { acp_ess_2 } from "@inrupt/solid-client";

// ... Various logic, including login logic, omitted for brevity.

async function removeAgentFromMatcher(resourceURL) {

  try {

    // 1. Fetch the SolidDataset with its Access Control Resource (ACR).
    let resourceWithAcr = await acp_ess_2.getSolidDatasetWithAcr(
        resourceURL,           // Resource whose Matcher you want to modify
        { fetch: fetch }       // fetch from the authenticated session
    );

    // 2. Get the Matcher to modify.
    let matcherToModify = acp_ess_2.getResourceMatcher(
        resourceWithAcr,
        "match-app-friends" // Name of the Matcher created in an earlier example.
    );

    // 3. Modify the Matcher; e.g., remove an Agent from the Matcher.

    const agentToRemove="https://id.example.com/chattycarl";
    matcherToModify = acp_ess_2.removeAgent(matcherToModify, agentToRemove);

    // 4. Store the modified Matcher definition to the resource's ACR.
    resourceWithAcr = acp_ess_2.setResourceMatcher(
        resourceWithAcr,
        matcherToModify
    );

    // 5. Save the modified ACR for the resource.
    const updatedResourceWithAcr = await acp_ess_2.saveAcrFor(
        resourceWithAcr,
        { fetch: fetch }          // fetch from the authenticated session
    );

  } catch (error) {
    console.error(error.message);
  }
}
```

**Details**

In particular, the example uses:

1. [acp\_ess\_2.getSolidDatasetWithAcr](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getsoliddatasetwithacr) to retrieve the SolidDataset (the SolidDataset can be a Container) with its ACR.

   ```javascript
   let resourceWithAcr = await acp_ess_2.getSolidDatasetWithAcr(
       resourceURL,           // Resource whose Matcher you want to modify
       { fetch: fetch }       // fetch from the authenticated session
   );
   ```

   To specify policies for files with other structures (such as .pdf or .jpeg files), use [acp\_ess\_2.getFileWithAcr](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getfilewithacr) instead.
2. [acp\_ess\_2.getResourceMatcher](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getresourcematcher) to get the Matcher from the resource’s ACR.

   ```javascript
   let matcherToModify = acp_ess_2.getResourceMatcher(
       resourceWithAcr,
       "match-app-friends" // Name of the Matcher created in an earlier example.
   );
   ```

   The `match-app-friends` was created in an earlier example, [Create Policy to Match Agents and Clients](https://github.com/inrupt/docs-gitbook/blob/main/guides/broken-reference/README.md).

   Tip

   To view existing Matchers for a resource, see [View Policies and Matchers for a Resource](https://github.com/inrupt/docs-gitbook/blob/main/guides/broken-reference/README.md).
3. [acp\_ess\_2.removeAgent](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#removeagent) to remove an Agent’s WebID from the list of the Matcher’s WebIDs to match.

   ```javascript
   policyToModify = acp_ess_2.setAllowModes(policyToModify,
     { write: false }
   );
   ```
4. [acp\_ess\_2.setResourceMatcher](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#setresourcematcher) to update the Matcher definition in the ACR:

   ```javascript
   resourceWithAcr = acp_ess_2.setResourcePolicy(
     resourceWithAcr,
     policyToModify
   );
   ```
5. [acp\_ess\_2.saveAcrFor](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#saveacrfor) to save the modified ACR.

   ```javascript
   const updatedResourceWithAcr = await acp_ess_2.saveAcrFor(
     resourceWithAcr,
     { fetch: fetch }          // fetch from the authenticated session
   );
   ```

#### Modify Existing Policy for a Resource

The following example continues from an earlier example. Specifically, the example modifies the `app-friends-policy` created in [Create Policy to Match Agents and Clients](/security/authorization/acp.md#create-policy-to-match-agents-and-clients).

Tip

To view existing Policies for a resource, see [View Policies and Matchers for a Resource](https://docs.inrupt.com/security/authorization/acp#view-policies-and-matchers-for-a-resource).

```javascript
import { handleIncomingRedirect, login, fetch, getDefaultSession } from '@inrupt/solid-client-authn-browser';
import { acp_ess_2 } from "@inrupt/solid-client";

// ... Various logic, including login logic, omitted for brevity.

async function modifyAppFriendsPolicy(resourceURL) {

  try {

    // 1. Fetch the SolidDataset with its Access Control Resource (ACR).
    let resourceWithAcr = await acp_ess_2.getSolidDatasetWithAcr(
      resourceURL,           // Resource whose Policy you want to modify
      { fetch: fetch }       // fetch from the authenticated session
    );

    // 2. Get the Policy to modify. 
    let policyToModify = acp_ess_2.getResourcePolicy(
      resourceWithAcr,
      "app-friends-policy" // Name of the Policy created in an earlier example.
    );

    // 3. Change the Write access mode to false (from true). Other access modes remain unchanged.
    policyToModify = acp_ess_2.setAllowModes(policyToModify,
      { write: false }
    );

    // 4. Store the modified Policy definition to the resource's ACR. 
    resourceWithAcr = acp_ess_2.setResourcePolicy(
      resourceWithAcr,
      policyToModify
    );

    // 5. Save the modified ACR for the resource.
    const updatedResourceWithAcr = await acp_ess_2.saveAcrFor(
      resourceWithAcr,
      { fetch: fetch }          // fetch from the authenticated session
    );

  } catch (error) {
    console.error(error.message);
  }
}
```

**Details**

In particular, the example uses:

1. [acp\_ess\_2.getSolidDatasetWithAcr](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getsoliddatasetwithacr) to retrieve the SolidDataset (the SolidDataset can be a Container) with its ACR.

   ```javascript
   let resourceWithAcr = await acp_ess_2.getSolidDatasetWithAcr(
     resourceURL,           // Resource whose Policy you want to modify
     { fetch: fetch }       // fetch from the authenticated session
   );
   ```

   To specify policies for files with other structures (such as .pdf or .jpeg files), use [acp\_ess\_2.getFileWithAcr](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getfilewithacr) instead.
2. [acp\_ess\_2.getResourcePolicy](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#getresourcepolicy) to get the Policy from the resource’s ACR. The `app-friends-policy` was created in an earlier example, [Create Policy to Match Agents and Clients](#create-policy-to-match-agents-and-clients).

   ```javascript
   let policyToModify = acp_ess_2.getResourcePolicy(
     resourceWithAcr,
     "app-friends-policy" // Name of the Policy created in an earlier example.
   );
   ```

   Tip

   To view existing Policies for a resource, see [View Policies and Matchers for a Resource](#view-policies-and-matchers-for-a-resource).
3. [acp\_ess\_2.setAllowModes](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#setallowmodes) to update the Write access mode for the Policy. The other Access Modes for this Policy remain unchanged.

   ```javascript
   policyToModify = acp_ess_2.setAllowModes(policyToModify,
     { write: false }
   );
   ```

   For additional Policy functions, see the [API documentation](https://inrupt.github.io/solid-client-js/).
4. [acp\_ess\_2.setResourcePolicy](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#setresourcepolicy) to update the Policy definition in the ACR:

   ```javascript
   resourceWithAcr = acp_ess_2.setResourcePolicy(
     resourceWithAcr,
     policyToModify
   );
   ```
5. [acp\_ess\_2.saveAcrFor](https://inrupt.github.io/solid-client-js/modules/acp_ess_2.html#saveacrfor) to save the modified ACR.

   ```javascript
   const updatedResourceWithAcr = await acp_ess_2.saveAcrFor(
     resourceWithAcr,
     { fetch: fetch }          // fetch from the authenticated session
   );
   ```


---

# 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/guides/access-control-policies.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.
