Appendix: ACP (ESS v1.1)#

Note

This page is compatible with Inrupt’s Enterprise Solid Server (ESS) 1.1. For content related to ESS 2.0, see Manage Access to Data (ACP).

ACP Modules#

Changed in version 1.21.0.

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

Tip

The solid-client library also provides universal access control APIs that can be used with either Access Control Policy (ACP) or Web Access Control (WAC).

When possible, use the universal access control APIs instead of the ACP-specific APIs or WAC-specific APIs. For situations that require ACP-specific or WAC-specific APIs, see Mechanism-Specific Access Control APIs.

Using the mechanism-specific APIs, it is possible for you to define an access model that is incompatible with the universal access APIs and, therefore, can only be managed with the mechanism-specific APIs.

To access and use ACP-specific functions compatible with Enterprise Solid Server (ESS) 1.1, import acp_ess_1.

import { acp_ess_1 } from "@inrupt/solid-client";

To use ACP-specific functions compatible with ESS 2.0, see Manage Access to Data (ACP).

Examples#

Note

The Enterprise Solid Server (ESS) 1.1 compatible examples use a single SolidDataset as a repository for the rules and policies.

Create a Rule for Matching an Agent#

The following example creates a new SolidDataset to store your custom ACP rules to match the specified agents.

import { handleIncomingRedirect, login, fetch, getDefaultSession } from '@inrupt/solid-client-authn-browser';
import { createSolidDataset, saveSolidDatasetAt, acp_ess_1 } from "@inrupt/solid-client";

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

const MY_POD_URL = "https://mypod.example.com/docsteam/";
const MY_ACP_SOLID_DATASET = `${MY_POD_URL}acp/myrulesandpolicies`;

async function setupMyAgentMatchingRule() {
  try {
    // 1. Initialize a new SolidDataset for your rules and policies.
    let myRulesAndPoliciesSolidDataset = createSolidDataset();
 
    // 2. Initialize your new Rules.
    let colleaguesRule = acp_ess_1.createRule(`${MY_ACP_SOLID_DATASET}#colleagues-rule`);
    let roommateRule = acp_ess_1.createRule(`${MY_ACP_SOLID_DATASET}#roommate-rule`);
  
    // 3. For the rules, specify the Agent to match.
    colleaguesRule = acp_ess_1.addAgent(colleaguesRule, "https://mypod.example.com/busybee/profile/card#me");
    colleaguesRule = acp_ess_1.addAgent(colleaguesRule, "https://mypod.example.com/leapinglizard/profile/card#me");

    roommateRule = acp_ess_1.addAgent(roommateRule, "https://mypod.example.com/snoringsue/profile/card#me");

    // 4. Add your new rules to the SolidDataset.
    myRulesAndPoliciesSolidDataset = acp_ess_1.setRule(myRulesAndPoliciesSolidDataset, colleaguesRule);
    myRulesAndPoliciesSolidDataset = acp_ess_1.setRule(myRulesAndPoliciesSolidDataset, roommateRule);

    // 5. Save the SolidDataset.
    const savedSolidDataset = await saveSolidDatasetAt(
      MY_ACP_SOLID_DATASET,
      myRulesAndPoliciesSolidDataset,
      { fetch: fetch }       // fetch from the authenticated session
    );
  } catch (error) {
      console.error(error.message);
  }
}

In particular, the example uses:

  1. createSolidDataset to initialize a new SolidDataset for storing your custom rules and policies.

    let myRulesAndPoliciesSolidDataset = createSolidDataset();
    
  2. acp_ess_1.createRule to initialize the new rule to save:

    let colleaguesRule = acp_ess_1.createRule(`${MY_ACP_SOLID_DATASET}#colleagues-rule`);
    let roommateRule = acp_ess_1.createRule(`${MY_ACP_SOLID_DATASET}#roommate-rule`);
    

    When creating the rule, pass in the target URL for the Rule.

  3. acp_ess_1.addAgent to specify the agent(s) to match with the rules:

    colleaguesRule = acp_ess_1.addAgent(colleaguesRule, "https://mypod.example.com/busybee/profile/card#me");
    colleaguesRule = acp_ess_1.addAgent(colleaguesRule, "https://mypod.example.com/leapinglizard/profile/card#me");
    
    roommateRule = acp_ess_1.addAgent(roommateRule, "https://mypod.example.com/snoringsue/profile/card#me");
    

    In this example, the colleaguesRule matches either the agent busybee or the agent leapinglizard (identified by their WebIDs), and roommateRule matches the agent snoringsue.

  4. acp_ess_1.setRule to add the new rules to a SolidDataset.

    myRulesAndPoliciesSolidDataset = acp_ess_1.setRule(myRulesAndPoliciesSolidDataset, colleaguesRule);
    myRulesAndPoliciesSolidDataset = acp_ess_1.setRule(myRulesAndPoliciesSolidDataset, roommateRule);
    
  5. saveSolidDatasetAt to save the SolidDataset.

    const savedSolidDataset = await saveSolidDatasetAt(
      MY_ACP_SOLID_DATASET,
      myRulesAndPoliciesSolidDataset,
      { fetch: fetch }       // fetch from the authenticated session
    );
    

