|
| 1 | +# Access Request Management |
| 2 | + |
| 3 | +This document describes the *access request administration endpoint*. |
| 4 | +It contains the methods to describe how to create, read, update and delete access requests. |
| 5 | +Example cURL-requests are provided for ease of use. |
| 6 | + |
| 7 | +The general flow of access requests and grants looks like this: |
| 8 | + |
| 9 | + |
| 10 | + |
| 11 | +The document makes use of these parties and identifiers: |
| 12 | + |
| 13 | +- **Resource Owner**: `https://pod.harrypodder.org/profile/card#me` |
| 14 | +- **Authorization Server**: `http://localhost:4000` |
| 15 | +- **Resource Server**: `http://localhost:3000/resources` |
| 16 | +- **Requesting Party**: `https://example.pod.knows.idlab.ugent.be/profile/card#me` |
| 17 | + |
| 18 | +The examples provided below make use of `text/turtle` and `application/sparql-update` messages. |
| 19 | +The access request used in the examples below looks like this: |
| 20 | + |
| 21 | +```turtle |
| 22 | +@prefix sotw: <https://w3id.org/force/sotw#> . |
| 23 | +@prefix odrl: <http://www.w3.org/ns/odrl/2/> . |
| 24 | +@prefix dcterms: <http://purl.org/dc/terms/> . |
| 25 | +@prefix dct: <http://purl.org/dc/terms/> . |
| 26 | +@prefix ex: <http://example.org/> . |
| 27 | +@prefix xsd: <http://www.w3.org/2001/XMLSchema#> . |
| 28 | +
|
| 29 | +ex:request a sotw:EvaluationRequest ; |
| 30 | + sotw:requestedTarget <http://localhost:3000/resources/resource.txt> ; |
| 31 | + sotw:requestedAction odrl:read ; |
| 32 | + sotw:requestingParty <https://example.pod.knows.idlab.ugent.be/profile/card#me> ; |
| 33 | + ex:requestStatus ex:requested . |
| 34 | +``` |
| 35 | + |
| 36 | +## Supported endpoints |
| 37 | + |
| 38 | +The current implementation supports the following requests to the `uma/requests` and `/uma/requests/:id` endpoints |
| 39 | + |
| 40 | +- [**GET**](#reading-access-requests) |
| 41 | +- [**POST**](#creating-access-requests) |
| 42 | +- [**PATCH**](#managing-access-requests) |
| 43 | +- [**DELETE**](#deleting-access-requests) |
| 44 | + |
| 45 | +## Creating access requests |
| 46 | + |
| 47 | +Create an access request/multiple access requests by sending a **POST** request to `uma/requests`. |
| 48 | +Apart from its `Authorization` header, the `Content-Type` header must be set to the RDF serialization format in which the body is written. |
| 49 | +The accepted formats are those accepted by the [N3 Parser](https://github.com/rdfjs/N3.js/?tab=readme-ov-file#parsing), represented by the following content types: |
| 50 | + |
| 51 | +- `text/turtle` |
| 52 | +- `application/trig` |
| 53 | +- `application/n-triples` |
| 54 | +- `application/n-quads` |
| 55 | +- `text/n3` |
| 56 | + |
| 57 | +The body is expected to represent a valid ODRL access request. |
| 58 | +No sanitization is currently applied. |
| 59 | +Upon success, the server responds with **status code 201**. |
| 60 | +Bad requests, possibly due to improper access request definition, will respond with **status code 400** (to be implemented) <!-- TODO: implement --> |
| 61 | +When the access requested has been validated (to be implemented), but the storage fails, the response will have **status code 500**. |
| 62 | + |
| 63 | +### Example POST request |
| 64 | + |
| 65 | +This example creates an access request `ex:request` for the RP `https://example.pod.knows.idlab.ugent.be/profile/card#me`: |
| 66 | + |
| 67 | +```shell-session |
| 68 | +curl --location 'http://localhost:4000/uma/requests' \ |
| 69 | +--header 'Authorization: https://example.pod.knows.idlab.ugent.be/profile/card#me' \ |
| 70 | +--header 'Content-Type: text/turtle' \ |
| 71 | +--data-raw ' |
| 72 | +@prefix sotw: <https://w3id.org/force/sotw#> . |
| 73 | +@prefix odrl: <https://www.w3.org/ns/odrl/2/> . |
| 74 | +@prefix dcterms: <https://purl.org/dc/terms/> . |
| 75 | +@prefix dct: <https://purl.org/dc/terms/> . |
| 76 | +@prefix ex: <https://example.org/> . |
| 77 | +@prefix xsd: <https://www.w3.org/2001/XMLSchema#> . |
| 78 | +
|
| 79 | +ex:request a sotw:EvaluationRequest ; |
| 80 | + dcterms:issued "2025-08-21T11:24:34.999Z"^^xsd:datetime ; |
| 81 | + sotw:requestedTarget <http://localhost:3000/resources/resource.txt> ; |
| 82 | + sotw:requestedAction odrl:read ; |
| 83 | + sotw:requestingParty <https://example.pod.knows.idlab.ugent.be/profile/card#me> ; |
| 84 | + ex:requestStatus ex:requested . |
| 85 | +' |
| 86 | +``` |
| 87 | + |
| 88 | +## Reading access requests |
| 89 | + |
| 90 | +To read policies, a single endpoint is currently implemented. |
| 91 | +This endpoint currently returns the list of access requests where the WebID provided in the `Authorization` header is marked as the requesting party. |
| 92 | +An example request to this endpoint is: |
| 93 | + |
| 94 | +```shell-session |
| 95 | +curl -X GET --location 'http://localhost:4000/uma/requests' \ |
| 96 | +--header 'Authorization: https://example.pod.knows.idlab.ugent.be/profile/card#me' |
| 97 | +``` |
| 98 | + |
| 99 | +## Managing access requests |
| 100 | + |
| 101 | +The RO can accept or deny the access requests, which is done by updating the status triple. |
| 102 | + |
| 103 | +Updating policies can be done through a **PATCH** request. |
| 104 | +The body must hold the content type `application/json`. |
| 105 | +The example below shows how to update the access request's status from `requested` to `accepted`: |
| 106 | + |
| 107 | +```shell-session |
| 108 | +curl -X PATCH --location 'http://localhost:4000/uma/rquests/:id' \ |
| 109 | +--header 'Authorization: https://example.pod.knows.idlab.ugent.be/profile/card#me' \ |
| 110 | +--header 'Content-Type: application/json' \ |
| 111 | +--data-raw '{ "status": "accepted" }' # can be changed to `denied` too. |
| 112 | +``` |
| 113 | + |
| 114 | +Once an access request's status has been changed from `requested` to `accepted`, the backend will automatically create a new policy including the correct rules to allow the RP access to the resource. |
| 115 | +After this, the RP will be able to use the resource following the UMA protocol. |
| 116 | + |
| 117 | +## Deleting access requests |
| 118 | + |
| 119 | +By making a simple **DELETE** request on the `/uma/requests/:id` endpoint, an access request can be deleted. |
| 120 | +The id should be sufficiently encoded in the URL. |
| 121 | + |
| 122 | +```shell-session |
| 123 | +curl -X DELETE --location 'http://localhost:4000/uma/requests/:id' \ |
| 124 | +--header 'Authorization: https://example.pod.knows.idlab.ugent.be/profile/card#me' \ |
| 125 | +``` |
| 126 | + |
| 127 | +## Important Notes |
| 128 | + |
| 129 | +### Undefined behavior for **PATCH/DELETE** request |
| 130 | + |
| 131 | +Upon the first **PATCH** request which changes an access request's status from `requested` to `accepted` a new policy and permission are created. |
| 132 | +When a new **PATCH** request would change the status to denied, nothing is currently done with the policy. |
| 133 | +Even when the access request would be deleted, the backend currently doesn't do anything to the policy. |
| 134 | +This is undefined behavior and should be treated as such. |
| 135 | +This works in both directions: if the policy is changed in some way, nothing is changed to the access request either. |
| 136 | + |
| 137 | +## Future work |
| 138 | + |
| 139 | +### Discrepancies between [earlier descriptions](https://github.com/bramcomyn/loama/blob/feat/odrl/documentation/access_grants_vs_dsnp.md) and this implementation |
| 140 | + |
| 141 | +This file counts as authorative resource for the access request management. |
| 142 | +Other documentation should point to this file as the latest and correct documentation. |
0 commit comments