From fef0d4dca894ca9c8c2de12d69929064258c38a8 Mon Sep 17 00:00:00 2001 From: Bart Date: Fri, 29 Mar 2024 10:48:35 +0100 Subject: [PATCH 1/5] Developer docs for Noodlebar APIs --- Poort8.Dataspace.Wiki/APIdocs.md | 126 ++++ .../Poort8.Noodlebar.postman_collection.json | 710 ++++++++++++++++++ 2 files changed, 836 insertions(+) create mode 100644 Poort8.Dataspace.Wiki/APIdocs.md create mode 100644 Poort8.Dataspace.Wiki/Poort8.Noodlebar.postman_collection.json diff --git a/Poort8.Dataspace.Wiki/APIdocs.md b/Poort8.Dataspace.Wiki/APIdocs.md new file mode 100644 index 0000000..a9a06b6 --- /dev/null +++ b/Poort8.Dataspace.Wiki/APIdocs.md @@ -0,0 +1,126 @@ +# Noodlebar API Documentation + +## Introduction + +The Noodlebar API, part of the Poort8 Dataspace, is designed to provide a structured platform for data providers, applications, and data consumers within the Basic Data Infrastructure (BDI). This API facilitates the creation of dataspaces that follow certain principles, enabling an initial setup for dataspace initiators. + +## Deploying a data service in this Noodlebar dataspace + +For developers using a .NET framework, the Poort8 iSHARE core package provides an easy start: https://github.com/POORT8/Poort8.Ishare.Core. Support for other scenarios follows soon. + +For all deployed data services, authentication and authorization process is explained on this page. + +## Postman Collection + +Access the Noodlebar Postman Collection for practical examples of API requests. Find it here: [Poort8.Noodlebar.postman_collection.json](/Poort8.Noodlebar.postman_collection.json) + +## Authentication + +All API requests require authentication via JWT (JSON Web Tokens). There are two options to obtain a token: +1. A POST request to the `/api/ishare/connect/token` endpoint with the appropriate client_assertion, based on an iSHARE compliant eIDAS certificate. +2. A POST request to the `/login` endpoint with the correct credentials from the user administration of the Noodlebar instance. + +The access_token obtained through either route must be included in the `Authorization` header as `Bearer ` for each subsequent API request. + +### Option 1. `/api/ishare/connect/token` + +```plaintext +POST /api/ishare/connect/token +Content-Type: application/x-www-form-urlencoded + +grantType=client_credentials&scope=api&clientId=&clientAssertionType=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&clientAssertion= +``` + +### Option 2. `/login` + +```plaintext +POST /login +Content-Type: application/json + +{ + "username": "", + "password": "", + "useCookies": true, + "useSessionCookies": true +} +``` + +## Authorization + +Applying Authorizations from the Noodlebar authorization registry can be done in three ways: + +Applying Authorizations from the Noodlebar authorization register can be accomplished in three ways: +1. A GET request to `/enforce`. This is the most straightforward method and can only be executed by the service provider. Depending on whether an authorization exists, this endpoint returns true or false. +2. A GET request to `/explained-enforce`. This method can also only be executed by the service provider, and in case of a true response, it also provides which policy supports this true response. +3. A POST request to `/ishare/delegation`. This method can be used by both the service to whom the authorization is granted or the service user. With a request in the form of an iSHARE delegation mask, a response is sent back which serves as a signed proof of authorization. + +### Option 1. `/api/enforce` + +```plaintext +GET /api/enforce +Check if an action on a resource is allowed based on the policy. +Parameters: +- subject: ID of the subject +- resource: ID of the resource +- action: The action being performed +- useCase: Specific use case +``` + +### Option 2. Explained-enforce + +```plaintext +GET /api/explained-enforce?subject=&resource=&action=&useCase=&issuer=&serviceProvider=&type=&attribute= +Accept: application/json + +This method also can only be executed by the service provider, and in case of a true response, it also provides which policy supports this true response. +``` + +### Option 3. `/api/ishare/delegation` + +```plaintext +POST /api/ishare/delegation +Use this to set up delegations for access to your data. +Request Body: +{ + "delegationRequest": { + "policyIssuer": "string", + "target": { + "accessSubject": "string" + }, + "policySets": [ + { + "policies": [ + { + "target": { + "resource": { + "type": "string", + "identifiers": ["string"], + "attributes": ["string"] + }, + "actions": ["string"], + "environment": { + "serviceProviders": ["string"] + } + }, + "rules": [ + { + "effect": "string" + } + ] + } + ] + } + ] + } +} +``` + +## Error Codes + +- 200 - Success +- 401 - Unauthorized: The request does not contain a valid authentication token. +- 403 - Forbidden: The user or service does not have access to the requested resource. + +## Support + +For further support or questions, please contact our support team at hello@poort8.nl. diff --git a/Poort8.Dataspace.Wiki/Poort8.Noodlebar.postman_collection.json b/Poort8.Dataspace.Wiki/Poort8.Noodlebar.postman_collection.json new file mode 100644 index 0000000..d7dca51 --- /dev/null +++ b/Poort8.Dataspace.Wiki/Poort8.Noodlebar.postman_collection.json @@ -0,0 +1,710 @@ +{ + "info": { + "_postman_id": "1baad6bc-aa24-4e4a-b74e-a858e4e8b23a", + "name": "Poort8.Noodlebar", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "14161223", + "_collection_link": "https://poort8.postman.co/workspace/Poort8~7a6e5661-2a26-478e-8bf8-0a844a032ef7/collection/14161223-1baad6bc-aa24-4e4a-b74e-a858e4e8b23a?action=share&source=collection_link&creator=14161223" + }, + "item": [ + { + "name": "Authentication", + "item": [ + { + "name": "Option 1. Fetch iSHARE/connect/token", + "event": [ + { + "listen": "prerequest", + "script": { + "exec": [ + "const jwsRequest = {\r", + " url: \"https://scheme.isharetest.net/testing/generate-jws\",\r", + " method: \"POST\",\r", + " header: {\r", + " alg: \"RS256\",\r", + " typ: \"JWT\",\r", + " aud: pm.environment.get(\"ARIdentifier\"),\r", + " iss: pm.environment.get(\"ARIdentifier\"),\r", + " x5c: pm.environment.get(\"IsharePublicKey\")\r", + " },\r", + " body: {\r", + " mode: 'application/text',\r", + " raw: pm.environment.get(\"IsharePrivateKey\")\r", + " }\r", + "};\r", + "\r", + "pm.sendRequest(jwsRequest, function (err, res) {\r", + " if (err) {\r", + " console.log(\"error: \" + err);\r", + " } else {\r", + " pm.expect(res).to.have.property('code', 200);\r", + " pm.environment.set('current.client_assertion', res.text());\r", + " }\r", + "});" + ], + "type": "text/javascript", + "packages": {} + } + }, + { + "listen": "test", + "script": { + "exec": [ + "let jsonBody = pm.response.json();\r", + "\r", + "pm.test(\"Verify 200\", function () {\r", + " pm.response.to.have.status(200);\r", + "});\r", + "\r", + "pm.test(\"Verify response\", function () {\r", + " pm.expect(jsonBody.access_token).to.not.null;\r", + " pm.expect(jsonBody.token_type).to.eql(\"Bearer\");\r", + " pm.expect(jsonBody.expires_in).to.eql(3600);\r", + "});\r", + "\r", + "pm.environment.set(\"token\", jsonBody.access_token);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "auth": { + "type": "noauth" + }, + "method": "POST", + "header": [], + "body": { + "mode": "urlencoded", + "urlencoded": [ + { + "key": "grant_type", + "value": "client_credentials", + "type": "text" + }, + { + "key": "scope", + "value": "iSHARE", + "type": "text" + }, + { + "key": "client_id", + "value": "EU.EORI.NL888888881", + "type": "text" + }, + { + "key": "client_assertion_type", + "value": "urn:ietf:params:oauth:client-assertion-type:jwt-bearer", + "type": "text" + }, + { + "key": "client_assertion", + "value": "{{client_assertion}}", + "type": "text" + } + ] + }, + "url": { + "raw": "{{baseUrl}}/api/ishare/connect/token", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "ishare", + "connect", + "token" + ] + } + }, + "response": [] + }, + { + "name": "Option 2. Fetch login token", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "let jsonBody = pm.response.json();", + "", + "pm.test(\"Verify 200\", function () {", + " pm.response.to.have.status(200);", + "});", + "", + "pm.test(\"Verify response\", function () {", + " pm.expect(jsonBody.access_token).to.not.null;", + " pm.expect(jsonBody.token_type).to.eql(\"Bearer\");", + " pm.expect(jsonBody.expires_in).to.eql(3600);", + "});", + "", + "pm.environment.set(\"token\", jsonBody.access_token);" + ], + "type": "text/javascript", + "packages": {} + } + } + ], + "request": { + "auth": { + "type": "noauth" + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"email\": \"user@example.com\",\n \"password\": \"userPassword123\",\n \"twoFactorCode\": \"123456\",\n \"twoFactorRecoveryCode\": null\n}\n", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/login?useCookies=true&useSessionCookies=true", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "login" + ], + "query": [ + { + "key": "useCookies", + "value": "true" + }, + { + "key": "useSessionCookies", + "value": "true" + } + ] + } + }, + "response": [ + { + "name": "Untitled Response", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"value\": \"reference #/components/schemas/MicrosoftAspNetCoreIdentityDataLoginRequest not found in the OpenAPI spec\"\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/login?useCookies=&useSessionCookies=", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "login" + ], + "query": [ + { + "key": "useCookies", + "value": "" + }, + { + "key": "useSessionCookies", + "value": "" + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"value\": \"reference #/components/schemas/MicrosoftAspNetCoreAuthenticationBearerTokenAccessTokenResponse not found in the OpenAPI spec\"\n}" + } + ] + } + ] + }, + { + "name": "Authorization", + "item": [ + { + "name": "Option 1. Enforce", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/enforce?subject=&resource=&action=&useCase=", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "enforce" + ], + "query": [ + { + "key": "subject", + "value": "", + "description": "(Required) " + }, + { + "key": "resource", + "value": "", + "description": "(Required) " + }, + { + "key": "action", + "value": "", + "description": "(Required) " + }, + { + "key": "useCase", + "value": "", + "description": "(Required) " + } + ] + } + }, + "response": [ + { + "name": "Success", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/enforce?subject=&resource=&action=&useCase=", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "enforce" + ], + "query": [ + { + "key": "subject", + "value": "", + "description": "(Required) " + }, + { + "key": "resource", + "value": "", + "description": "(Required) " + }, + { + "key": "action", + "value": "", + "description": "(Required) " + }, + { + "key": "useCase", + "value": "", + "description": "(Required) " + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"allowed\": \"\"\n}" + } + ] + }, + { + "name": "Option 2. Explained-enforce", + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/explained-enforce?subject=&resource=&action=&useCase=&issuer=&serviceProvider=&type=&attribute=", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "explained-enforce" + ], + "query": [ + { + "key": "subject", + "value": "", + "description": "(Required) " + }, + { + "key": "resource", + "value": "", + "description": "(Required) " + }, + { + "key": "action", + "value": "", + "description": "(Required) " + }, + { + "key": "useCase", + "value": "", + "description": "(Required) " + }, + { + "key": "issuer", + "value": "", + "description": "(Required) " + }, + { + "key": "serviceProvider", + "value": "", + "description": "(Required) " + }, + { + "key": "type", + "value": "", + "description": "(Required) " + }, + { + "key": "attribute", + "value": "", + "description": "(Required) " + } + ] + } + }, + "response": [ + { + "name": "Success", + "originalRequest": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json" + } + ], + "url": { + "raw": "{{baseUrl}}/api/explained-enforce?subject=&resource=&action=&useCase=&issuer=&serviceProvider=&type=&attribute=", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "explained-enforce" + ], + "query": [ + { + "key": "subject", + "value": "", + "description": "(Required) " + }, + { + "key": "resource", + "value": "", + "description": "(Required) " + }, + { + "key": "action", + "value": "", + "description": "(Required) " + }, + { + "key": "useCase", + "value": "", + "description": "(Required) " + }, + { + "key": "issuer", + "value": "", + "description": "(Required) " + }, + { + "key": "serviceProvider", + "value": "", + "description": "(Required) " + }, + { + "key": "type", + "value": "", + "description": "(Required) " + }, + { + "key": "attribute", + "value": "", + "description": "(Required) " + } + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"allowed\": \"\",\n \"explainPolicies\": [\n {\n \"policyId\": \"\",\n \"useCase\": \"\",\n \"issuedAt\": \"\",\n \"notBefore\": \"\",\n \"expiration\": \"\",\n \"issuerId\": \"\",\n \"subjectId\": \"\",\n \"serviceProvider\": \"\",\n \"action\": \"\",\n \"resourceId\": \"\",\n \"type\": \"\",\n \"attribute\": \"\",\n \"license\": \"\",\n \"properties\": [\n {\n \"propertyId\": \"\",\n \"key\": \"\",\n \"value\": \"\",\n \"isIdentifier\": \"\"\n },\n {\n \"propertyId\": \"\",\n \"key\": \"\",\n \"value\": \"\",\n \"isIdentifier\": \"\"\n }\n ]\n },\n {\n \"policyId\": \"\",\n \"useCase\": \"\",\n \"issuedAt\": \"\",\n \"notBefore\": \"\",\n \"expiration\": \"\",\n \"issuerId\": \"\",\n \"subjectId\": \"\",\n \"serviceProvider\": \"\",\n \"action\": \"\",\n \"resourceId\": \"\",\n \"type\": \"\",\n \"attribute\": \"\",\n \"license\": \"\",\n \"properties\": [\n {\n \"propertyId\": \"\",\n \"key\": \"\",\n \"value\": \"\",\n \"isIdentifier\": \"\"\n },\n {\n \"propertyId\": \"\",\n \"key\": \"\",\n \"value\": \"\",\n \"isIdentifier\": \"\"\n }\n ]\n }\n ]\n}" + } + ] + }, + { + "name": "Option 3. iSHARE/delegation", + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"delegationRequest\": {\n \"policyIssuer\": \"\",\n \"target\": {\n \"accessSubject\": \"\"\n },\n \"policySets\": [\n {\n \"policies\": [\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n },\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n }\n ]\n },\n {\n \"policies\": [\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n },\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n }\n ]\n }\n ]\n }\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/ishare/delegation", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "ishare", + "delegation" + ] + } + }, + "response": [ + { + "name": "Success", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + }, + { + "key": "Accept", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"delegationRequest\": {\n \"policyIssuer\": \"\",\n \"target\": {\n \"accessSubject\": \"\"\n },\n \"policySets\": [\n {\n \"policies\": [\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n },\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n }\n ]\n },\n {\n \"policies\": [\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n },\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n }\n ]\n }\n ]\n }\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/ishare/delegation", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "ishare", + "delegation" + ] + } + }, + "status": "OK", + "code": 200, + "_postman_previewlanguage": "json", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "cookie": [], + "body": "{\n \"delegation_token\": \"\"\n}" + }, + { + "name": "Unauthorized", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"delegationRequest\": {\n \"policyIssuer\": \"\",\n \"target\": {\n \"accessSubject\": \"\"\n },\n \"policySets\": [\n {\n \"policies\": [\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n },\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n }\n ]\n },\n {\n \"policies\": [\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n },\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n }\n ]\n }\n ]\n }\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/ishare/delegation", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "ishare", + "delegation" + ] + } + }, + "status": "Unauthorized", + "code": 401, + "_postman_previewlanguage": "text", + "header": [], + "cookie": [], + "body": "" + }, + { + "name": "Forbidden", + "originalRequest": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"delegationRequest\": {\n \"policyIssuer\": \"\",\n \"target\": {\n \"accessSubject\": \"\"\n },\n \"policySets\": [\n {\n \"policies\": [\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n },\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n }\n ]\n },\n {\n \"policies\": [\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n },\n {\n \"target\": {\n \"resource\": {\n \"type\": \"\",\n \"identifiers\": [\n \"\",\n \"\"\n ],\n \"attributes\": [\n \"\",\n \"\"\n ]\n },\n \"actions\": [\n \"\",\n \"\"\n ],\n \"environment\": {\n \"serviceProviders\": [\n \"\",\n \"\"\n ]\n }\n },\n \"rules\": [\n {\n \"effect\": \"\"\n },\n {\n \"effect\": \"\"\n }\n ]\n }\n ]\n }\n ]\n }\n}", + "options": { + "raw": { + "headerFamily": "json", + "language": "json" + } + } + }, + "url": { + "raw": "{{baseUrl}}/api/ishare/delegation", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "ishare", + "delegation" + ] + } + }, + "status": "Forbidden", + "code": 403, + "_postman_previewlanguage": "text", + "header": [], + "cookie": [], + "body": "" + } + ] + } + ] + }, + { + "name": "Dataservice", + "item": [] + } + ], + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "packages": {}, + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "packages": {}, + "exec": [ + "" + ] + } + } + ], + "variable": [ + { + "key": "baseUrl", + "value": "https://example.com" + } + ] +} \ No newline at end of file From e767936860e9f98b699828f12f5801d0561013c2 Mon Sep 17 00:00:00 2001 From: Bart Date: Fri, 29 Mar 2024 10:51:05 +0100 Subject: [PATCH 2/5] Update APIdocs.md --- Poort8.Dataspace.Wiki/APIdocs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Poort8.Dataspace.Wiki/APIdocs.md b/Poort8.Dataspace.Wiki/APIdocs.md index a9a06b6..6d51b59 100644 --- a/Poort8.Dataspace.Wiki/APIdocs.md +++ b/Poort8.Dataspace.Wiki/APIdocs.md @@ -12,7 +12,7 @@ For all deployed data services, authentication and authorization process is expl ## Postman Collection -Access the Noodlebar Postman Collection for practical examples of API requests. Find it here: [Poort8.Noodlebar.postman_collection.json](/Poort8.Noodlebar.postman_collection.json) +Access the Noodlebar Postman Collection for practical examples of API requests. Find it here: [Poort8.Noodlebar.postman_collection.json](Poort8.Noodlebar.postman_collection.json) ## Authentication From 27b89979dc5a6b6483118f92ff76da95387ba5fc Mon Sep 17 00:00:00 2001 From: Bart Date: Fri, 29 Mar 2024 10:55:49 +0100 Subject: [PATCH 3/5] Update APIdocs.md --- Poort8.Dataspace.Wiki/APIdocs.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Poort8.Dataspace.Wiki/APIdocs.md b/Poort8.Dataspace.Wiki/APIdocs.md index 6d51b59..d4dc1fb 100644 --- a/Poort8.Dataspace.Wiki/APIdocs.md +++ b/Poort8.Dataspace.Wiki/APIdocs.md @@ -1,5 +1,7 @@ # Noodlebar API Documentation +**Status: 🚧 Draft** + ## Introduction The Noodlebar API, part of the Poort8 Dataspace, is designed to provide a structured platform for data providers, applications, and data consumers within the Basic Data Infrastructure (BDI). This API facilitates the creation of dataspaces that follow certain principles, enabling an initial setup for dataspace initiators. From 695ecb183e3061df5bf1bc169c9bb24288d586b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amy=20Now=C3=A9?= Date: Fri, 29 Mar 2024 11:46:38 +0100 Subject: [PATCH 4/5] Edited APIdocs --- Poort8.Dataspace.Wiki/APIdocs.md | 76 +++++++++++++++++--------------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/Poort8.Dataspace.Wiki/APIdocs.md b/Poort8.Dataspace.Wiki/APIdocs.md index d4dc1fb..7349ae0 100644 --- a/Poort8.Dataspace.Wiki/APIdocs.md +++ b/Poort8.Dataspace.Wiki/APIdocs.md @@ -1,30 +1,30 @@ -# Noodlebar API Documentation +# Noodle Bar API Documentation **Status: 🚧 Draft** ## Introduction -The Noodlebar API, part of the Poort8 Dataspace, is designed to provide a structured platform for data providers, applications, and data consumers within the Basic Data Infrastructure (BDI). This API facilitates the creation of dataspaces that follow certain principles, enabling an initial setup for dataspace initiators. +The Noodle Bar API, part of the Poort8 Dataspace, is designed to provide a structured platform for data providers, applications, and data consumers within the Basic Data Infrastructure (BDI). This API facilitates the creation of dataspaces that follow certain principles, enabling an initial setup for dataspace initiators. -## Deploying a data service in this Noodlebar dataspace +## Deploying a data service in this Noodle Bar dataspace -For developers using a .NET framework, the Poort8 iSHARE core package provides an easy start: https://github.com/POORT8/Poort8.Ishare.Core. Support for other scenarios follows soon. +For developers using the .NET framework, the Poort8 iSHARE core package provides an easy start: https://github.com/POORT8/Poort8.Ishare.Core. Support for other scenarios follows soon. -For all deployed data services, authentication and authorization process is explained on this page. +For all deployed data services, the authentication and authorization process is explained on this page. ## Postman Collection -Access the Noodlebar Postman Collection for practical examples of API requests. Find it here: [Poort8.Noodlebar.postman_collection.json](Poort8.Noodlebar.postman_collection.json) +Access the Noodle Bar Postman Collection for practical examples of API requests. You can find it here: [Poort8.NoodleBar.postman_collection.json](Poort8.NoodleBar.postman_collection.json) ## Authentication All API requests require authentication via JWT (JSON Web Tokens). There are two options to obtain a token: -1. A POST request to the `/api/ishare/connect/token` endpoint with the appropriate client_assertion, based on an iSHARE compliant eIDAS certificate. -2. A POST request to the `/login` endpoint with the correct credentials from the user administration of the Noodlebar instance. +1. A POST request to the `/api/ishare/connect/token` endpoint with the appropriate client assertion, based on an iSHARE compliant eIDAS certificate. +2. A POST request to the `/login` endpoint with the correct credentials from the user administration of the Noodle Bar instance. -The access_token obtained through either route must be included in the `Authorization` header as `Bearer ` for each subsequent API request. +The access token obtained through either route must be included in the `Authorization` header as `Bearer ` for each subsequent API request. -### Option 1. `/api/ishare/connect/token` +### Option 1: `/api/ishare/connect/token` ```plaintext POST /api/ishare/connect/token @@ -33,7 +33,7 @@ Content-Type: application/x-www-form-urlencoded grantType=client_credentials&scope=api&clientId=&clientAssertionType=urn:ietf:params:oauth:client-assertion-type:jwt-bearer&clientAssertion= ``` -### Option 2. `/login` +### Option 2: `/login` ```plaintext POST /login @@ -49,40 +49,47 @@ Content-Type: application/json ## Authorization -Applying Authorizations from the Noodlebar authorization registry can be done in three ways: +Applying Authorizations from the Noodle Bar authorization registry - checking if an action on a resource is allowed based on the policy - can be done in three different ways. -Applying Authorizations from the Noodlebar authorization register can be accomplished in three ways: -1. A GET request to `/enforce`. This is the most straightforward method and can only be executed by the service provider. Depending on whether an authorization exists, this endpoint returns true or false. -2. A GET request to `/explained-enforce`. This method can also only be executed by the service provider, and in case of a true response, it also provides which policy supports this true response. -3. A POST request to `/ishare/delegation`. This method can be used by both the service to whom the authorization is granted or the service user. With a request in the form of an iSHARE delegation mask, a response is sent back which serves as a signed proof of authorization. - -### Option 1. `/api/enforce` - -```plaintext -GET /api/enforce -Check if an action on a resource is allowed based on the policy. -Parameters: -- subject: ID of the subject -- resource: ID of the resource +### Option 1: `/api/enforce` +This is the most straightforward method and can only be executed by the service provider. Depending on whether an authorization exists, this endpoint returns true or false. This request requires the following query parameters: +- subject: The ID of the subject +- resource: The ID of the resource - action: The action being performed - useCase: Specific use case + +```plaintext +GET /api/enforce?subject=&resource=&action=&useCase= +Accept: application/json +Authorization: Bearer ``` -### Option 2. Explained-enforce +### Option 2: `/api/explained-enforce` +This method can also only be executed by the service provider. In case of a true response, it will say which policy supports this response. This request requires the following query parameters: +- subject: The ID of the subject +- resource: The ID of the resource +- action: The action being performed +- useCase: Specific use case +- issuer: The ID of the issuer +- serviceProvider: The ID of the service provider +- type: The type of resource +- attribute: The attribute of the resource ```plaintext -GET /api/explained-enforce?subject=&resource=&action=&useCase=&issuer=&serviceProvider=&type=&attribute= +GET /api/explained-enforce?subject=&resource=&action=&useCase=&issuer=&serviceProvider=&type=&attribute= Accept: application/json - -This method also can only be executed by the service provider, and in case of a true response, it also provides which policy supports this true response. +Authorization: Bearer ``` -### Option 3. `/api/ishare/delegation` +### Option 3: `/api/ishare/delegation` +This method can be used by both the service to whom the authorization is granted, or the service user. With a request formatted as an iSHARE delegation mask, a response is sent back which serves as signed proof of authorization. Use this to set up delegations for access to your data. ```plaintext POST /api/ishare/delegation -Use this to set up delegations for access to your data. -Request Body: +Content-Type: application/json +Accept: application/json +Authorization: Bearer + { "delegationRequest": { "policyIssuer": "string", @@ -117,12 +124,11 @@ Request Body: } ``` -## Error Codes +## Response codes - 200 - Success - 401 - Unauthorized: The request does not contain a valid authentication token. - 403 - Forbidden: The user or service does not have access to the requested resource. ## Support - -For further support or questions, please contact our support team at hello@poort8.nl. +For further support or questions, please contact our support team at hello@poort8.nl. \ No newline at end of file From 5a7e35db6f3caaa8eed5e31be0f6f3e561ef5fa8 Mon Sep 17 00:00:00 2001 From: Amy <131142051+poort8amy@users.noreply.github.com> Date: Fri, 29 Mar 2024 11:47:20 +0100 Subject: [PATCH 5/5] Remaned Noodle Bar Postman collection --- ...llection.json => Poort8.NoodleBar.postman_collection.json} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename Poort8.Dataspace.Wiki/{Poort8.Noodlebar.postman_collection.json => Poort8.NoodleBar.postman_collection.json} (99%) diff --git a/Poort8.Dataspace.Wiki/Poort8.Noodlebar.postman_collection.json b/Poort8.Dataspace.Wiki/Poort8.NoodleBar.postman_collection.json similarity index 99% rename from Poort8.Dataspace.Wiki/Poort8.Noodlebar.postman_collection.json rename to Poort8.Dataspace.Wiki/Poort8.NoodleBar.postman_collection.json index d7dca51..20de5b9 100644 --- a/Poort8.Dataspace.Wiki/Poort8.Noodlebar.postman_collection.json +++ b/Poort8.Dataspace.Wiki/Poort8.NoodleBar.postman_collection.json @@ -1,7 +1,7 @@ { "info": { "_postman_id": "1baad6bc-aa24-4e4a-b74e-a858e4e8b23a", - "name": "Poort8.Noodlebar", + "name": "Poort8.NoodleBar", "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", "_exporter_id": "14161223", "_collection_link": "https://poort8.postman.co/workspace/Poort8~7a6e5661-2a26-478e-8bf8-0a844a032ef7/collection/14161223-1baad6bc-aa24-4e4a-b74e-a858e4e8b23a?action=share&source=collection_link&creator=14161223" @@ -707,4 +707,4 @@ "value": "https://example.com" } ] -} \ No newline at end of file +}