Create a Rule for the General Public#

Note

The example uses a single SolidDataset as a repository for the rules and policies.

The following example continues from the previous example and assumes the existence of the SolidDataset at https://mypod.example.com/acp/myrulesandpolicies. Specifically, the example creates a new rule for the general Public and adds it to the https://mypod.example.com/acp/myrulesandpolicies SolidDataset:

import { handleIncomingRedirect, login, fetch, getDefaultSession } from '@inrupt/solid-client-authn-browser';
import { getSolidDataset, setThing, saveSolidDatasetAt, acp_ess_1 } from "@inrupt/solid-client";

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

const MY_POD_URL = "https://mypod.example.com/docsteam/";
const MY_ACP_SOLID_DATASET = `${MY_POD_URL}acp/myrulesandpolicies`;

async function setupMyPublicRule() {
  try {
    // 1. Fetch the SolidDataset for your rules and policies.
    let myRulesAndPoliciesSolidDataset = await getSolidDataset(
      MY_ACP_SOLID_DATASET,
      { fetch: fetch }          // fetch from the authenticated session
    );
 
    // 2. Initialize your new Rule.
    let publicRule = acp_ess_1.createRule(`${MY_ACP_SOLID_DATASET}#public-rule`);
  
    // 3. For the rule, specify that it should match the public.
    publicRule = acp_ess_1.setPublic(publicRule);

    // 4. Add your new rule to the SolidDataset.
    myRulesAndPoliciesSolidDataset = acp_ess_1.setRule(myRulesAndPoliciesSolidDataset, publicRule);

    // 5. Save the SolidDataset.
    const savedSolidDataset = await saveSolidDatasetAt(
      MY_ACP_SOLID_DATASET,
      myRulesAndPoliciesSolidDataset,
      { fetch: fetch }        // fetch from the authenticated session
    );
  } catch (error) {
    console.error(error.message);
  }
}

In particular, the example uses:

  1. getSolidDataset to retrieve the SolidDataset for storing your custom rules and policies.

    let myRulesAndPoliciesSolidDataset = await getSolidDataset(
      MY_ACP_SOLID_DATASET,
      { fetch: fetch }          // fetch from the authenticated session
    );
    
  2. acp_ess_1.createRule to initialize the new rule to save:

    let publicRule = acp_ess_1.createRule(`${MY_ACP_SOLID_DATASET}#public-rule`);
    

    When creating the rule, pass in the target URL for the Rule.

  3. acp_ess_1.setPublic to specify that the rule matches the public|setRule| (i.e., everyone):

    publicRule = acp_ess_1.setPublic(publicRule);
    
  4. acp_ess_1.setRule to add the new rule to a SolidDataset.

    myRulesAndPoliciesSolidDataset = acp_ess_1.setRule(myRulesAndPoliciesSolidDataset, publicRule);
    
  5. saveSolidDatasetAt to save the SolidDataset.

    const savedSolidDataset = await saveSolidDatasetAt(
      MY_ACP_SOLID_DATASET,
      myRulesAndPoliciesSolidDataset,
      { fetch: fetch }        // fetch from the authenticated session
    );
    

Create Rule for a Specific Client Application#

Note

The example uses a single SolidDataset as a repository for the rules and policies. There is no requirement for the rules or policies to be stored in a single SolidDataset.

With ACP, you can create a rule that specifies not only the Agent but the Client Application. A Client Application identifies itself using a its client identifier. To verify the Client Application, a user must be logged in.

The following example continues from the previous example and assumes the existence of the SolidDataset at https://mypod.example.com/acp/myrulesandpolicies.

import { handleIncomingRedirect, login, fetch, getDefaultSession } from '@inrupt/solid-client-authn-browser';
import { getSolidDataset, saveSolidDatasetAt, acp_ess_1 } from "@inrupt/solid-client";

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

const MY_POD_URL = "https://mypod.example.com/docsteam/";
const MY_ACP_SOLID_DATASET = `${MY_POD_URL}acp/myrulesandpolicies`;

async function setupMyAgentApplicationMatchingRule() {
  try {
    // 1. Fetch the SolidDataset for your rules and policies.
    let myRulesAndPoliciesSolidDataset = await getSolidDataset(
      MY_ACP_SOLID_DATASET,
      { fetch: fetch }          // fetch from the authenticated session
    );
 
    // 2. Initialize your new Rules.
    let chatFriendRule = acp_ess_1.createRule(`${MY_ACP_SOLID_DATASET}#chat-friend-rule`);
  
    // 3. For the rule, specify the Agent to match.
    chatFriendRule = acp_ess_1.addAgent(chatFriendRule, "https://mypod.example.com/chattypatty/profile/card#me");

    // 4. For the rule, specify the Client Application to match.
    chatFriendRule = acp_ess_1.addClient(chatFriendRule, "https://mychat.example.net/appid.jsonld");

    // 5. Add your new rules to the SolidDataset.
    myRulesAndPoliciesSolidDataset = acp_ess_1.setRule(myRulesAndPoliciesSolidDataset, chatFriendRule);

    // 6. Save the SolidDataset.
    const savedSolidDataset = await saveSolidDatasetAt(
      MY_ACP_SOLID_DATASET,
      myRulesAndPoliciesSolidDataset,
      { fetch: fetch }       // fetch from the authenticated session
    );
  } catch (error) {
      console.error(error.message);
  }
}

In particular, the example uses:

  1. getSolidDataset to retrieve the SolidDataset for storing your custom rules and policies.

    let myRulesAndPoliciesSolidDataset = await getSolidDataset(
      MY_ACP_SOLID_DATASET,
      { fetch: fetch }          // fetch from the authenticated session
    );
    
  2. acp_ess_1.createRule to initialize the new rule to save:

    let chatFriendRule = acp_ess_1.createRule(`${MY_ACP_SOLID_DATASET}#chat-friend-rule`);
    

    When creating the rule, pass in the target URL for the Rule.

  3. acp_ess_1.addAgent to specify the agent(s) to match with the rule:

    chatFriendRule = acp_ess_1.addAgent(chatFriendRule, "https://mypod.example.com/chattypatty/profile/card#me");
    
  4. acp_ess_1.addClient to specify the client(s) to match with the rule:

    chatFriendRule = acp_ess_1.addClient(chatFriendRule, "https://mychat.example.net/appid.jsonld");
    

    With the addition of the client to the rule, this rule matches only when agent chattypatty (added in the previous step) uses the specified client application.

  5. acp_ess_1.setRule to add the new rule to a SolidDataset.

    myRulesAndPoliciesSolidDataset = acp_ess_1.setRule(myRulesAndPoliciesSolidDataset, chatFriendRule);
    
  6. saveSolidDatasetAt to save the SolidDataset.

    const savedSolidDataset = await saveSolidDatasetAt(
      MY_ACP_SOLID_DATASET,
      myRulesAndPoliciesSolidDataset,
      { fetch: fetch }       // fetch from the authenticated session
    );
    

For information on client application identifiers, see Appendix: Client ID Document (Browser & Node.JS).

Create Policies#

Note

The example uses a single SolidDataset as a repository for the rules and policies. There is no requirement for the rules or policies to be stored in a single SolidDataset.

A policy specifies the Access Rules and Access Modes for the Resource:

  • A policy specifies its rules as part of allOf(), anyOf(), and noneOf() operator expressions.

  • A policy specifies its access modes in allow(<Access Modes>) or deny(Access Modes) expressions.

The following example continues from the previous examples. Specifically, the example creates new policies using the rules saved from the previous examples.

