Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

defaultAccessContainer Link header #531

Open
bblfish opened this issue Jun 6, 2023 · 1 comment
Open

defaultAccessContainer Link header #531

bblfish opened this issue Jun 6, 2023 · 1 comment

Comments

@bblfish
Copy link
Member

bblfish commented Jun 6, 2023

This proposal solves the 2n+1 request cost problem for finding the effective ACL of a resource, reducing it down to a max of 2, while being fully compatible with the current spec. I have implemented this in Solid-Control Pr25 and have built a crawler script in SolidCtrl App repo.

The idea is simple: A server can add a defaultAccessContainer link to a resource, pointing to the effective ACL container, which will point using the acl link to the effective acl. This is similar to the proposal in #325, which pointed directly to the effective acl. The problem with that proposal became apparent implementing a client. Fetching the direct acl for a resource makes it difficult for later requests on subresources of the default container to search their own cache for a potential default ACL candidate.

Short description

We want a client to make as few requests as possible. So if it is crawling a Linked Data Event Stream or blogs on a server, it should, ideally once it has found the default ACL for one resource, be able to guess that all the other resources located in that container or subcontainers can be accessed using the same authentication mechanism. Meaning that if the LDES stream is 100 resources it would only need to make

  1. a request to the resource R1 and receive a 401 with link to the default ACL dir using link type "defaultAccessContainer" to the ../../ which resolves to Cd
  2. HEAD on default ACL dir Cd which points to ACL Ar
  3. fetch ACL Ar
  4. fetch R1 with signed header successfully
  5. fetch 99 other resources successfully, as long as they are in that container. (it is possible that some subcontainers have different access rules, but then a client would just start at 1 above again)

so the total number of requests would be 100+3

The direct link to the ACL reduces that by 1 to 100+2,
but it means that a client cache that presumably is following links around the web does not have information in its DB going directly from the container with the effective acl to the acl. That means that basic caches cannot be used, but one needs to enhance those with information about incoming links.
(Note: I have been thinking this through in this document The Cache)

Detailed description

GET /ldes/defaultCF/stream HTTP/1.1
Host: localhost:8080
Accept: text/turtle, application/n-triples, application/rdf+xml, application/ld+json
Date: Sat, 03 Jun 2023 16:16:33 GMT
Connection: keep-alive
User-Agent: http4s-ember/1.0.0-M39

This returns a response containing an

  • acl link to the resource that currently does not exist but that the client can edit to create a specialised access control rule for that resource.
  • a defaultAccessContainer link to the container that contains an existing acl with a default rule.
HTTP/1.1 401 Unauthorized
WWW-Authenticate: HttpSig realm="http://localhost:8080/ldes/defaultCF/stream"
Link: <http://localhost:8080/ldes/defaultCF/stream.acl>; rel=acl, <http://localhost:8080/ldes/defaultCF/>; rel=defaultAccessContainer
Server: reactive-solid/0.3 akka-http/10.2.10
Date: Sat, 03 Jun 2023 16:16:33 GMT
Content-Length: 0

Seeing the defaultAccessControl link, the client follows that link with a HEAD to find the effective acl link.

HEAD /ldes/defaultCF/ HTTP/1.1
Host: localhost:8080
Accept: text/turtle, application/n-triples, application/ld+json;q=0.8, application/rdf+xml;q=0.8
Date: Sat, 03 Jun 2023 16:16:33 GMT
Connection: keep-alive
User-Agent: http4s-ember/1.0.0-M39
Content-Length: 0

HTTP/1.1 401 Unauthorized
WWW-Authenticate: HttpSig realm="http://localhost:8080/ldes/defaultCF/"
Link: <http://localhost:8080/ldes/defaultCF/.acl>; rel=acl
Server: reactive-solid/0.3 akka-http/10.2.10
Date: Sat, 03 Jun 2023 16:16:33 GMT
Content-Length: 0

From that, the client can find the acl rules

GET /ldes/defaultCF/.acl HTTP/1.1
Host: localhost:8080
Accept: text/turtle, application/n-triples, application/ld+json;q=0.8, application/rdf+xml;q=0.8
Date: Sat, 03 Jun 2023 16:16:33 GMT
Connection: keep-alive
User-Agent: http4s-ember/1.0.0-M39

HTTP/1.1 200 OK
Last-Modified: Sat, 06 May 2023 09:37:47 GMT
ETag: "1683365867128_486_24083069"
Allow: GET, PUT, DELETE, HEAD, OPTIONS
Link: <http://www.w3.org/ns/ldp#Resource>; rel=type, <http://localhost:8080/ldes/defaultCF/.acl>; rel=acl, <http://localhost:8080/ldes/defaultCF/.acl>; rel=latest-version, <http://localhost:8080/ldes/defaultCF/.acl.0>; rel=predecessor-version
Server: reactive-solid/0.3 akka-http/10.2.10
Date: Sat, 03 Jun 2023 16:16:33 GMT
Content-Type: text/turtle
Content-Length: 486

@prefix wac: <http://www.w3.org/ns/auth/acl#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix security: <https://w3id.org/security#> .

<#R0> a wac:Authorization; 
   wac:mode wac:Control;
   wac:default <.> .

<#R1> a wac:Authorization; 
   wac:mode wac:Read;
   wac:agentClass foaf:Agent ;
   wac:accessTo <.acl> .

<#R2> a wac:Authorization; 
   wac:agent _:a ;
   wac:mode wac:Read, wac:Write;
   wac:default <.> .

</rfcKey#> security:controller _:a . 

With that information, the client can then authenticate with a signed request using HTTP-Sig in this case

GET /ldes/defaultCF/stream HTTP/1.1
Host: localhost:8080
Accept: text/turtle, application/n-triples, application/rdf+xml, application/ld+json
Signature-Input: sig1=();created=1685808993;keyid="http://localhost:8080/rfcKey#"
Signature: sig1=:iKfT6OcNPWegDWjHQbsjJ+1ELopixW5FXDMyPYJHQDr2P4duHHDIcjI9Y4S6/bgODK/v1y+aQqzN17ETUFvHh8ULBp2ABcWwjfnk96+fwXjA5WAsF0RaE813GjJMIstWLITHvqQBQHa84BqhGKr5R8fQCKKeehedINvD59rn4zmvQx8WXYvSOxTMdGvtAb59nUXY2n7+Hb7pvCGj3P09Zl23kcMkOKSq1Sz/OIse/7MQAaULsOW8931rGb9RQVhbsyGIuDtuPrlYVz0jO0gnk2hDKFJL7gXAEKQ8UokwMyiZghXOKRpROsS4vRgvTirEEtV2aOaTTfCummeUjaidgQ==:
Authorization: HttpSig proof=sig1
Date: Sat, 03 Jun 2023 16:16:33 GMT
Connection: keep-alive
User-Agent: http4s-ember/1.0.0-M39

If a client wants to make a request later to /ldes/defaultCF/2023/06/06/00_08, the client can search through the local cache hierarchy all the way down to /ldes/defaultCF/ following reverse ldp:contains links or just the directory structure, and from there find the link to the effective acl, that will also be in the cache due to the interaction above. That can be done very efficiently as it requires no internet communication. (see also #528 ), allowing the client to sign the next request immediately.

@bblfish
Copy link
Member Author

bblfish commented Jun 21, 2023

I have a screencast of a demo of how the defaultAccessContainer link works here
https://twitter.com/bblfish/status/1666547828506742788

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant