# Error 403 for PATCH after creating document ACL

**URL:** <https://forum.solidproject.org/t/error-403-for-patch-after-creating-document-acl/3426>\
**Category:** Solid App Development FAQs\
**Created:** [September 3, 2020, 3:21pm UTC](https://forum.solidproject.org/t/error-403-for-patch-after-creating-document-acl/3426 "2020-09-03T15:21:43Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![FlorSanders](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/florsanders/32/1566_2.png) [@FlorSanders](https://forum.solidproject.org/u/FlorSanders)\
**Post date:** [September 3, 2020, 3:21pm UTC](https://forum.solidproject.org/t/error-403-for-patch-after-creating-document-acl/3426/1 "2020-09-03T15:21:43Z")

</div>

Hi

I’m working on a project where I need to change the ACL for some files and I’ve run into an issue, hoping I can find some help here in debugging it because I can’t seem to find where it goes wrong.

I have a script running that updates a file every ~30 secs with some new data using the rdflib updater. (Authentication happens using solid-auth-cli by Jeffz and I’m using the WebId of the actual Solid Pod)  
If the individual file does not have its own ACL yet, all works fine and I’m getting responses like this:

```auto
Updating the content at https://flordigipolis.inrupt.net/private/iot/urn:dev:mac:807d3afffe367a58_humidity.ttl with 1 messages.
    UpdateManager: Return success 200 elapsed 971ms
Succesfully updated resource at https://flordigipolis.inrupt.net/private/iot/urn:dev:mac:807d3afffe367a58_humidity.ttl

```

Though after adding the ACL suddenly I get 403 errors, like these:

```auto
Updating the content at https://flordigipolis.inrupt.net/private/iot/urn:dev:mac:807d3afffe367a58_humidity.ttl with 1 messages.
    UpdateManager: Return FAILURE undefined elapsed 1059ms
Error updating document: Web error: 403 (Forbidden) on PATCH of <https://flordigipolis.inrupt.net/private/iot/urn:dev:mac:807d3afffe367a58_humidity.ttl>

```

(Note: the first and third lines result from my own code, not the rdflib library)

At first I though something must be going wrong while creating the ACL, but when I print fetch it right after creating the document and it looks like this:

```auto
@prefix acl: <http://www.w3.org/ns/auth/acl#>.
@prefix foaf: <http://xmlns.com/foaf/0.1/>.

<#default> a acl:Authorization;
    acl:agent </profile/card#me>;
    acl:accessTo <./urn%3Adev%3Amac%3Ab4e62dfffe703f4d_light.ttl>;
    acl:mode acl:Append, acl:Control, acl:Read, acl:Write.
<#ReadWriteAppendControl-0> a acl:Authorization;
    acl:agent </profile/card#me>;
    acl:accessTo <./urn%3Adev%3Amac%3Ab4e62dfffe703f4d_light.ttl>;
    acl:mode acl:Read, acl:Write, acl:Append, acl:Control.

```

The rule I want to be in there is now in there twice, because I explicitly added the rule again to make sure. Though if I don’t do this it doesn’t make any difference to the end result.

Any idea of what could be going on? Or at least of how I could try to fix this?  
Thanks in advance

Edit: Just realized I copied the ACL and 403 error messages for different files, but I’ve tried the same action on different files and all give the same result. Sorry if this causes confusion.

---

<div class="post-metadata">

**Author:** ![Vincent](https://avatars.discourse-cdn.com/v4/letter/v/e9bcb4/32.png) [@Vincent](https://forum.solidproject.org/u/Vincent)\
**Post date:** [September 3, 2020, 3:44pm UTC](https://forum.solidproject.org/t/error-403-for-patch-after-creating-document-acl/3426/2 "2020-09-03T15:44:49Z")

</div>

Could you post the ACL and 403 messages for the correct files? And also possibly the ACL for the parent of the file you’re trying to update?

---

<div class="post-metadata">

**Author:** ![FlorSanders](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/florsanders/32/1566_2.png) [@FlorSanders](https://forum.solidproject.org/u/FlorSanders)\
**Post date:** [September 3, 2020, 5:23pm UTC](https://forum.solidproject.org/t/error-403-for-patch-after-creating-document-acl/3426/3 "2020-09-03T17:23:02Z")

</div>

Hi Vincent,  
The content of the different ACL files and 403 messages are identical other than the file name.  
I just shut down for today but I’ll make sure to post the ACL for the parent directory first thing tomorrow.

---

<div class="post-metadata">

**Author:** ![FlorSanders](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/florsanders/32/1566_2.png) [@FlorSanders](https://forum.solidproject.org/u/FlorSanders)\
**Post date:** [September 4, 2020, 6:42am UTC](https://forum.solidproject.org/t/error-403-for-patch-after-creating-document-acl/3426/4 "2020-09-04T06:42:27Z")

</div>

Okay so here’s an update: (Along with hopefully a better description of the situation)  
(I just created a new Pod to isolate the issue to what’s happening now.)

I have 3 files in the `/private/iot/` folder, created using rdflib’s `createIfNotExists`.  
Before sharing, only the private folder has an ACL, which looks like:

```auto
# ACL resource for the private folder
@prefix acl: <http://www.w3.org/ns/auth/acl#>.

# The owner has all permissions
<#owner>
    a acl:Authorization;
    acl:agent <https://cleenmail.inrupt.net/profile/card#me>;
    acl:accessTo <./>;
    acl:defaultForNew <./>;
    acl:mode acl:Read, acl:Write, acl:Control.

```

For managing the ACL I’m using the [SolidAclUtils by A\_A](https://github.com/Otto-AA/solid-acl-utils) which correctly gives me back the permissions from the `/private` folder when asking for the permissions on one of the files.

Up to this moment the updating works perfectly as well:

```auto
Updating the content at https://cleenmail.inrupt.net/private/iot/urn:dev:mac:807d3afffe367a58_humidity.ttl with 1 messages.
    UpdateManager: Return success 200 elapsed 387ms
Succesfully updated resource at https://cleenmail.inrupt.net/private/iot/urn:dev:mac:807d3afffe367a58_humidity.ttl

```

Then, when I try adding a permission to the ACL for one of the three files (i.c. the one ending on \_humidity), using the `acl.addRule(READ, url)` function, the following occurs:

1. The file now has its own ACL file with these contents:

```auto
@prefix acl: <http://www.w3.org/ns/auth/acl#>.
@prefix foaf: <http://xmlns.com/foaf/0.1/>.

<#owner> a acl:Authorization;
    acl:agent </profile/card#me>;
    acl:accessTo <./urn%3Adev%3Amac%3A807d3afffe367a58_humidity.ttl>;
    acl:mode acl:Read, acl:Write, acl:Control.
<#Read-0> a acl:Authorization;
    acl:agent <https://flordigipolis.solidweb.org/profile/card#me>;
    acl:accessTo <./urn%3Adev%3Amac%3A807d3afffe367a58_humidity.ttl>;
    acl:mode acl:Read.

```

1. The `/private` folder still has its own ACL file with unchanged contents.
2. My script now isn’t succeeding anymore in sending patches to the file in question.

```auto
Updating the content at https://cleenmail.inrupt.net/private/iot/urn:dev:mac:807d3afffe367a58_humidity.ttl with 1 messages.
    UpdateManager: Return FAILURE undefined elapsed 394ms
Error updating document: Web error: 403 (Forbidden) on PATCH of <https://cleenmail.inrupt.net/private/iot/urn:dev:mac:807d3afffe367a58_humidity.ttl>

```

1. My script still succeeds in patching the contents of the files in the same `/iot` folder.

```auto
Updating the content at https://cleenmail.inrupt.net/private/iot/urn:dev:mac:b4e62dfffe703f4d_light.ttl with 1 messages.
    UpdateManager: Return success 200 elapsed 363ms
Succesfully updated resource at https://cleenmail.inrupt.net/private/iot/urn:dev:mac:b4e62dfffe703f4d_light.ttl

```

As far as I can see there has been no permissions taken away upon the sharing of the file, only read permissions for an extra webId has been added. And still this causes the patch permissions to break.

Edit: Deleting the file in a tool like [Inrupts pod browser](https://pod-browser.vercel.app) apparently also deletes its ACL and thus resets the problem, so I’m able to reproduce the problem several times if necessary.  
Also, trying to add read permissions through the pod browser results in this (possibly unrelated) error:  
 ![image](https://europe1.discourse-cdn.com/flex017/uploads/solidproject/original/2X/6/6d438547f83037f8803bd78ecec662c663f3f224.png)

---

<div class="post-metadata">

**Author:** ![FlorSanders](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/florsanders/32/1566_2.png) [@FlorSanders](https://forum.solidproject.org/u/FlorSanders)\
**Post date:** [September 4, 2020, 7:13am UTC](https://forum.solidproject.org/t/error-403-for-patch-after-creating-document-acl/3426/5 "2020-09-04T07:13:13Z")

</div>

So, I have been trying some things to see what could be the issue since everyting looked like it was supposed to work.

1. I tried saving directly to the `/private` folder to make sure the issue wasn’t that the `private/iot` folder still didn’t have an ACL of its own after sharing files within it, this made no difference.
2. I changed the file name to something more simple (`file0.ttl`) (shorter and without special characters). This actually solved the issue!

Now the ACL looks like this:

```auto
@prefix acl: <http://www.w3.org/ns/auth/acl#>.
@prefix foaf: <http://xmlns.com/foaf/0.1/>.

<#owner> a acl:Authorization;
    acl:agent </profile/card#me>;
    acl:accessTo <./file0.ttl>;
    acl:mode acl:Read, acl:Write, acl:Control.
<#Read-0> a acl:Authorization;
    acl:agent <https://flordigipolis.solidweb.org/profile/card#me>;
    acl:accessTo <./file0.ttl>;
    acl:mode acl:Read.

```

Which is, other than the filename, identical to the one I got before.  
Now I don’t know if the cause is that the file name was too long or if it unsupported characters like colons.  
The fact that a file name can break the access control system does worry me though, might be something worth looking into.

Update: I tried again with the original file names, but just replaced all colons `:` with underscores `_` so the filename is immediately URI-safe and this works.  
Conclusion: Characters that aren’t URI-safe can cause trouble with access lists, avoid using them.

---

<div class="post-metadata">

**Author:** ![Vincent](https://avatars.discourse-cdn.com/v4/letter/v/e9bcb4/32.png) [@Vincent](https://forum.solidproject.org/u/Vincent)\
**Post date:** [September 4, 2020, 9:27am UTC](https://forum.solidproject.org/t/error-403-for-patch-after-creating-document-acl/3426/6 "2020-09-04T09:27:23Z")

</div>

Good work finding that! That sounds like a bug in the Pod server software used at [inrupt.net](http://inrupt.net), node-solid-server. Possibly you could [report there](https://github.com/solid/node-solid-server/issues/new) that it has trouble associating an ACL with resources with a colon in their name?

---

<div class="post-metadata">

**Author:** ![FlorSanders](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/florsanders/32/1566_2.png) [@FlorSanders](https://forum.solidproject.org/u/FlorSanders)\
**Post date:** [September 4, 2020, 9:33am UTC](https://forum.solidproject.org/t/error-403-for-patch-after-creating-document-acl/3426/7 "2020-09-04T09:33:14Z")

</div>

Sure thing, I will open an [issue](https://github.com/solid/node-solid-server/issues/1474).  
Edit: Link added for future reference

---

<div class="post-metadata">

**Author:** ![bourgeoa](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/bourgeoa/32/291_2.png) [@bourgeoa](https://forum.solidproject.org/u/bourgeoa)\
**Post date:** [September 4, 2020, 1:13pm UTC](https://forum.solidproject.org/t/error-403-for-patch-after-creating-document-acl/3426/8 "2020-09-04T13:13:26Z")

</div>

I tried to reproduce your problem,

- creating a file like test:test.txt with solid-ide
- adding an acl with solid-ide

and everything is correct. I can access the file and the linked ACL.  
So I suppose something else occur in your application.  
Your acl content is correct with acl:accessTo \<%-encoded filename\>

- How do you create the file ? what app are you using ?
- Are you URL’s correctly encoded/decoded ?  
[https://www.urlencoder.io/learn/#:~:text=ASCII%20control%20characters%20](https://www.urlencoder.io/learn/#:~:text=ASCII%20control%20characters%20)(e.g.%20backspace,have%20special%20meaning%20within%20URLs.

My understanding is that the filename logic is :

- NSS internally uses URL’s so they are %-encoded
- NSS mashlib displays %-decoded filenames
- solid NSS store on the filesystem the %-decoded filename

If you used a pod on solid.community I could check if there is a filename problem.

---

<div class="post-metadata">

**Author:** ![FlorSanders](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/florsanders/32/1566_2.png) [@FlorSanders](https://forum.solidproject.org/u/FlorSanders)\
**Post date:** [September 4, 2020, 2:30pm UTC](https://forum.solidproject.org/t/error-403-for-patch-after-creating-document-acl/3426/9 "2020-09-04T14:30:16Z")

</div>

Hi @bourgeoa

> [@bourgeoa](#):
>
> How do you create the file ? what app are you using ?

The file is created using rdflib.js fetcher’s `createIfNotExists()` function. Though admittedly I’m not pre-%-encoding the filename, just pass that down as an argument with colons and all. This seems to create the file no problem, at least it doesn’t give any errors.

> [@bourgeoa](#):
>
> Are you URL’s correctly encoded/decoded ?

When I fetch a filelist using Jeffz’s solid-file-client the filename is still percent-encoded, so once it’s encoded it seemingly doesn’t get decoded anymore. (Also the percent-encoded filename is visible in the podbrowser etc)

> [@bourgeoa](#):
>
> and everything is correct. I can access the file and the linked ACL.

Well I can also still access and edit the file using the built-in ui and other apps like the pod-browser, it’s patch requests that get rejected. (Called using rdflib.js updater)

> [@bourgeoa](#):
>
> If you used a pod on solid.community I could check if there is a filename problem.

I have a pod on solid.community with %-encoded files in the `https://flordigipolis.solid.community/private/iot/` folder. Though on those files I managed to remove my own access altogether (some older less succesful experiments).

---

<div class="post-metadata">

**Author:** ![FlorSanders](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.solidproject.org/florsanders/32/1566_2.png) [@FlorSanders](https://forum.solidproject.org/u/FlorSanders)\
**Post date:** [September 4, 2020, 3:24pm UTC](https://forum.solidproject.org/t/error-403-for-patch-after-creating-document-acl/3426/10 "2020-09-04T15:24:10Z")

</div>

@bourgeoa Since you couldn’t seem to reproduce the issue, I wrote a small script which seems to do the trick.

```auto
import auth from 'solid-auth-cli';
import $rdf from 'rdflib';
import aclClient from 'ownacl';

export const IDENTITY_PROVIDER = 'https://solid.community';
export const USERNAME = 'USERNAME';
export const PASSWORD = 'PASSWORD';

const FILE = 'https://flordigipolis.solid.community/private/test:test.ttl';
var RDF = $rdf.Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#");

const run = async function () {
    try {
        // Log in
        console.log('Logging in...');
        var session = await auth.currentSession();
        if (!session) session = await auth.login({ idp: IDENTITY_PROVIDER, username: USERNAME, password: PASSWORD });
        console.log(`Logged in as ${session.webId}`);
        
        // Initialize rdflib constructs
        const store = $rdf.graph();
        const fetcher = new $rdf.Fetcher(store);
        const updater = new $rdf.UpdateManager(store);

        // Create file
        await fetcher.createIfNotExists($rdf.sym(FILE), 'text/turtle', '');

        // Send first update
        console.log('Sending first update...')
        const add1 = $rdf.st($rdf.sym('http://example.org/somePerson'), RDF('type'), $rdf.sym('http://example.org/person'), $rdf.sym(FILE));
        updater.update(null, add1, async (uri, ok, msg) => {
            if(ok){
                console.log('First update sent\nAdding an extra read permission to the ACL...')

                const acl = new aclClient(`${FILE}.acl`);
                var accessControl = await acl.readAccessControl();
                console.log('Original access control:')
                console.log(accessControl);
                const agent = { name: 'http://flordigipolis.inrupt.net/profile/card#me', access: ['Read'] }
                await acl.addAgent(agent);
                var accessControl = await acl.readAccessControl();
                console.log('New access control:')
                console.log(accessControl);

                console.log('Extra read permission added\nSending second update...')
                // Send second update
                const add2 = $rdf.st($rdf.sym('http://example.org/someOtherPerson'), RDF('type'), $rdf.sym('http://example.org/person'), $rdf.sym(FILE));
                updater.update(null, add2, (uri, ok, msg) => {
                    if(ok){
                        // Update happened succesfully
                        console.log('Second update sent')
                    } else {
                        console.log(msg);
                    }
                })
            } else {
                // Something went wrong
                console.log(msg);
            }
        })
    } catch (err) {
        console.log(err)
    }
}

run()

```

This should reproduce the issue when running it in a Node environment (sorry for the hardcoded variables, this was quickly put together).  
When I run it the following happens:

- First run everything goes fine, it creates the file, adds the first update, creates the ACL (printed before and after in console) and performs the second update.
- If I run it a second time however, I get a 403 error at the createIfNotExists command.  
Also, when I go look on my pod, I have seem to have lost all permissions over the file in question.
- Critically, this does not happen if I simply remove the `:` in the `FILE` variable, then everything just works fine, no matter how many times I run the script.

Hope this helps (maybe you can figure some things out by looking at the file on my Pod).