import { handleIncomingRedirect, login, fetch, getDefaultSession } from '@inrupt/solid-client-authn-browser';
import { getSolidDataset, saveSolidDatasetAt, acp_ess_1 } from "@inrupt/solid-client";


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

const MY_POD_URL = "https://mypod.example.com/docsteam/";
const MY_ACP_SOLID_DATASET = `${MY_POD_URL}acp/myrulesandpolicies`;

async function setupMyPolicies() {
  try {
    // 1. Fetch the SolidDataset for your rules and policies.
    let myRulesAndPoliciesSolidDataset = await getSolidDataset(
      MY_ACP_SOLID_DATASET,
      { fetch: fetch }      // fetch from the authenticated session
    );
 
    // 2. Initialize your new Policies.
    let roommateandcolleaguesPolicy = acp_ess_1.createPolicy(`${MY_ACP_SOLID_DATASET}#roommates-colleagues-policy`);
    let publicReadPolicy = acp_ess_1.createPolicy(`${MY_ACP_SOLID_DATASET}#public-read-policy`);
  
    // 3. Add the rules from previous examples as allOf() or anyOf() expressions to the Policies.
    roommateandcolleaguesPolicy = acp_ess_1.addAnyOfRuleUrl(
        roommateandcolleaguesPolicy,
        `${MY_ACP_SOLID_DATASET}#colleagues-rule`       
    );
    roommateandcolleaguesPolicy = acp_ess_1.addAnyOfRuleUrl(
        roommateandcolleaguesPolicy,
        `${MY_ACP_SOLID_DATASET}#roommate-rule`       
    );

    publicReadPolicy = acp_ess_1.addAllOfRuleUrl(
      publicReadPolicy,
      `${MY_ACP_SOLID_DATASET}#public-rule`   // Rule matches anyone
    );

    // 4. Specify the access modes for the policies.
    roommateandcolleaguesPolicy = acp_ess_1.setAllowModes(
      roommateandcolleaguesPolicy,
      { read: true, append: false, write: true },
    );

    publicReadPolicy = acp_ess_1.setAllowModes(
      publicReadPolicy,
      { read: true, append: false, write: false },
    );

    // 5. Add your new Policies to the SolidDataset.
    myRulesAndPoliciesSolidDataset = acp_ess_1.setPolicy(myRulesAndPoliciesSolidDataset, roommateandcolleaguesPolicy);
    myRulesAndPoliciesSolidDataset = acp_ess_1.setPolicy(myRulesAndPoliciesSolidDataset, publicReadPolicy);

    // 6. Save the SolidDataset.
    const savedSolidDataset = await saveSolidDatasetAt(
      MY_ACP_SOLID_DATASET,
      myRulesAndPoliciesSolidDataset,
      { fetch: fetch }      // fetch from the authenticated session
    );
  } catch (error) {
    console.error(error.message);
  }
}

In particular, the example uses:

  1. getSolidDataset to retrieve the SolidDataset for storing your custom rules and policies.

    let myRulesAndPoliciesSolidDataset = await getSolidDataset(
      MY_ACP_SOLID_DATASET,
      { fetch: fetch }      // fetch from the authenticated session
    );
    
  2. acp_ess_1.createPolicy to initialize the new policies to save:

    let roommateandcolleaguesPolicy = acp_ess_1.createPolicy(`${MY_ACP_SOLID_DATASET}#roommates-colleagues-policy`);
    let publicReadPolicy = acp_ess_1.createPolicy(`${MY_ACP_SOLID_DATASET}#public-read-policy`);
    

    When creating the policy, pass in the target URL for the policy.

  3. acp_ess_1.addAnyOfRuleUrl and acp_ess_1.addAllOfRuleUrl to the rules for the policies:

    roommateandcolleaguesPolicy = acp_ess_1.addAnyOfRuleUrl(
        roommateandcolleaguesPolicy,
        `${MY_ACP_SOLID_DATASET}#colleagues-rule`       
    );
    roommateandcolleaguesPolicy = acp_ess_1.addAnyOfRuleUrl(
        roommateandcolleaguesPolicy,
        `${MY_ACP_SOLID_DATASET}#roommate-rule`       
    );
    
    publicReadPolicy = acp_ess_1.addAllOfRuleUrl(
      publicReadPolicy,
      `${MY_ACP_SOLID_DATASET}#public-rule`   // Rule matches anyone
    );
    

    The roomateandcollegauesPolicy applies if either the agent is matched by the colleagues-rule or the agent is matched by the roommate-rule.

    The publicReadPolicy applies if the agent is matched by the public-rule (i.e., any agent matches this rule).

  4. acp_ess_1.setAllowModes to specify the access modes for the policies:

    roommateandcolleaguesPolicy = acp_ess_1.setAllowModes(
      roommateandcolleaguesPolicy,
      { read: true, append: false, write: true },
    );
    
    publicReadPolicy = acp_ess_1.setAllowModes(
      publicReadPolicy,
      { read: true, append: false, write: false },
    );
    
  5. acp_ess_1.setPolicy to add the new policies to the SolidDataset.

    myRulesAndPoliciesSolidDataset = acp_ess_1.setPolicy(myRulesAndPoliciesSolidDataset, roommateandcolleaguesPolicy);
    myRulesAndPoliciesSolidDataset = acp_ess_1.setPolicy(myRulesAndPoliciesSolidDataset, publicReadPolicy);
    
  6. saveSolidDatasetAt to save the SolidDataset.

    const savedSolidDataset = await saveSolidDatasetAt(
      MY_ACP_SOLID_DATASET,
      myRulesAndPoliciesSolidDataset,
      { fetch: fetch }      // fetch from the authenticated session
    );
    

Apply Policies to a Resource#

Every Resource has an associated Access Control Resource (ACR). The Access Control Resource specifies the Access Policies that apply to its associated Resource. If the Resource is a Container, you can also specify Member Policies to the Resource’s ACR; the Member Policies gets propagated to the Resource’s children’s ACR.

The following example continues from the previous examples. Specifically, the example modifies a Resource’s access policies by adding to the Resource’s ACR the policies saved from the previous example.

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

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

const MY_POD_URL = "https://mypod.example.com/docsteam/";
const MY_ACP_SOLID_DATASET = `${MY_POD_URL}acp/myrulesandpolicies`;

async function setupAccessToResource() {
  try {
    
    // 1. Fetch the SolidDataset with its Access Control Resource (ACR).
    const resourceWithAcr = await acp_ess_1.getSolidDatasetWithAcr(
      `${MY_POD_URL}schedule/holidays`,
      { fetch: fetch }            // fetch from the authenticated session
    );

    // 2. Add the policies from previous examples to the ACR.
    let changedResourceWithAcr = acp_ess_1.addPolicyUrl(
      resourceWithAcr,
      `${MY_ACP_SOLID_DATASET}#roommates-colleagues-policy`
    );

    changedResourceWithAcr = acp_ess_1.addPolicyUrl(
      resourceWithAcr,
      `${MY_ACP_SOLID_DATASET}#public-read-policy`
    );

    // 3. Save the Resource with its ACR.
    const updatedResourceWithAcr = await acp_ess_1.saveAcrFor(
      changedResourceWithAcr, 
      { fetch: fetch }           // fetch from the authenticated session
    );

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

In particular, the example uses:

  1. acp_ess_1.getSolidDatasetWithAcr to retrieve the SolidDataset with its ACR.

    const resourceWithAcr = await acp_ess_1.getSolidDatasetWithAcr(
      `${MY_POD_URL}schedule/holidays`,
      { fetch: fetch }            // fetch from the authenticated session
    );
    
  2. acp_ess_1.addPolicyUrl to add policies (by their URLs) to the Resource’s ACR.

    let changedResourceWithAcr = acp_ess_1.addPolicyUrl(
      resourceWithAcr,
      `${MY_ACP_SOLID_DATASET}#roommates-colleagues-policy`
    );
    
    changedResourceWithAcr = acp_ess_1.addPolicyUrl(
      resourceWithAcr,
      `${MY_ACP_SOLID_DATASET}#public-read-policy`
    );
    
  3. acp_ess_1.saveAcrFor to the save the Resource with its ACR.

    const updatedResourceWithAcr = await acp_ess_1.saveAcrFor(
      changedResourceWithAcr, 
      { fetch: fetch }           // fetch from the authenticated session
    );
    

You can control access to the Access Control Resource (ACR) itself. For example, if you want others to be able to modify access policies for the Resource, you would give them write access the Resource’s ACR.

For brevity, the following example omits the logic to create https://mypod.example.com/acp/myrulesandpolicies#family-can-modify-policy:

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


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

const MY_POD_URL = "https://mypod.example.com/docsteam/";
const MY_ACP_SOLID_DATASET = `${MY_POD_URL}acp/myrulesandpolicies`;

// ... Logic to create the `${MY_ACP_SOLID_DATASET}#family-can-modify-policy` omitted for brevity.

async function setupAccessToResourceACR() {
  try {

    // 1. Fetch the SolidDataset with its Access Control Resource (ACR).
    const resourceWithAcr = await acp_ess_1.getSolidDatasetWithAcr(
      `${MY_POD_URL}schedule/holidays`,
      { fetch: fetch }          // fetch from the authenticated session
    );

    // 2. Add the policy that determines access, not to the Resource itself, but to the Resource's ACR.
    let changedResourceWithAcr = acp_ess_1.addAcrPolicyUrl(
      resourceWithAcr,
      `${MY_ACP_SOLID_DATASET}#family-can-modify-policy` 
    );

    // 3. Save the Resource with its ACR.
    const updatedResourceWithAcr = await acp_ess_1.saveAcrFor(
      changedResourceWithAcr, 
      { fetch: fetch }          // fetch from the authenticated session
    );

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

In particular, the example uses:

  1. acp_ess_1.getSolidDatasetWithAcr to retrieve the SolidDataset with its ACR.

    const resourceWithAcr = await acp_ess_1.getSolidDatasetWithAcr(
      `${MY_POD_URL}schedule/holidays`,
      { fetch: fetch }          // fetch from the authenticated session
    );
    
  2. acp_ess_1.addAcrPolicyUrl (instead of acp_ess_1.addPolicyUrl) to specify the ACR policy:

    let changedResourceWithAcr = acp_ess_1.addAcrPolicyUrl(
      resourceWithAcr,
      `${MY_ACP_SOLID_DATASET}#family-can-modify-policy` 
    );
    
  3. acp_ess_1.saveAcrFor to the save the Resource with its ACR.

    const updatedResourceWithAcr = await acp_ess_1.saveAcrFor(
      changedResourceWithAcr, 
      { fetch: fetch }          // fetch from the authenticated session
    );
    

Use Resource-specific Rules and Policies#

Access Control Policies allow you to set up access configurations that can be applied to multiple Resources. However, in some instances, you may want to set up Policies and Rules that apply to a single Resource.

Tip

To set up Policies and Rules that apply to a single Resource, use the universal access control APIs when possible. When not possible, you can use the ACP API to store Rules and Policies directly in the single Resource’s Access Control Resource (ACR).

The following example creates a resource-specific rules and policies:

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

const MY_POD_URL = "https://mypod.example.com/docsteam/";

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

async function createResourceSpecificRulesPolicies() {
  try {

    // 1. Fetch the SolidDataset with its Access Control Resource (ACR).
    const resourceWithAcr = await acp_ess_1.getSolidDatasetWithAcr(
      `${MY_POD_URL}reviews/someReview`,
      { fetch: fetch }          // fetch from the authenticated session
    );


    // 2. Create the Resource-specific Rule.
    let resourceRule = acp_ess_1.createResourceRuleFor(resourceWithAcr, "myrule-public")
    resourceRule = setPublic(resourceRule);

    // 3. Create the Resource-specific Policy.
    let resourcePolicy = acp_ess_1.createResourcePolicyFor(
      resourceWithAcr,
      "mypolicy-public",
    );

    // 4. Add the public matching rule as an allOf() expression.
    resourcePolicy = acp_ess_1.addAllOfRuleUrl(
      resourcePolicy,
      resourceRule
    );
    
    // 5. Specify the access modes for the policy.
    resourcePolicy = acp_ess_1.setAllowModes(
      resourcePolicy,
      { read: true, append: false, write: false },
    );

    // 6. Add the new Rule to the Access Control Resource.
    let changedResourceWithAcr = acp_ess_1.setResourceRule(
      resourceWithAcr,
      resourceRule,
    );

    // 7. Add the new Policy to the Access Control Resource.
    changedResourceWithAcr = acp_ess_1.setResourcePolicy(
      changedResourceWithAcr,
      resourcePolicy,
    );

    // 8. Save the Resource with its ACR.
    const updatedResourceWithAcr = await acp_ess_1.saveAcrFor(
      changedResourceWithAcr, 
      { fetch: fetch }          // fetch from the authenticated session
    );

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

In particular, the example uses:

  1. acp_ess_1.getSolidDatasetWithAcr to retrieve the SolidDataset with its ACR.

    const resourceWithAcr = await acp_ess_1.getSolidDatasetWithAcr(
      `${MY_POD_URL}reviews/someReview`,
      { fetch: fetch }          // fetch from the authenticated session
    );
    
  2. acp_ess_1.createResourceRuleFor to initialize the Resource-specific Rule.

    let resourceRule = acp_ess_1.createResourceRuleFor(resourceWithAcr, "myrule-public")
    resourceRule = setPublic(resourceRule);
    
  3. acp_ess_1.createResourcePolicyFor to initialize the Resource-specific Policy.

    let resourceRule = acp_ess_1.createResourceRuleFor(resourceWithAcr, "myrule-public")
    resourceRule = setPublic(resourceRule);
    
  4. acp_ess_1.addAllOfRuleUrl to the rule for the policy:

    resourcePolicy = acp_ess_1.addAllOfRuleUrl(
      resourcePolicy,
      resourceRule
    );
    
  5. acp_ess_1.setAllowModes to specify the access modes for the policy:

    resourcePolicy = acp_ess_1.setAllowModes(
      resourcePolicy,
      { read: true, append: false, write: false },
    );
    
  6. acp_ess_1.setResourceRule to add the new rule directly to the Resource’s ACR.

    let changedResourceWithAcr = acp_ess_1.setResourceRule(
      resourceWithAcr,
      resourceRule,
    );
    
  7. acp_ess_1.setResourcePolicy to add the new policy directly to the Resource’s ACR. This not only stores the policy definition in the ACR, but also applies the policy to the Resource.

    changedResourceWithAcr = acp_ess_1.setResourcePolicy(
      changedResourceWithAcr,
      resourcePolicy,
    );
    

    Note

    With regular Policies, after saving them to a resource-agnostic SolidDataset (e.g., Create Policies), they have to be applied explicitly to a Resource using various functions (e.g., Apply Policies to a Resource). With Resource-specific Policies, they are applied automatically to their Resource.

  8. acp_ess_1.saveAcrFor to the save the Resource with its ACR.

    const updatedResourceWithAcr = await acp_ess_1.saveAcrFor(
      changedResourceWithAcr, 
      { fetch: fetch }          // fetch from the authenticated session
    );
    

Modify Existing Access for a Resource#

The following example continues from the previous example to modify a Resource’s existing access policies:

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

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

const MY_POD_URL = "https://mypod.example.com/docsteam/";

async function modifyResourceAccessPolicies() {

  try {
    // 1. Fetch the SolidDataset with its Access Control Resource (ACR).
    const resourceWithAcr = await acp_ess_1.getSolidDatasetWithAcr(
      `${MY_POD_URL}schedule/holidays`,
      { fetch: fetch }            // fetch from the authenticated session
    );

    // 2. Get all Policies in the Resource's ACR
    const myResourceAccessPolicies = acp_ess_1.getPolicyUrlAll(resourceWithAcr);
    // ... Can loop through policies to view all policies. 

    // 3. Removes a specific Policy in the Resource's ACR (i.e., it no longer applies to the resource)
    
    let changedResourceWithAcr = acp_ess_1.removePolicyUrl(
      resourceWithAcr,
      `${MY_ACP_SOLID_DATASET}#roommates-colleagues-policy`
    );
            
    // 4. Save the Resource with its ACR.
    const updatedResourceWithAcr = await acp_ess_1.saveAcrFor(
      changedResourceWithAcr, 
      { fetch: fetch }           // fetch from the authenticated session
    );    

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

In particular, the example uses:

  1. acp_ess_1.getSolidDatasetWithAcr to retrieve the SolidDataset with its ACR.

    const resourceWithAcr = await acp_ess_1.getSolidDatasetWithAcr(
      `${MY_POD_URL}schedule/holidays`,
      { fetch: fetch }            // fetch from the authenticated session
    );
    
  2. acp_ess_1.getPolicyUrlAll to get the Policies that applies to the Resource.

    const myResourceAccessPolicies = acp_ess_1.getPolicyUrlAll(resourceWithAcr);
    // ... Can loop through policies to view all policies. 
    
  3. acp_ess_1.removePolicyUrl to remove a specific Policy.

    let changedResourceWithAcr = acp_ess_1.removePolicyUrl(
      resourceWithAcr,
      `${MY_ACP_SOLID_DATASET}#roommates-colleagues-policy`
    );
            
    
  4. acp_ess_1.saveAcrFor to the save the Resource with its ACR.

    const updatedResourceWithAcr = await acp_ess_1.saveAcrFor(
      changedResourceWithAcr, 
      { fetch: fetch }           // fetch from the authenticated session
    );    
    

View Existing Policies and Rules#

The following example continues from the previous examples. Specifically, it assumes the existence of the SolidDataset at https://mypod.example.com/acp/myrulesandpolicies that acts as a repository for the example rules and policies.

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

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

const MY_POD_URL = "https://mypod.example.com/docsteam/";
const MY_ACP_SOLID_DATASET = `${MY_POD_URL}acp/myrulesandpolicies`;

async function viewMyRulesAndPolicies() {

  try {
    // 1. Fetch the SolidDataset acting as a repository of my rules and policies.
    const myACPRespository = await getSolidDataset(
      MY_ACP_SOLID_DATASET,
      { fetch: fetch }          // fetch from the authenticated session
    );

    // 2. Get all Policies stored in that SolidDataset.
    const myExamplePolicies = acp_ess_1.getPolicyAll(myACPRespository);

    myExamplePolicies.forEach(mypolicy => {
      // ... policy processing logic omitted, such as to update the policy, etc.
    });
  
    // 3. Get a specific Policy stored in that SolidDataset.
    const mySpecificPolicy = acp_ess_1.getPolicy(
      myACPRespository,
      `${MY_ACP_SOLID_DATASET}#roommates-colleagues-policy`
    );
  
    // ... policy processing logic omitted, such as to update the policy, etc.

    // 4. Get all Rules stored in that SolidDataset.
    const myExampleRules = acp_ess_1.getRuleAll(myACPRespository);

    myExampleRules.forEach(myrule => {
      // ... rule processing logic omitted, such as to update the rule, etc.
    });
  
    // 5. Get a specific Rule stored in that SolidDataset.
    const mySpecificRule = acp_ess_1.getRule(
      myACPRespository,
      `${MY_ACP_SOLID_DATASET}#colleagues-rule`
    );
  
    // ... rule processing logic omitted, such as to update the rule, etc.
  } catch (error) {
      console.error(error.message);
  }
}

In particular, the example uses:

  1. getSolidDataset to fetch the SolidDataset.

    const myACPRespository = await getSolidDataset(
      MY_ACP_SOLID_DATASET,
      { fetch: fetch }          // fetch from the authenticated session
    );
    
  2. acp_ess_1.getPolicyAll to access all policies stored in the SolidDataset.

    const myExamplePolicies = acp_ess_1.getPolicyAll(myACPRespository);
    
    myExamplePolicies.forEach(mypolicy => {
      // ... policy processing logic omitted, such as to update the policy, etc.
    });
    
  3. acp_ess_1.getPolicy to access a specific policy stored in the SolidDataset.

    const mySpecificPolicy = acp_ess_1.getPolicy(
      myACPRespository,
      `${MY_ACP_SOLID_DATASET}#roommates-colleagues-policy`
    );
    
    // ... policy processing logic omitted, such as to update the policy, etc.
    
  4. acp_ess_1.getRuleAll to access all rules stored in the SolidDataset.

    const myExampleRules = acp_ess_1.getRuleAll(myACPRespository);
    
    myExampleRules.forEach(myrule => {
      // ... rule processing logic omitted, such as to update the rule, etc.
    });
    
  5. acp_ess_1.getRule to access a specific rule stored in the SolidDataset.

    const mySpecificRule = acp_ess_1.getRule(
      myACPRespository,
      `${MY_ACP_SOLID_DATASET}#colleagues-rule`
    );
    
    // ... rule processing logic omitted, such as to update the rule, etc.