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

Propose access request with LDN #28

Merged
merged 1 commit into from
Apr 7, 2021
Merged

Conversation

RubenVerborgh
Copy link
Contributor

@RubenVerborgh RubenVerborgh commented Aug 30, 2019

Status: draft intended for feedback.

This PR follows up on #27 by providing a generic mechanism that allows agents to request permissions to resources. It supports:

  • one or multiple agents
  • groups
  • for all apps or for specific apps
  • different modes (Read / Append / Write / Control)
  • for one or multiple resources
  • multiple permissions blocks for different agents
  • any future extensions to WebACL documents

As currently drafted, it also supports:

  • requesting append operations to any RDF document

@zenomt
Copy link
Contributor

zenomt commented Sep 1, 2019

for evaluation, it would be useful to have more detail in this proposal, including operational details (such as how an approval process could work between steps 3 and 4).

also it would be useful and instructive to see a complete practical example similar to the one in my proposal that illustrates how the parties (that is: requester, resource server, approver) fit together, and how they transition between their different states.

@RubenVerborgh
Copy link
Contributor Author

RubenVerborgh commented Sep 1, 2019

how an approval process could work between steps 3 and 4

That's is an internal matter though; it's not visible in the communication, which is what this process governs. There are many different ways for such an internal process to work (and the proposal purposely does not constrain them). One of them is an app that handles requests matching the suggested shape, and presents them to a user in natural language.

Any other specific details that would be needed?

also it would be useful and instructive to see a complete practical example similar to the one in my proposal

The draft is basically only such an example at the moment. Will add some more description.

@RubenVerborgh RubenVerborgh force-pushed the feature/ldn-access-request branch 2 times, most recently from 96f0d18 to 86e3327 Compare September 1, 2019 16:09
@RubenVerborgh RubenVerborgh force-pushed the feature/ldn-access-request branch from 86e3327 to cad3901 Compare September 1, 2019 16:09
@zenomt
Copy link
Contributor

zenomt commented Sep 1, 2019

Any other specific details that would be needed?

lots more details would be needed to evaluate the proposal. however, a good start would be the two previously requested.

if how an approval process could work (including how an app might help the user participate in the process) is out of scope, then some indication of how a workable user experience for approval might fit in with the flow you imagine would be useful. for example, do you imagine the user having an approval app sitting in a window off to the side, listening for incoming permission requests? do you imagine some parallel means by which an app might be alerted to direct the user to an approval app or page or ...?

by "complete practical example similar to the one in my proposal", i meant annotated HTTP exchange(s) that show exactly what you mean (even if some things like exact data formats and link relation names are preliminary).

some other details that would be useful to know, for a start:

  1. do you need authorization credentials to post to the permission request inbox?
  2. do you imagine the permission request inbox will always have the same URI?
  3. what if the server determines it's not appropriate to allow this client to make a permission request?
  4. to what inbox would the resource server send an accept/denied notification? are credentials needed to post to that?
  5. how does the app get permission to read the notification inbox in the first place?
  6. do you imagine that permission requests would be explicitly for the exact permission to the exact resource(s) required, or do you imagine that the common case would be that the server would interpret the request as a representative example of the kind of access required, and let/help the approver generalize the request to what's actually needed?

there will be more questions as details are filled in.

@RubenVerborgh
Copy link
Contributor Author

RubenVerborgh commented Sep 1, 2019

Thanks for following up.

lots more details would be needed to evaluate the proposal.

Note that at this moment, I'm mainly looking for an evaluation of the idea, that idea being "let's solve it with LDN". If that general direction is confirmed to be promising, a more formal description would be proposed.

however, a good start would be the two previously requested.

annotated HTTP exchange(s) that show exactly what you mean (even if some things like exact data formats and link relation names are preliminary).

This proposal does not define a new protocol of API over HTTP; it reuses the LDN protocol. The only thing this proposal does is constrain LDN messages. Therefore, I would not include detailed HTTP requests in the proposal, not even in the formalized version, since they would be (selectively and thus inadequately) repeating the LDN spec and its underlying LDP spec. I imagine that we would have several proposals for Solid that are merely constraints over LDN, so repeating LDN in every proposal would not be meaningful.

The list of required interactions is of course relevant, but that is already in the proposal.

To answer your question and to facilitate discussion, I will copy requests from https://www.w3.org/TR/ldn/#protocol below and instantiate them with the examples of the document.

Request from requesting agent to resource server

POST /inbox/ HTTP/1.1
Host: resources
Content-Type: text/turtle

@prefix acl: <http://www.w3.org/ns/auth/acl#>.
@prefix as: <https://www.w3.org/ns/activitystreams#>.
@prefix tbd: <http://example.org/to-be-determined#>.
[
  a tbd:AppendRequest;
    as:actor <https://user/#me>;
    as:target <https://resources/documents/x.acl>;
    as:object [
      a acl:Authorization;
      acl:agent <https://user/#me>;
      acl:accessTo <https://resources/documents/x>;
      acl:mode acl:Read, acl:Write;
    ];
].

Response from resource server

HTTP/1.1 201 Created
Location: https://resources/inbox/1234.ttl

Request from processing agent to inbox of requesting agent

POST /inbox/ HTTP/1.1
Host: requesting-agent
Content-Type: text/turtle

@prefix as: <https://www.w3.org/ns/activitystreams#>.
[
  a as:Accept; # or as:Reject
    as:object <https://resources/inbox/1234.ttl>;
    as:target  <https://resources/documents/x.acl>; # or just /x
].

Response from inbox of requesting agent

HTTP/1.1 201 Created
Location: https://requesting-agent/inbox/5678.ttl
  1. do you need authorization credentials to post to the permission request inbox?

The proposal does not constrain this. Whichever party is managing the inbox can choose so freely, and will use the existing mechanisms from the Solid specification to indicate this.

  1. do you imagine the permission request inbox will always have the same URI?

The proposal does not constrain this. It might or might not.

  1. what if the server determines it's not appropriate to allow this client to make a permission request?

This is handled by the LDN specification, which states at https://www.w3.org/TR/ldn/#constraints:

Senders should comply with constraint specifications or the receiver may reject their notification and return an appropriate 4xx error code.

  1. how does the app get permission to read the notification inbox in the first place?

The app does not necessarily need that permission. Notifications of acceptance or rejection can be read by different apps; and their reception by the requesting app is optional.

  1. do you imagine that permission requests would be explicitly for the exact permission to the exact resource(s) required, or do you imagine that the common case would be that the server would interpret the request as a representative example of the kind of access required, and let/help the approver generalize the request to what's actually needed?

The proposal does not constrain this; both are possible. However, I do not expect it to be the common case. Requesters should ask for the permissions they need.

One possible configuration could be to have an agent automatically reject certain requests. For instance, requests for multiple documents, requests by people that are not in my address book, etc. But none of these belong in the proposal, which only governs the communication, not the internal processes.

@zenomt
Copy link
Contributor

zenomt commented Sep 1, 2019

Note that at this moment, I'm mainly looking for an evaluation of the idea, that idea being "let's solve it with LDN".

i think it's obvious that such an idea could be made to work, and in fact multiple non-me people expressed a preference for this approach in #27. therefore, more detail (particularly in the context of the use cases this panel is considering) would be helpful.

regarding "annotated HTTP exchange(s) that show exactly what you mean", i meant starting from the original request that gets denied, perhaps illustrating a likely common use case, through "then the app can try again". such an operational example would be crucial in the proposal, along with explorations of different possible (non-limiting) alternatives at different decision points. this will aid understanding of how this approach can address different use cases, be realized in implementation, and what the user experience might be like.

@RubenVerborgh
Copy link
Contributor Author

more detail (particularly in the context of the use cases this panel is considering) would be helpful.

