[SOLVED] Solid-Client create ACL for container makes agent lose control

Edit: I’ve posted a simplified and clearer example below as a comment.

I have a question to the usage of the ACL module in @inrupt/solid-client.

I create a new resource locally, send it to the pod, where a new container and the resource is persisted.

Hierarchy like this:

.
|-- my-example
|  |-- new-container
|  |  |-- new-resource.ttl

I want to set the ACL now for both the new resource and the new container to: public: read-only, agent: control
I do this with:

setAgentResourceAccess(resourceAcl, 'https://janschill.net/profile/card#me', {
            read: false, write: false, append: false, control: true
          })

setPublicResourceAccess(resourceAcl, {
  read: true, write: false, append: false, control: false
})

Both ACL files are created when I push everything up to the pod, but I lose control. Looking at the containers newly created ACL file tells me that I (WebId) have weird access rights:

n0:ControlReadWrite
    a n1:Authorization;
    n1:accessTo sc:;
    n1:agent <mailto:schill@hey.com>;
    n1:default sc:;
    n1:mode n1:Control, n1:Read, n1:Write.

This is indeed my email address, but I am not referenced with my WebId like it is done in other ACLs with n1:agent c:me for example.

There are also these two entries, which I don’t quite understand, but it seems to be the controls, I’ve set?

:16143697092612634176570800957
    a n1:Authorization;
    n1:agent c:me;
    n1:default sc:;
    n1:mode n1:Control, n1:Read, n1:Write.
:16143697092639940288503178427
a n1:Authorization; n1:accessTo sc:; n1:agent c:me; n1:mode n1:Control.

Is there something obvious I am missing? Thank you for the help.

I have simplified my scripts, but the problem remains.

// created a new resource at myContainerUrl, which created myContainerUrl
// myContainerUrl and the resource get the ACL from app-root
// now I want to set the container ACL
const webId = "https://janschill.net/profile/card#me"
const myContainerUrl = "https://janschill.net/app-root/my-container/"
const myDatasetWithAcl = await getSolidDatasetWithAcl(myContainerUrl, { fetch: fetch })
const resourceAcl = createAcl(myDatasetWithAcl)
const updatedAcl = setAgentResourceAccess(
  resourceAcl,
  webId,
  { read: true, append: true, write: true, control: true }
)
await saveAclFor(myDatasetWithAcl, updatedAcl, { fetch: fetch })
const myUpdateDatasetWithAcl = await getSolidDatasetWithAcl(myContainerUrl, { fetch: fetch })
const agentAccess = getAgentAccess(myUpdateDatasetWithAcl, webId)

When I do this it creates an ACL with:

@prefix : <#>.
@prefix n0: <http://www.w3.org/ns/auth/acl#>.
@prefix sc: <./>.
@prefix c: </profile/card#>.

:1614379761250894769371517192
    a n0:Authorization;
    n0:accessTo sc:;
    n0:agent c:me;
    n0:mode n0:Control, n0:Read, n0:Write.

Which then does not allow me to create another resource in it:

No authorized session found. Error: Storing the Resource at [https://janschill.net/app-root/my-container/20210226T224931104Z.ttl] failed: [403] [].

The SolidDataset that was sent to the Pod is listed below.

…

I’ve changed the paths for this example slightly, because they are not relevant. Just so you don’t bother checking the URLs out.

Hi Jan, I think what may be the problem there is that while you have write access to the Container, the ACL does not specify any access that applies for children of that Container without an ACL, and therefore does not give you write access to them.

To set this access, you’ll probably want to replace

const updatedAcl = setAgentResourceAccess(
  resourceAcl,
  webId,
  { read: true, append: true, write: true, control: true }
)

with

let updatedAcl = setAgentResourceAccess(
  resourceAcl,
  webId,
  { read: true, append: true, write: true, control: true }
)
updatedAcl = setAgentDefaultAccess(
  updatedAcl,
  webId,
  { read: true, append: true, write: true, control: true }
)

(So in addition to specifying Resource access on the Container, you also set Default access, which specifies what access people have by default on children if they do not have their own ACL.)

Also make sure that that second call extends updatedAcl, not resourceAcl again.

Let us know if that helps.

2 Likes

Perfect, this was exactly what resolved the issue. Thank you very much!

2 Likes

Great, thanks for reporting back - taught me something about how ACLs get applied to not-yet-existing child Resources too :slight_smile: