Skip to content

Conversation

@mirdono
Copy link

@mirdono mirdono commented Jan 24, 2026

Add initial functionality to support specifying authorisation policies using ODRL (with some SHACL), as an option next to the existing lisp ACL.

Approach

Specifying authorisation policies using ODRL and SHACL

The following table contains an overview of how the different elements in sparql-parser's ACL are expressed using ODRL and SHACL. A more detailed description can be found on gitbook.

ACL ODRL/SHACL
access ODRL Party collection
graph ODRL Asset collection
type-specification ODRL Asset and SHACL node shape with property shapes
grant ODRL Permission

An ODRL Party collection can be linked to a query (and parameters) in which case it would correspond to an access-by-query, otherwise it corresponds to always-accessible. It is currently not supported to influence this mapping using constraints.

In this context an ODRL Asset collection describes a set of triples in a graph. Therefore, we opted to use SHACL shapes instead of ODRL constraints to capture type-specifications, as the former is specifically intended to express that kind of information. ODRL constraints on the other hand are not suitable here.
A SHACL node shape (ODRL Asset) specifies a resource type as sh:targetClass and can contain property shapes to further refine for specific predicates. For example, a type-specification such as

(typeOne -> predOne
         <- predTwo)

could correspond to the following node shape:

someShape a odrl:Asset , sh:NodeShape ;
  odrl:partOf someCollection ;
  sh:targetClass typeOne ;
  sh:property [
    sh:path predOne
  ] , [
    sh:path [ sh:inversePath predTwo ]
  ] .

ODRL model implementation

The ODRL/SHACL model explained above is implemented as a set of classes in odrl.lisp and shacl.lisp. This allows to internally instantiate ODRL policies read from a configuration file as well as convert ODRL model instances to the ACL sparql-parser uses. Having this intermediate representation should allow that the functionality to convert it to the internal ACL can evolve independently from the functionality parsing the input configuration file. For example, supporting another file format only requires to implement functionality to instantiate an ODRL model from its contents.

The model implementations only cover the parts of the ODRL and SHACL specifications that are necessary to express authorisation policies. For example, no support for ODRL offers or constraints is implemented. Furthermore,
the implemented ODRL model deviates from the specification in two ways. First, in our implementation rules can have multiple actions. This allows to "merge" rules that should be converted to a single grant simplifying the actual conversion. Second, asset collections reference their contained assets, whereas in the ODRL specification it is assets that link to the collections they are part of via the odrl:partOf predicate. This inversion allows to pass over all elements in a policy in a top-down fashion, instead of having to keep track of all available assets separately.

Conversion to ACL

Converting an ODRL model instance to the internal ACL is implemented using generic functions, odrl-to-acl and shacl-to-acl, and their method implementations. In summary this conversion starts from an ODRL rule-set and passes over each contained element to convert them to their corresponding ACL element.

Note, as the conversion starts from the rules in a policy, only party (asset) collections that are used in at least 1 rule are converted. This is different from configurations in lisp, where each specified access and graph is evaluated irrelevant of whether there is a grant using it.

Input file parsing

As input an n-triples file is expected, this file is read and parsed by the functionality in parse-ntriples. The load-policy-file function reads input file and parses the content using cl-ntriples. The result is a list of lists, with each inner list representing a triple. The make-rule-set function converts the triples to their corresponding ODRL or SHACL objects.

Open issues

  • Currently only n-triples are supported as input format. Thereby any policy written in ttl must be converted to n-triples to be usable. This is intended as a temporary workaround until a ttl parser can be written, which will allow to directly use ttl files as input.
  • The README should be further extended to document to used ODRL model.

ODRL policies do not yet support all features available through the lisp ACL:

  • Specifying scopes for grants is not supported. Instead (list 'acl:_) is always used as value for :scopes argument for the acl:grant* function, similar to what the acl:grant macro does when no scope is specified.
  • It is not possible to explicitly specify a constraint for a party collection, as can be done for allowed-groups in the acl:supply-allowed-group macro. Consequently, the type of acl:access that will be created for each party collection is determined by the presence or absence of a query. It is thus not possible to specify a NEVER constraint, or force the creation of an acl:always-accessible instance despite the presence of a query.
  • Asset Collections do not support setting options on a per instance basis. Each Asset Collection will be translated to an acl::graph-specification with generate-delta-p and generate-sparql-p set to t.

Notes

  • The ODRL model is documented on the gitbook for the DECIDe project.
  • The implementation is adapted from the odrl-parser-service which served as PoC to show the feasibility of expressing semantic.works authorisation in ODRL.

Related tickets

  • LBRON-719

mirdono and others added 6 commits January 24, 2026 13:35
Define simplified models for ODRL and SHACL using classes. These models only
cover the parts of the respective specifications that we need to express
authorisation policies in ODRL(+SHACL).

These models facilitate an internal representation of an ODRL policy that can
serve as an intermediary between the raw input (e.g. ODRL policy in ttl file)
and the ACL used internally by this service.
- Parse the contents of a n-triples files using `cl-ntriples`
- Convert each relevant resource to its corresponding ODRL/SHACL object. The
  `make-rule-set` function is used as the entrypoint for this conversion.
- Triples in the input that are not relevant for model instances are simply
  ignored.
- Add `./odrl/config.{nt,ttl}` as example for testing purposes.
An ODRL Set is loaded as ACL by iterating over its contained rules:
1. Each Party (Asset) Collection referenced in a rule is converted into a
   corresponding allowed-group (graph-specification). Consequently, collections
   that are not used in any rule are ignored.
2. The set of rules in the policy are "reduced" by merging rules that have the
   same assignee and target. Any merged rule has as actions the union of its
   original rules. Note, this step is necessary because ODRL only allows 1
   action per rule, whereas grants can specify multiple actions.
3. Convert the reduced rules into grants.
- Split the actual assertions to a separate function so they can be reused in
  multiple scenarios.
- Added specific functions to run the assertion tests with either ACL or ODRL
  config to allow testing these flows independently.
- Let `run-assertion-tests` execute the scenario twice, first with an ACL config
  and second with the same config in ODRL.
- Removed previous example configs in favour of config used in test scenarios
- Ensure any n-triples configuration is copied from the mounted config volume.
- Conditionally load policy from n-triples file if
  `odrl-config::*use-odrl-config-p*` is set to a non-nil value.
- The original lisp config confi is still evaluated as before to allow using to
  configure the service by setting parameters/variables. But loading an ODRL
  config first clears the ACL variables to remove any policy elements that would
  be defined in the lisp config.
@mirdono mirdono changed the title feature: support configurating authorisation policies in ODRL feature: support configuring authorisation policies in ODRL Jan 24, 2026
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

Successfully merging this pull request may close these issues.

1 participant