Are there any from the list https://github.com/solid/app-authorization-panel/blob/master/UseCases.md in particular which you want me to step through?
It seems that most can be extrapolated from the example I've provided, but happy to help where that is not the case.

starting from the original request that gets denied

Note that this is just one of many entry points into the scenario. I will document one possible approach to that specific entry point here.

Request from requesting agent to resource server

GET /documents/x HTTP/1.1
Host: resources
Authorization: Bearer secret

Response from resource server

HTTP/1.1 403 Forbidden
Link: </inbox/>; rel="http://www.w3.org/ns/ldp#inbox"

perhaps illustrating a likely common use case

The above requests could be followed by the requests detailed in #28 (comment)

through "then the app can try again"

Request from requesting agent to resource server

GET /documents/x HTTP/1.1
Host: resources
Authorization: Bearer secret

Response from resource server

If accepted, then:

HTTP/1.1 200 OK

Otherwise, again the 403 from above.

@elf-pavlik
Copy link
Member

I like this LDN approach. Based on #27 (comment) I still see the example in this PR not dealing with anything specific to applications.

for all apps or for specific apps

I understand that would need to get requested from a particular RS only in situations where RS doesn't honor user preference published by the user someone else - kind of global app authorization granted by the user to application - or user doesn't have such preference published.
In that case how would the request to RS hosting specific resouce look if person already has needed access to that specific resource and would only like to restrict it to some specific application(s)? Also keeping in mind #24 how one can later revoke such authorization for some / all of authorized applications, without removing person's own access all together?

@michielbdejong
Copy link
Contributor

@RubenVerborgh thanks for joining our efforts here! can you add yourself as a panelist please?

@RubenVerborgh
Copy link
Contributor Author

I still see the example in this PR not dealing with anything specific to applications.

@elf-pavlik That would likely be an extra triple in the permissions block. However, I don't think we have such a predicate yet (that would probably be the subject of another PR); unless I'm overlooking something in https://github.com/solid/web-access-control-spec.

But imagine something like

[
  a tbd:AppendRequest;
    as:actor <https://user/#me>;
    as:target <https://resources/documents/x.acl>;
    as:object [
      a acl:Authorization;
      acl:agent <https://user/#me>;
      acl:accessTo <https://resources/documents/x>;
      acl:mode acl:Read, acl:Write;
      tbd:fromOrigin <https://app>; # <== add origins here
    ];
].

In that case how would the request to RS hosting specific resouce look if person already has needed access to that specific resource

