Skip to content

Permissioning API specification

Rachel Arnould edited this page Oct 3, 2025 · 1 revision

# DPM API reference specification

Document goal

This wiki page is the reference of the current data permissioning module API, which allows enterprises to manage platforms access to their general, products or orders data.

It will allow platforms developers to implement the endpoints needed for the client side module to work properly.

During this first implementation, we took to point of view of an enterprise managing platforms and their associated scopes.

List the plaftorms and currently assigned scopes

To load the initial data for a given enterprise, we designed a GET api endpoint accessible on URI https://myapplication.com/enterprises/{enterpriseId}/platforms which MUST return a rdf:List of knowns platforms, each handling a list of assignedScopes like so:

{
  "@context": "https://cdn.startinblox.com/owl/context-bis.jsonld",
  "@id": "https://mydataserver.com/enterprises/{enterpriseId}/platforms",
  "dfc-t:platforms": {  
    "@type": "rdf:List",
    "@list": [
      {
        "@id": "https://waterlooregionfood.ca/profile",
        "@type": "dfc-t:Platform",
        "localId": "xxxxxxxxxxxxxxxxx",
        "dfc-t:hasAssignedScopes": {
          "@type": "rdf:List",
          "@list": [
            {
               "@id": "https://cdn.startinblox.com/owl/dfc/scopes.jsonld#ReadEnterprise",
               "dfc-t:scope": "ReadEnterprise",
               "@type": "dfc-t:Scope"
            }
          ]
        }
      },
      {
        "@id": "https://anotherportal.ca/portal/profile",
        "@type": "dfc-t:Platform",
        "localId": "yyyyyyyyyyyyyyy",
        "dfc-t:hasAssignedScopes": {
           "@type": "rdf:List",
           "@list": []
        }
      }
    ]
  }
}

One important field is the localId which is the ID of the dfc-t:Platform on the data-server. It will be used by our permissioning web-component when the user PUTs new assigned scopes for the platform, sending a PUT request to enterprises/{enterpriseId}/platforms/{platformId} (detailed below).

List all the scopes

The list of scopes is coming from a publicly accessible link to a list of scope hosted on cdn.startinblox.com here.

The next version of this list is conforming to the taxonomy approach based on Skos used by DFC for productTypes or measurement units and has been drafted and hosted on cdn.startinblox.com for now. The two links are:

In future this document may be integrated in the taxonomies folder of the official DFC standard, and then integrated as the reference list of scopes used by the module. Validation is ongoing while the network is in staging.

Notes for platforms implementers

For identifying a scope in a consistent way on your side when checking it for filtering requests or storing the scopes/platforms associations, you should rely on the dfc-t:scope property available as a literal, for instance "WriteEnterprise", "ReadEnterprise", "WriteProducts", "ReadProducts", ... Relying on the complete @ids would be a more standard approach but as the location of the current list will change, relying on this literal for now will be safer.

Assign a scope to a platform

Updating the list of scopes assigned to a given platform for an enterprise is done by sending a PUT request to the https://myapplication.com/enterprises/{enterpriseId}/platforms/{localId} uri and passing a payload which contains the list of hasAssignedScopes with the proper entries added or removed from there:

{
  "@context": "https://cdn.startinblox.com/owl/context-bis.jsonld",
  "@id": "https://api.proxy-dev.cqcm.startinblox.com/profile",
  "@type": "dfc-t:Platform",
  "localId": "682b2e2b031c28f69cda1645",
  "dfc-t:hasAssignedScopes": {
    "@list": [
      {
        "@id": "https://cdn.startinblox.com/owl/dfc/scopes.jsonld#ReadEnterprise",
        "@type": "dfc-t:Scope",
        "dfc-t:scope": "ReadEnterprise"
      },
      {
        "@id": "https://cdn.startinblox.com/owl/dfc/scopes.jsonld#WriteEnterprise",
        "@type": "dfc-t:Scope",
        "dfc-t:scope": "WriteEnterprise"
      },
      {
        "@id": "https://cdn.startinblox.com/owl/dfc/scopes.jsonld#ReadProducts",
        "@type": "dfc-t:Scope",
        "dfc-t:scope": "ReadProducts"
      },
      {
        "@id": "https://cdn.startinblox.com/owl/dfc/scopes.jsonld#WriteProducts",
        "@type": "dfc-t:Scope",
        "dfc-t:scope": "WriteProducts"
      }
    ],
    "@type": "rdf:List"
  }
}

If ok, this call answers a 200 status code with the same payload as sent. The component will then trigger a reload of the /platforms/ endpoint.

Notes for platforms implementers

This PUT call is the one which allows you to manage the platform/scope association for a given enterprise. The associated GET one, returning the exact same content is also required. The @id MUST reference the actual WebID profile URI of the actual platform, like https://api.proxy-dev.cqcm.startinblox.com/profile for instance and your internal ID used for targetting the proper object on your side MUST be serialized as localId

Impact on the DFC API itself

After that, the idea is for endpoints conforming to the DFC API (example available here and here) to secure the endpoints access by introspecting the authorization token provided with the request against the common keycloak instance and filtering the answers to only returns data associated with enterprises which actually gave access to the requesting portal.

Integrating the web component

The solid-permissioning is a web component which can be integrated into a HTML page, relying on the Startin'Blox scripts:

<!DOCTYPE html>
<html lang="fr">
    <head>
        <title>Platform Authorizations</title>
        <script type="module" src="https://cdn.jsdelivr.net/npm/@startinblox/core@latest/dist/index.js"></script>
    </head>
    <body>
        <style>
            solid-permissioning {
                max-width: 1000px;
                margin: 10px auto;
                width: 100%;
            }
        </style>
        <script type="module">
            window.orbit = {
                client: {
                name: "Orbit",
                logo: "https://cdn.startinblox.com/logos/ACME.svg",
                },
                components: [],
                getRoute: (route) => route,
                getDefaultRoute: () => "",
                getComponent: () => undefined,
                getComponentFromRoute: () => undefined,
                Swal: () => {},
                defaultRoute: "",
                federations: {},
                componentSet: new Set(["routing", "menu", "menu-top", "autoLogin", "solid-permissioning"]),
            };
        </script>
        <solid-permissioning
            data-src="{{ enterprise_platforms_url }}"
            scopes-uri="https://cdn.startinblox.com/owl/dfc/taxonomies/scopes.jsonld"
            auth-token="{{ auth_token }}"
            auto-lang=""
            norouter="">
        </solid-permissioning>
        <script src="https://cdn.jsdelivr.net/npm/@startinblox/solid-data-permissioning@latest/dist/index.js" type="module"></script>
    </body>
</html>

Note the injection of two properties into the solid-permissioning element:

  • data-src: an absolute URL pointing to your platforms endpoint, e.g. https://myapplication.com/enterprises/{enterpriseId}/platforms
  • auth-token: a token which can be used to authenticate the user in the PUT operation. The authenticated user SHOULD be verified by the server to have the necessary permissions to override the scopes afforded to a given platform for the given enterprise.

List of existing proxy servers

For development and validation purposes, some proxy servers have already been set and can be referenced by platforms developers in their internal configuration. All of those proxy servers have been referenced in as existing client in the staging keycloak and are assigned the proper scopes so the tokens can be properly resolved. This list includes:

So for a platform willing to test/demonstrate an end-to-end integration with the existing staging map, it should focus on assigning scopes on data for the proxy "https://api.proxy-stg.cqcm.startinblox.com/profile".