The conditions on which a processing agent grants access are not specified here. It could look up the existing ACL, or it could not. We might want to suggest such a process (but I'd consider that a different, orthogonal PR).

and would only like to restrict it to some specific application(s)?

I don't think "restriction" is the desired interpretation. It all depends on how the ACL specifies it though. It seems that we have a dependency on WebACL actually; regardless of the chosen protocol, they probably need to figure out first how to represent app-specific permissions in an ACL document, since otherwise we can't store these.

Also keeping in mind #24 how one can later revoke such authorization for some / all of authorized applications,

There are at least two different cases: the requester asking to remove permissions, or the processing agent (or even a third party). The way ACLs are currently written, this would need a deletion request of some kind for the requester. Other scenarios could work differently.

can you add yourself as a panelist please?

@michielbdejong Thanks, I appreciate the invite. However, I'm already quite committed panel-wise, and am discussing #27/#28 in my capacity of Data Interoperability and Notifications panel member. Feel free to just consider me a regular member of the public for these now 🙂

@dmitrizagidulin
Copy link
Member

Let's leave aside, for the moment, the fact that inboxes / LDN in Solid is currently not ready for use (there are numerous issues with it, such as - Solid servers currently do not record who created a particular notification, and there are many spoof and XSS vectors).

I think this proposal (requesting access with LDN) is trying to solve a very different problem than @zenomt's privilege request protocol, and is trying to solve it at the wrong level (at an application-specific level, rather than at the HTTP / REST level).

@csarven
Copy link
Member

csarven commented Sep 17, 2019

@dmitrizagidulin You bring that argument up about LDN/Solid not being "ready" or having "issues" every now and then, and my response is the same: in what way are those issues or shortcomings unique to LDN and virtually not any other interaction in context of Solid or say LDP for read/write?

@dmitrizagidulin
Copy link
Member

@csarven The difference is - the Inbox is world-writeable, and the rest of the pod is not.

@RubenVerborgh
Copy link
Contributor Author

RubenVerborgh commented Sep 17, 2019 via email

@elf-pavlik
Copy link
Member

How does one request access without having public append on the access request inbox container?

@RubenVerborgh
Copy link
Contributor Author

The general inbox normally needs to have public append, to be able to receive messages from anyone. More specific inboxes might be less open. For instance, a resource A could decide that only people from a certain group can request access. Or only people who are logged in.

Moreover, the URL of the request inbox to A could only be exposed to only a small group; i.e., not everyone who gets denied access is given the opportunity to request it.

@csarven
Copy link
Member

csarven commented Sep 17, 2019

@dmitrizagidulin I think it goes without saying that any authorization policy, at any time (and duration), for any reason, can precede that expectation.

@elf-pavlik That's a fair point but it is orthogonal to whether an inbox is public append and subject to the perceived Inbox-centric issues. If it holds true for an inbox container, it holds true for any other resource.

@csarven
Copy link
Member

csarven commented Sep 17, 2019

@elf-pavlik Pardon me, I didn't actually answer your question. Ruben already answered I think. Given that if a specific actor is not mentioned in a policy and that the container is not public append, then I suppose it is not possible as there is no way to inform the target about the request through a notification. So, the system is essentially locked down and it doesn't seem like the sender can be usefully verified any way. If some message were to get through, then there'd be possibilities eg. requester also places their request in their outbox whereby the target entity (the one controlling the access request inbox container) checks to see if the information matches the notification that they've received in the inbox.

@elf-pavlik
Copy link
Member

Thanks for clarifications @RubenVerborgh and @csarven

Or only people who are logged in.

I see the distinct acl:AuthenticatedAgent , @csarven can correct me but that seems like what would match this SHOULD recomendation on inbox https://www.w3.org/TR/ldn/#sender-verification

If some message were to get through, then there'd be possibilities eg. requester also places their request in their outbox whereby the target entity (the one controlling the access request inbox container) checks to see if the information matches the notification that they've received in the inbox.

If inbox uses acl:AuthenticatedAgent for append permission this doesn't seem like a necessary step.

Solid servers currently do not record who created a particular notification

This sounds like implementation specific issue, maybe also possibly something for Data Interoperability panel to address - eg. validation of something like dcterms:creator (required by shape) matching WebID of authenticated user.

@RubenVerborgh
Copy link
Contributor Author

RubenVerborgh commented Sep 17, 2019 via email

@justinwb
Copy link
Member

@RubenVerborgh I believe that we have covered this exchange in the interoperability panel as part of the Data Authorization workflows. After we've had a change to discuss, I think we could probably close this, but will keep it open until we do.

@csarven
Copy link
Member

csarven commented Oct 15, 2020

@justinwb To be clear, from the point of panel proposals, the linked Data Authorization is a proposal. It is on equal grounds with the proposal in this PR. We can't just close this issue, especially if the data interop panel didn't take it into account / acknowledge its existence prior to writing up a proposed solution in one of its own documents. Significant amount of work is put into creating issues and PRs and they ought to be processed prior to writing up alternatives on an open canvas and dismissing existing work/proposals.


## Request access shape

_This example needs to be formalized into a SHACL and/or ShEx shape._

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quick guess:

PREFIX acl: <http://www.w3.org/ns/auth/acl#>
PREFIX as: <https://www.w3.org/ns/activitystreams#>
PREFIX tbd: <http://example.org/to-be-determined#>


tbd:ReqShape {
  a [tbd:AppendRequest]? ;
  as:actor IRI ;
  as:target IRI ;
  as:object {
    a [acl:Authorization] ;
    acl:agent IRI ;
    acl:accessTo IRI ;
    acl:mode [acl:Read acl:Write acl:Whatever]+
  }
}

[try it]

@justinwb
Copy link
Member

@justinwb To be clear, from the point of panel proposals, the linked Data Authorization is a proposal. It is on equal grounds with the proposal in this PR. We can't just close this issue, especially if the data interop panel didn't take it into account / acknowledge its existence prior to writing up a proposed solution in one of its own documents. Significant amount of work is put into creating issues and PRs and they ought to be processed prior to writing up alternatives on an open canvas and dismissing existing work/proposals.

@csarven I don't think it's appropriate to say that work done in another panel equates to a conscious dismissal of work in another. You are leaping to a conclusion that if this was closed, it would be done under the cover of darkness, with no regard for anyone. In fact, as I told you live, I'll be discussing this with the original poster (@RubenVerborgh), who my comment was aimed at, next week. Following that discussion, we'll have a better idea of how to proceed, one of the outcomes possibly being closing this proposal if we judge the efforts to be duplicated. If someone else would like to pick it up instead - fantastic.

@csarven
Copy link
Member

csarven commented Oct 15, 2020

Fantastic. Please discuss in one of the public minuted meetings.

You'll probably recall that all of this surfaced when I tried to understand what you were trying to achieve. Which turned out to be a form of requesting access as originally proposed in solid/data-interoperability-panel#13 (comment) and then this PR.. that I've pointed you to, live. One only wonders why prior work is not acknowledged prior to making a new proposal.

Do you suppose that one of the outcomes possibly being retracting the other proposal if "we" judge the efforts to be duplicated? Probably not.

@elf-pavlik
Copy link
Member

elf-pavlik commented Oct 15, 2020

I believe that everyone is doing one's best and while we may improve our workflow, we should anticipate some glitches now and then.

I have impression that this PR now looses its focus and we drift into discussions about process. I would suggest creating issue in process repo to discuss process and here let's give @RubenVerborgh a chance to respond if he sees https://solid.github.io/data-interoperability-panel/specification/#needs-access-request having potential to supersede this PR or we should keep working on both proposals concurrently

@justinwb
Copy link
Member

You'll probably recall that all of this surfaced when I tried to understand what you were trying to achieve. Which turned out to be a form of requesting access as originally proposed in solid/data-interoperability-panel#13 (comment) and then this PR.. that I've pointed you to, live.

Authorization (requesting access, etc.) is an important part of interoperability - but not the only part. The aim is to solve these Problems, and path to solve them makes the approaches for data validation, organization, and authorization somewhat intertwined.

One only wonders why prior work is not acknowledged prior to making a new proposal.

Because we're all just trying to do the best job we can with the time and resources we've got - to get work done that everyone can use - and do real things with Solid. There's no ill intent involved. It's not constructive to assume otherwise first. If this is an indirect way of pointing out that the interop spec draft needs an acknowledgements section - that's a completely fair point. It hasn't been added yet - not because there's any bad intentions, but because we've been focused on the functional pieces, and the full draft isn't complete. I'm happy to prioritize it, and I will.

@csarven
Copy link
Member

csarven commented Oct 15, 2020

This is about processing proposals. Nothing to do with panels or attributions.

This PR describes a solution using existing specs to a need based on implementation experience.

@RubenVerborgh
Copy link
Contributor Author

RubenVerborgh commented Oct 22, 2020

Catching up!

@justinwb wrote:

I believe that we have covered this exchange in the interoperability panel as part of the Data Authorization workflows.

I had a look at 6.2.2. Another Agent Requests Access.

Initial thoughts:

  • I'm very surprised by the REQAPP steps. I would expect usage of an app to be optional/orthogonal. An agent acting through an app is just delegation, right?
  • I find the interop:receivesAccessReceipt workflow weird. Why is that not in the access request notification? (Given that the inbox could be different per request.)
  • CAUTHZ monitors CONTROLLER's access inbox autonomously It does not seem to be our territory what should happen on the inside. The Solid specs govern the wires and stop at the Ethernet port on both sides.

A difficulty is of course that I can only see the outcome of discussions in the document, not the rationale.
My current feeling is "too complicated" and "overreach" (because it discusses what seem to be implementation internals), but I might lack the requirements that have inspired the procedure.

But fundamentally, I don't think this even belongs in application interop (as far as the access requests are for entire documents). We should have a procedure independent of apps (such as the one I describe in this PR), and then—possibly, if needed—an extension in case app delegation takes place.

So I'm confused at the moment, and I think it will take us a couple of meetings/discussions to have a full understanding.

@timbl
Copy link
Contributor

timbl commented Mar 2, 2021

@timbl
Copy link
Contributor

timbl commented Mar 2, 2021

Suggest allow the user to give either a reason for wanting access, or maybe a pointer to some solid thing like a task oir a message in a chat

@timbl
Copy link
Contributor

timbl commented Mar 2, 2021

If the request is granted, suggest the original user gets a notification that it has.

@prefix as: <https://www.w3.org/ns/activitystreams#>.
@prefix tbd: <http://example.org/to-be-determined#>.

[
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggest use a URI to identify the request like <#this> so it can be linked to in any response

@RubenVerborgh
Copy link
Contributor Author

@timbl Thanks for the feedback, will incorporate!

This implements Roadmap task https://solidos.solidcommunity.net/public/Roadmap/Tasks/state.ttl#Iss1613476102890

Perhaps also good to mention that this PR addresses the needs of the proposal in solid/data-interoperability-panel#13 regarding Resource Access.

@elf-pavlik
Copy link
Member

I will bring up this PR during next interop panel meeting to clarify how Access Needs can be used in this flow.

@bblfish
Copy link
Contributor

bblfish commented Mar 12, 2021

In order to satisfy the Minimal Credentials Disclosure Use Case we will need to have access control rules that are also visible. How this can be done in a way compatible with the current WAC specs is described in Issue 189: ACLs on ACLs for WAC. Publicly readable ACLs does not actually need to give out information about who is member of a group, such as when

  1. the agentClass is given by description as when anyone who can prove they are over 21, as described at the end of the HttpSig authentication proposal
  2. the group is only readable by members of the group as described in the comment on the ACLs on ACLs

In the first use case there is no way to become a member of it without already being a member (ie. being over 21 and being able to prove it). In the second use case one would indeed want a way to be notified that one is a member, or request membership. To be notified the server can fins one's ldn:inbox from one's foaf profile. If the client wants access it will need to find a link from the group to a notification mechanism. But where would that link be placed? It could be placed in the ACL itself. So to take that example, one could add:

<#> authorizes [ 
   acl:agentClass <15263626-8352-11eb-8dcd-0242ac130003#invitees>
   :mode :Read ] .

<15263626-8352-11eb-8dcd-0242ac130003#invitees> ldn:inbox </requests/> .

It could be in the HTTP header of the non accesible group, but how could a client add that link header there? (Good suggestions welcome). Perhaps if the group acl has the statement

<> ldn:inbox </requests/>

Then the server could display an inbox relation in the HTTP header. Or perhaps those should go in a meta related resource.... ?

@csarven
Copy link
Member

csarven commented Mar 25, 2021

dokieli-access-request

Edit: Screencast showing request access implementation in dokieli (source: dokieli/dokieli@edd43f7 ). Updated (local) NSS to include the Link header for the inbox for dokieli to follow.

@elf-pavlik elf-pavlik merged commit 9d9dd0e into main Apr 7, 2021
@elf-pavlik elf-pavlik deleted the feature/ldn-access-request branch April 7, 2021 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants