This document describes SAVE (Semantic dAta priVacy modEl) - a conceptual model for fine-grained representation of privacy policies, encoded as an ODRL profile. The model reuses and adapts existing Semantic Web resources, namely ORCP - ODRL Regulatory Compliance Profile, and DPV - Data Privacy Vocabulary. In this document we describe the resulting ODRL profile and demonstrate how existing privacy policies and other contractual documents, such as data processing agreements can be translated into ODRL-like deontic rules.

This work is developed within the RUNE track of the ASGARD research project, supported by the Wallonian Region, Belgium.

The suggested prefix for the SAVE namespace is save

The SAVE ontology is available here.

Since SAVE initially is a merge of existing models, significant parts of this specifications are referring to the [[ODRL]] Information Model standard, ODRL Regulatory Comliance Profile and Data Privacy Vocabulary.

Introduction

This document provides an overview of the SAVE model/ODRL profile, which is synthesized from two ontological resources - ODRL Regulatory compliance Profile (ORCP) and Data Privacy Vocabulary (DPV). With the help of ontology reuse and merging techniques, SAVE profile extends ORCP with new vocabulary taxonomies from DPV, for detailed representation of privacy documents, written in natural language.

Aims and Justification of the Model

The primary aim of the model is to represent privacy policies, data processing agreements and other related contracts to the maximum level of detail, which can allow the generation of actionable rules for access control management and compliance checking. For that it is necessary to be able to express every possible rule, as well as every data type, action, purpose, legal basis, etc., mentioned in the written policies. ORCP has already made a step towards representing GDPR regulations, and with SAVE we are offering the lower level of policies, that i) can be checked for compliance over GDPR policies defined by ORCP; and ii) can themselves be the regulating rules, against which the business requests can be checked.

The examples presented in this specification are created in Protege and serialized with [[turtle]].

The following prefixes are used for the examplples:

@prefix dpv: <http://www.w3.org/ns/dpv/> .

@prefix dpv-gdpr: <http://w3.org/ns/dpv-gdpr#> .

@prefix orcp: <http://example.com/odrl:profile:regulatoryCompliance/> .

@prefix odrl: <http://www.w3.org/ns/odrl/2/> .

@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .

@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

@prefix owl: <http://www.w3.org/2002/07/owl#> .

@prefix xml: <http://www.w3.org/XML/1998/namespace> .

@prefix time: <http://www.w3.org/2006/time#> .

Terminology

The ODRL/ORCP terms used in this document, including Permission, Prohibition, Obligation, Dispensation, and others, are equivalent to the terminology of ORCP, with some additions listed below.

ODRL Regulatory Compliance Profile Vocabulary
A set of terms used to specify regulatory policies.
Data Privacy Vocabulary
A set of top-level concepts used to specify concepts described in DPV.
Personal Data
Any information relating to an identified or identifiable natural person (‘data subject’); an identifiable natural person is one who can be identified, directly or indirectly, in particular by reference to an identifier such as a name, an identification number, location data, an online identifier or to one or more factors specific to the physical, physiological, genetic, mental, economic, cultural or social identity of that natural person; Defined by GDPR
Controller
The natural or legal person, public authority, agency or other body which, alone or jointly with others, determines the purposes and means of the processing of Personal Data; where the purposes and means of such processing are determined by Union or Member State law, the controller or the specific criteria for its nomination may be provided for by Union or Member State law; Defined by GDPR
Processor
A natural or legal person, public authority, agency or other body which processes Personal Data on behalf of the Controller; Defined by GDPR
Technical and Organisational Measures
Measures to be implemented by a Data Controller or a Data Processor in regards to Personal Data. Defined in DPV.

Semantic davata pricy model

The SAVE profile is based on the ODRL Regulatory Compliance Profile, which means that it inherits ODRL's and ORCP's core elements: deontic rules. Permissions, prohibitions, obligations ana dispensations express rules for actions performed by various parties over Personal Data, as well as purposes of processing, legal bases. Another component of SAVE - Data Privacy Vocabulary extends the top-level concepts of ORCP with diverse taxonomies of agreed upon terms, as well as adds technical and organisational measures to the ODRL/ORCP rules.

The conceptual model has been synthesized from existing ontologies, therefore to merge the selected ontological resources - ORCP and DPV, the set of concept alignments ahs been established: we found "anchor points" in ORCP that can be extended with DPV sub-taxonomies. The alignments are presented below.

Ontology alignments between ORCP and DPV

Table 1 : Ontology alignments established by SAVE
DPV/DPV-GDPR Concept Relation ORCP/ORDL Concept
PersonalDataCategory owl:equivalentClass PersonalData
Processing owl:equivalentClass Action
Purpose owl:equivalentClass Purpose
LegalBasis owl:equivalentClass LegalBasis
A6-1-a-explicit-consent
A6-1-a-non-explicit-consent
A9-2-a
rdfs:subClassOf Consent
A6-1-b owl:equivalentClass Contract
A6-1-c owl:equivalentClass LegalObligation
A6-1-d
A9-2-c
rdfs:subClassOf VitalInterest
A6-1-e
A9-2-g
A9-2-i
A9-2-j
rdfs:subClassOf PublicInterest
DataController owl:equivalentClass Controller
DataProcessor owl:equivalentClass Processor
DataSubject
ThirdParty
rdfs:subClassOf Party
hasTechnicalOrganisationalMeasure rdfs:domain Policy or Rule
hasDataSubject rdfs:subPropertyOf function

Resulting Model

The ORCP and DPV have been merged into one model using the alignments identified above. The figure below shows the resulting SAVE model, which is illustrated with Graffoo widgets and color-coded according to ODRL/ORCP information models. Prefix denotes the source ontology. Same-source subclasses are grouped. Underlined classes are the top levels of DPV taxonomies.

SAVE model
SAVE model (Also available in SVG format)

Rule Structure

The simplified view of the rule structure in SAVE is depicted below:

SAVE rule structure
SAVE model's rule structure

Examples

The selected examples provided here are taken from manually processed use-case policies of IMDB, GitHub, Readdle, or the template for a Data Processing Agreement. The fully processed IMDB policy can be found here.

Each code example is preceeded by the text taken from the corresponding source document and processed to extract the model concepts. The text is color-coded according to the information model above. The absence of namespace in the code indicates that the concept from ORCP/DPV had to be redefined during the merging phase to create SAVE. All of the examples presented here, and more, can also be found in the ontology file.

IMDB Permission

From IMDB policy:

Information You Give Us: We receive and store any information you enter on our Web site or give us in any other way. Click here to see examples of what we collect.

You provide most such information when you register, search, post, participate in a contest or questionnaire, or communicate with us. For example, you provide information when you search for a movie, actor or director; provide information in our registration form; communicate with us by phone ,e-mail, or otherwise; complete a questionnaire or a contest entry form; vote in a poll; provide movie reviews or information related to movies; participate in a discussion board; and employ our notification services. As a result of those actions, you might supply us with such information as your name, e-mail address, physical address, zip code, and phone number; your age and gender; the movies and actors you like or dislike; and your general movie preferences.

You can choose not to provide certain information, but then you might not be able to take advantage of many of our features. We use the information that you provide for such purposes as responding to your requests, customizing future browsing for you, improving our site, and communicating with you.

            ###  http://example.com/privacy-policy-model/IMDBPermission1
            :IMDBPermission1 rdf:type owl:NamedIndividual ,
                                      orcp:Permission ;
                             :action :Collect ,
                                     :Store ,
                                     :Use ;
                             :controller :IMDB ;
                             :data :Address ,
                                   :Age ,
                                   :EmailAddress ,
                                   :Gender ,
                                   :MovieDislikes ,
                                   :MovieLikes ,
                                   :MoviePreferences ,
                                   :Name ,
                                   :PhoneNumber ,
                                   :ZipCode ;
                             :hasDataSubject :IMDBUser ;
                             :purpose :Communication ,
                                      :Personalization ,
                                      :UICustomization ;
                             orcp:uid "IMDB-permission-1" .
            

IMDB Prohibition

From IMDB policy:

IMDb is not intended for use by children under the age of 13. If you are under 13, you may not submit information about yourself to IMDb.

            ###  http://example.com/privacy-policy-model/IMDBProhibition6
            :IMDBProhibition6 rdf:type owl:NamedIndividual ,
                                       orcp:Prohibition ;
                              :action :AnyProcessing ;
                              :controller :IMDB ;
                              :data :PersonalInformation ;
                              :sender :ChildUser .
            

IMDB Prohibition With a Despensation

From IMDB policy:

Agents: We employ other companies and individuals to perform functions on our behalf. Examples include sending e-mail, removing repetitive information from user lists, analyzing data, and providing marketing assistance . They have access to personal information needed to perform their functions, but may not use it for other purposes.

            ###  http://example.com/privacy-policy-model/IMDBConstraint1
            :IMDBConstraint1 rdf:type owl:NamedIndividual ,
                                      orcp:PredicateConstraint ;
                             orcp:leftOperand :purpose ;
                             orcp:operator orcp:isAnyOf ;
                             orcp:rightOperand :Communication ,
                                               :DataAnalysis ,
                                               :Marketing .

            ###  http://example.com/privacy-policy-model/IMDBDispensation1
            :IMDBDispensation1 rdf:type owl:NamedIndividual ,
                                        orcp:Dispensation ;
                               orcp:constraint :IMDBConstraint1 .

            ###  http://example.com/privacy-policy-model/IMDBProhibition3
            :IMDBProhibition3 rdf:type owl:NamedIndividual ,
                                       orcp:Prohibition ;
                              :action :Use ;
                              :data :PersonalInformation ;
                              :dispensation :IMDBDispensation1 ;
                              :processor :Agent .
            

IMDB Obligation

The example also includes TechnicalOrganisationalMeasure from DPV being used to describe the obligation of encrypting the data.

From IMDB policy:

If you use our subscription service, we work to protect the security of your subscription information during transmission by using Secure Sockets Layer (SSL) software, which encrypts information you input.

            ###  http://example.com/privacy-policy-model/IMDBObligation1
            :IMDBObligation1 rdf:type owl:NamedIndividual ,
                                      orcp:Obligation ;
                             :action :TransmitViaNetwork ;
                             :controller :IMDB ;
                             :data :SubscriptionInformation ;
                             :hasTechnicalOrganisationalMeasure :SSLEncryption .

            

GitHub Permission with a Prohibition

From GitHub policy:

User Personal Information does not include aggregated, non-personally identifying information that does not identify a User or cannot otherwise be reasonably linked or connected with them. We may use such aggregated, non-personally identifying information for research purposes and to operate, analyze, improve, and optimize our Website and Service.

            ###  http://example.com/privacy-policy-model/GitHubConstraint1
            :GitHubConstraint1 rdf:type owl:NamedIndividual ,
                                        orcp:PredicateConstraint ;
                               orcp:leftOperand :data ;
                               orcp:operator orcp:isA ;
                               orcp:rightOperand :PersonallyIdentifiableInformation .

            ###  http://example.com/privacy-policy-model/GitHubProhibition1
            :GitHubProhibition1 rdf:type owl:NamedIndividual ,
                                         orcp:Prohibition ;
                                orcp:constraint :GitHubConstraint1 .
                                
            ###  http://example.com/privacy-policy-model/GitHubPermission3
            :GitHubPermission3 rdf:type owl:NamedIndividual ;
                               :action :Use ;
                               :controller :GitHub ;
                               :data :PersonalInformation ;
                               :prohibition :GitHubProhibition1 ;
                               :purpose :Research ,
                                        :ServiceFeatures ,
                                        :ServiceOptimization .
            

GitHub Prohibition with Dispensation

From GitHub policy:

If you sign on to a paid Account with us, send funds through the GitHub Sponsors Program, or buy an application on GitHub Marketplace, we collect your full name, address, and credit card information or PayPal information. Please note, GitHub does not process or store your credit card information or PayPal information, but our third-party payment processor does.

            ###  http://example.com/privacy-policy-model/GitHubConstraint2
            :GitHubConstraint2 rdf:type owl:NamedIndividual ,
                                        orcp:PredicateConstraint ;
                               orcp:leftOperand :processor ;
                               orcp:operator orcp:isA ;
                               orcp:rightOperand :ThirdPartyPaymentProcessor .

            ###  http://example.com/privacy-policy-model/GitHubDispensation1
            :GitHubDispensation1 rdf:type owl:NamedIndividual ,
                                          orcp:Dispensation ;
                                 orcp:constraint :GitHubConstraint2 .

            ###  http://example.com/privacy-policy-model/GitHubProhibition2
            :GitHubProhibition2 rdf:type owl:NamedIndividual ,
                                         orcp:Prohibition ;
                                :action :Store ,
                                        :Use ;
                                :controller :GitHub ;
                                :data :CreditCardInformation ,
                                      :PayPalInformation ;
                                :dispensation :GitHubDispensation1 .
            

Readdle Permission with Legal Basis

From Readdle Policy:

We partly use service providers who process Personal Data on behalf of us to operate the technical platform for the Services (for example, the documents that you scan and send via the App are processed by a third party fax service provider (whereas the respective servers are exclusively situated in EU member states)). These service providers process the data exclusively according to our instructions (order processing). The legal basis for the data processing described in this section 4 is Art. 6 (1) sentence 1 lit. b GDPR (performance of contract and pre-contractual measures) and Art. 28 GDPR (order processing).

            ###  http://example.com/privacy-policy-model/ReaddlePermission1
            :ReaddlePermission1 rdf:type owl:NamedIndividual ,
                                         orcp:Permission ;
                                :action :Use ;
                                :controller :Readdle ;
                                :data :ReaddlePersonalData ;
                                :legalBasis :A61b ;
                                :processor :ReaddleServiceProvider ;
                                :purpose :ReaddleServices .
            

DPA Template Permission with Obligation

From publicly available DPA template:

Taking into account the state of the art, the costs of implementation and the nature, scope, context and purposes of Processing as well as the risk of varying likelihood and severity for the rights and freedoms of natural persons, Processor shall in relation to the Company Personal Data implement appropriate technical and organizational measures to ensure a level of security appropriate to that risk, including, as appropriate, the measures referred to in Article 32(1) of the GDPR.

            ###  http://example.com/privacy-policy-model/DPATemplateObligation1
            :DPATemplateObligation1 rdf:type owl:NamedIndividual ,
                                             orcp:Obligation ;
                                    :hasTechnicalOrganisationalMeasure :DPATemplateTechnicalAndOrgMeasures ;
                                    :responsibleParty :DPATemplateProcessor .

            ###  http://example.com/privacy-policy-model/DPATemplatePermission1
            :DPATemplatePermission1 rdf:type owl:NamedIndividual ,
                                             orcp:Permission ;
                                    :action :DPATemplateProcessing ;
                                    :controller :DPATemplateController ;
                                    :data :DPATemplateCompanyPersonalData ;
                                    :obligation :DPATemplateObligation1 ;
                                    :processor :DPATemplateProcessor ;
                                    :responsibleParty :DPATemplateProcessor .

            

DPA Template Prohibition

From publicly available DPA template:

Processor shall not appoint (or disclose any Company Personal Data to) any Subprocessor unless required or authorized by the Company.

            ###  http://example.com/privacy-policy-model/DPATemplateConstraint1
            :DPATemplateConstraint1 rdf:type owl:NamedIndividual ,
                                             orcp:PredicateConstraint ;
                                    orcp:leftOperand :legalBasis ;
                                    orcp:operator orcp:isAnyOf ;
                                    orcp:rightOperand :DPATemplateAuthorizedByController ,
                                                      :DPATemplateRequiredByController .

            ###  http://example.com/privacy-policy-model/DPATemplateDispensation1
            :DPATemplateDispensation1 rdf:type owl:NamedIndividual ,
                                               orcp:Dispensation ;
                                      orcp:constraint :DPATemplateConstraint1 .

            ###  http://example.com/privacy-policy-model/DPATemplateProhibition1
            :DPATemplateProhibition1 rdf:type owl:NamedIndividual ,
                                              orcp:Prohibition ;
                                     :action :DPATemplateDisclose ;
                                     :data :DPATemplateCompanyPersonalData ;
                                     :dispensation :DPATemplateDispensation1 ;
                                     :processor :DPATemplateSubprocessor ;
                                     :recipient :DPATemplateSubprocessor ;
                                     :responsibleParty :DPATemplateProcessor .


            

Compliance Checking with SHACL

RUNE's compliance checking model is based on SHACL rules. We combine the validation of the entities (SAVE rules, policies and requests) with the compliance checking itself. In this Section, we consolidate our compliance checking methodology into a model consisting of two principal modules. The first module - Preprocessing, which takes as input a SAVE policy, - includes automatic conflict detection, resolution (by a legal expert), denormalization of conflicted rules, and, finally, automatic generation of compliance rules in SHACL. This module is executed once (or upon policy update) and the resulting SHACL rules are added to the SAVE policy. The combination of a policy and its compliance rules gives us an "operational" model, where compliance is encoded in a structured, unambiguous and, therefore, interoperable way. The second module -- Compliance Checking -- works with the SHACL rules and contains two parts: request preprocessing and compliance checking itself. We include a request preprocessing step in our model, since we want to allow our system to process various kinds of compliance requests, be it a request sent by a user, or generated from an application, describing desired processing activity. These requests may include various metadata, as well as mention physical data sources (tables, columns) instead of SAVE concepts. Thus, from the initial request and metadata, we need to generate a valid request expressed in SAVE terms. We leave out of the scope at this phase the mapping of data sources to ontological concepts and assume that such mapping is already available (Business Catalog), for example from ODIN system. Additionally, as our compliance checking model is focused on personal data access and usage, we plan an integration with an external access control system to handle user/role privileges.

SHACL Compliance model
SHACL compliance model.

Translation from SAVE to SHACL

Continuing the use-case of IMDB DPA presented above, we demonstrate the compliance checking functionality implemented with SHACL on the SAVE IMDB policy. Figure 3 showcases the translation of SAVE rule (Permission 1) into SHACL rule. Here the compliance checking is combined with validation of properties (e.g., sh:minCount). It is evident from the illustration that the translation from a SAVE rule into SHACL compliance rule is fairly straightforward and can be generated automatically: each concept mentioned in the attribute becomes either sh:class condition (for actions, data, purposes and legal bases) or sh:hasValue (for controllers, processors, data subjects and parties), and each attribute is translated into sh:property condition in SHACL rule. If the request satisfies the conditions expressed in the rule, two additional triples are inferred, with properties conformsTo/prohibitedBy and answer. Every rule from the policy is encoded in a similar way and included into one shapes graph - RequestImdb - describing the compliance rules applied to any request for processing personal data of IMDB users. The shapes graph assumes an input of the initial request (parent) and its normalized version (subrequests). Subrequests are checked against the policy rules first, and finally, the answer for the parent request is inferred from the subrequests' results.

SHACL Compliance model
SAVE/SHACL rule translation.

Examples

To demonstrate the possible requests that can be sent to the SHACL inference engine, we provide an example policy, expressed in SHACL and created from 3 IMDB rules - Permission 1 and Prohibition 3 + Dispensation 1 (conflict-free) - and 3 example requests. (More details about conflict resolution can be found in the paper and in the following examples). All examples are available in the shapes file and can be run in TopBraid.

IMDB policy (Permission 1, Prohibition 3, Dispensation 1)

The policy, represented with SHACL shape, contains 3 first-order sh:rule - one per SAVE rule, and a final order sh:rule - to gather the results of each rule and decide the final answer. The answer can be "granted" (when all subrequests are permitted), "prohibited" (no subrequest is permitted and at least one is prohibited), "part-granted" (when at least one subrequest is permitted), and "not granted" (nothing is permitted, nothing is prohibited). These answers and logic behind them, obviously, can be changed depending on the application requirements: more options can be added, such as "part-prohibited" or "part-granted-part-prohibited". Other properties - conformsTo and prohibitedBy - help give more detailed answer, as they indicate exactly which rules were matched during the inference.

  ex:RequestImdb
  rdf:type rdfs:Class ;
  rdf:type sh:NodeShape ;
  rdfs:label "RequestImdb" ;
  rdfs:subClassOf ex:RequestBase ;
  skos:prefLabel "RequestImdb" ;
  sh:rule [
      rdf:type sh:SPARQLRule ;
      rdfs:label "Infer if $this is compliant with IMDB Permission 1" ;
      sh:condition ex:RequestTest ;
      sh:condition [
          sh:property [
              sh:path ex:action ;
              sh:minCount 1 ;
              sh:or (
                  [
                    sh:class dpv:Collect ;
                  ]
                  [
                    sh:class dpv:Use ;
                  ]
                  [
                    sh:class dpv:Store ;
                  ]
                ) ;
            ] ;
        ] ;
      sh:condition [
          sh:property [
              sh:path ex:controller ;
              sh:hasValue :IMDB ;
            ] ;
        ] ;
      sh:condition [
          sh:property [
              sh:path ex:data ;
              sh:minCount 1 ;
              sh:or (
                  [
                    sh:class dpv:PhysicalAddress ;
                  ]
                  [
                    sh:class dpv:Age ;
                  ]
                  [
                    sh:class dpv:EmailAddress ;
                  ]
                  [
                    sh:class dpv:Gender ;
                  ]
                  [
                    sh:class dpv:Dislike ;
                  ]
                  [
                    sh:class dpv:Like ;
                  ]
                  [
                    sh:class dpv:Preference ;
                  ]
                  [
                    sh:class dpv:TelephoneNumber ;
                  ]
                  [
                    sh:class dpv:Country ;
                  ]
                ) ;
            ] ;
        ] ;
      sh:condition [
          sh:property [
              sh:path ex:dataSubject ;
              sh:hasValue :IMDBUser ;
            ] ;
        ] ;
      sh:condition [
          sh:property [
              sh:path ex:purpose ;
              sh:minCount 1 ;
              sh:or (
                  [
                    sh:class dpv:CustomerCare ;
                  ]
                  [
                    sh:class dpv:ServicePersonalization ;
                  ]
                  [
                    sh:class dpv:UserInterfacePersonalisation ;
                  ]
                ) ;
            ] ;
        ] ;
      sh:construct """
			PREFIX :
			PREFIX ex:
			PREFIX rdf:
			CONSTRUCT {
				$this ex:conformsTo :IMDBPermission1 .
				$this ex:answer \"permitted\" .
			}
			WHERE {}
			""" ;
      sh:order 1 ;
      sh:prefixes ex: ;
    ] ;
  sh:rule [
      rdf:type sh:SPARQLRule ;
      rdfs:label "Infer if $this is compliant" ;
      sh:condition ex:RequestTest ;
      sh:condition [
          sh:property [
              sh:path ex:parentRequest ;
              sh:maxCount 0 ;
            ] ;
        ] ;
      sh:construct """
			PREFIX ex:
			CONSTRUCT {
				$this ex:children ?total .
				$this ex:nPermitted ?granted .
                $this ex:answer ?perm .
			}
			WHERE {
				{SELECT $this (COUNT(*) AS ?total)
				WHERE {
					?s ex:parentRequest $this .
				}
				group by $this
				}
				{SELECT $this (SUM(IF(?p,1,0)) AS ?granted)
				WHERE {
					?s ex:parentRequest $this .
					bind(exists { ?s ex:answer \"permitted\" } as ?p)
				}
				group by $this
				}
  				{
				SELECT $this (SUM(IF(?proh,1,0)) AS ?prohibited)
				WHERE {
					?s ex:parentRequest $this .
					bind(exists { ?s ex:answer \"prohibited\" } as ?proh)
				}
				group by $this
				}
				BIND ( IF ( ?total = ?granted, \"granted\", IF( ?granted = 0 && ?prohibited > 0, \"prohibited\" , IF ( ?total > ?granted && ?granted > 0, \"part-granted\", 'not granted' ) )) AS ?perm )
			}
			""" ;
      sh:order 100 ;
      sh:prefixes ex: ;
    ] ;
  sh:rule [
      rdf:type sh:SPARQLRule ;
      rdfs:label "Infer if $this is permitted by with IMDB Dispensation 1" ;
      sh:condition ex:RequestTest ;
      sh:condition [
          sh:property [
              sh:path ex:action ;
              sh:class dpv:Use ;
              sh:minCount 1 ;
            ] ;
        ] ;
      sh:condition [
          sh:property [
              sh:path ex:data ;
              sh:class dpv:PersonalDataCategory ;
              sh:minCount 1 ;
            ] ;
        ] ;
      sh:condition [
          sh:property [
              sh:path ex:dataSubject ;
              sh:hasValue :IMDBUser ;
            ] ;
        ] ;
      sh:condition [
          sh:property [
              sh:path ex:processor ;
              sh:hasValue :Agent ;
            ] ;
        ] ;
      sh:condition [
          sh:property [
              sh:path ex:purpose ;
              sh:minCount 1 ;
              sh:or (
                  [
                    sh:class dpv:CustomerCare ;
                  ]
                  [
                    sh:class dpv:CommercialResearch ;
                  ]
                  [
                    sh:class dpv:CreateProductRecommendations ;
                  ]
                ) ;
            ] ;
        ] ;
      sh:construct """
			PREFIX :
			PREFIX ex:
			PREFIX rdf:
			CONSTRUCT {
				$this ex:conformsTo :IMDBDispensation1 .
				$this ex:answer \"permitted\" .
			}
			WHERE {}
			""" ;
      sh:order 1 ;
      sh:prefixes ex: ;
    ] ;
  sh:rule [
      rdf:type sh:SPARQLRule ;
      rdfs:label "Infer if $this is prohibited by with IMDB Prohibition 3" ;
      sh:condition ex:RequestTest ;
      sh:condition [
          sh:property [
              sh:path ex:action ;
              sh:class dpv:Use ;
              sh:minCount 1 ;
            ] ;
        ] ;
      sh:condition [
          sh:property [
              sh:path ex:data ;
              sh:class dpv:PersonalDataCategory ;
              sh:minCount 1 ;
            ] ;
        ] ;
      sh:condition [
          sh:property [
              sh:path ex:dataSubject ;
              sh:hasValue :IMDBUser ;
            ] ;
        ] ;
      sh:condition [
          sh:property [
              sh:path ex:processor ;
              sh:hasValue :Agent ;
            ] ;
        ] ;
      sh:condition [
          sh:property [
              sh:path ex:purpose ;
              sh:minCount 1 ;
              sh:or (
                  [
                    sh:class dpv:AcademicResearch ;
                  ]
                  [
                    sh:class dpv:CommercialInterest ;
                  ]
                  [
                    sh:class dpv:CreateEventRecommendations ;
                  ]
                  [
                    sh:class dpv:DeliveryOfGoods ;
                  ]
                  [
                    sh:class dpv:NonCommercialResearch ;
                  ]
                  [
                    sh:class dpv:PersonalisedBenefits ;
                  ]
                  [
                    sh:class dpv:Security ;
                  ]
                  [
                    sh:class dpv:ServiceOptimization ;
                  ]
                  [
                    sh:class dpv:UserInterfacePersonalisation ;
                  ]
                ) ;
            ] ;
        ] ;
      sh:construct """
			PREFIX :
			PREFIX ex:
			PREFIX rdf:
			CONSTRUCT {
				$this ex:prohibitedBy :IMDBProhibition3 .
				$this ex:answer \"prohibited\" .
			}
			WHERE {}
			""" ;
      sh:order 1 ;
      sh:prefixes ex: ;
    ] ;
.

                

Request 1 (Permission 1)

The request covers two actions - Collect and Transofrm, one of which is permitted by Permission 1 (for the same data/purpose/etc.), and the other is not mentioned in any permission (for the same other attributes). The result of applying inference on this request is "part-granted".

Note: here, during the normalization of the query, the full normalization (to atomic state) is not necessary. No subclasses of Transfer action are mentioned in any of the policy rules. Generally, though, normalization to atomic rules is the safest way to get fully detailed answer to your query.

:Request_1
  rdf:type ex:RequestImdb ;
  ex:action :Collect ;
  ex:action :Transform ;
  ex:childRequest :Request_1_1 ;
  ex:childRequest :Request_1_2 ;
  ex:controller :IMDB ;
  ex:data :Address ;
  ex:dataSubject :IMDBUser ;
  ex:purpose :Communication ;
  rdfs:label "Request 1" ;
  skos:prefLabel "Request 1" ;
.
:Request_1_1
  rdf:type ex:RequestImdb ;
  ex:action :Collect ;
  ex:controller :IMDB ;
  ex:data :Address ;
  ex:dataSubject :IMDBUser ;
  ex:parentRequest :Request_1 ;
  ex:purpose :Communication ;
  rdfs:label "Request 1_1" ;
  skos:prefLabel "Request 1_1" ;
.
:Request_1_2
  rdf:type ex:RequestImdb ;
  ex:action :Transform ;
  ex:controller :IMDB ;
  ex:data :Address ;
  ex:dataSubject :IMDBUser ;
  ex:parentRequest :Request_1 ;
  ex:purpose :Communication ;
  rdfs:label "Request 1_2" ;
  skos:prefLabel "Request 1_2" ;
.

                

Conflict resolution Prohibition 3

Let us consider Prohibition 3: it contains action, data, processor, but not purpose, which means - dpv:Purpose, or AnyPurpose. However, the rule also contains a dispensation - exception to a prohibition, i.e., permission nested from a prohibition. It contains all the same attributes, except it allows 3 purposes. Therefore, there is a conflict between the prohibition (which prohibits all purposes) and permission (which allows 3 of them). We know that the dispensation (permission) is an exception to the prohibition, which means that it is stronger. Therefore, to resolve the conflict, after normalizing the prohibition, we remove the parts of the prohibition (the 3 purposes) that are weaker than the permission, and the resulting "denormalized" prohibition contains all the remaining purposes. Other attributes don't change. Below are the initial rules and their conflict-free versions, that are included in the SHACL policy.

:IMDBProhibition3
rdf:type orcp:Prohibition ;
rdf:type owl:NamedIndividual ;
:action :Use ;
:data :PersonalInformation ;
:dispensation :IMDBDispensation1 ;
:processor :Agent ;
.


:IMDBDispensation1
rdf:type orcp:Dispensation ;
rdf:type owl:NamedIndividual ;
:action :Use ;
:data :PersonalInformation ;
:processor :Agent ;
:purpose :Communication ;
:purpose :DataAnalysis ;
:purpose :Marketing ;
.
                
:IMDBProhibition3_ConflictFree
rdf:type orcp:Prohibition ;
rdf:type owl:NamedIndividual ;
:action :Use ;
:data :PersonalInformation ;
:dispensation :IMDBDispensation1 ;
:processor :Agent ;
:purpose :AcademicResearch ;
:purpose :CommercialInterest ;
:purpose :CreateEventRecommendations ;
:purpose :DeliveryOfGoods ;
:purpose :NonCommercialResearch ;
:purpose :PersonalisedBenefits ;
:purpose :Security ;
:purpose :ServiceOptimization ;
:purpose :UserInterfacePersonalisation ;
.


:IMDBDispensation1
rdf:type orcp:Dispensation ;
rdf:type owl:NamedIndividual ;
:action :Use ;
:data :PersonalInformation ;
:processor :Agent ;
:purpose :Communication ;
:purpose :DataAnalysis ;
:purpose :Marketing ;
.
                

Request 2 (Prohibtion 3 / Dispensation 1)

Now that we have conflict-free policy, we can showcase a request that would highlight the behaviour concerning prohibitions. The request contains same attributes as Prohibition 3/Dispensation 1, but 2 purposes it mentions belong to the opposite rules. The request gets broken down into 2 subrequests (again, full normalization is not performed here for space saving purpose). After performing SHACL inference, one subrequest of this request is permitted, and the other is prohibited, resulting in "part-granted" answer to the full query.

:Request_2
rdf:type ex:RequestImdb ;
ex:action :Use ;
ex:childRequest :Request_2_1 ;
ex:childRequest :Request_2_2 ;
ex:data :Address ;
ex:dataSubject :IMDBUser ;
ex:processor :Agent ;
ex:purpose :Communication ;
ex:purpose :DeliveryOfGoods ;
rdfs:label "Request 2" ;
skos:prefLabel "Request 2" ;
.
:Request_2_1
rdf:type ex:RequestImdb ;
ex:action :Use ;
ex:data :Address ;
ex:dataSubject :IMDBUser ;
ex:parentRequest :Request_2 ;
ex:processor :Agent ;
ex:purpose :DeliveryOfGoods ;
rdfs:label "Request 2" ;
skos:prefLabel "Request 2" ;
.
:Request_2_2
rdf:type ex:RequestImdb ;
ex:action :Use ;
ex:data :Address ;
ex:dataSubject :IMDBUser ;
ex:parentRequest :Request_2 ;
ex:processor :Agent ;
ex:purpose :Communication ;
rdfs:label "Request 2" ;
skos:prefLabel "Request 2" ;

            

Request 3 (Permission 1 with normalization)

This example, like Request 1, is supposed to be targeted at Permission 1. The difference is that the action - Obtain - is more general than the action Collect, mentioned in the permission. This way, if we don't normalize the action into its atomic parts (or at least don't break it down to the level existing in the permission), the answer to the request is a definite "not granted" (see what happens if only Request 3_1 is sent to inference). However, this answer is not informative enough - to get the full explanation, we normalize the request into 3 atomic subrequests, and receive the answer "part-granted", which is the actual case. Such granularity in compliance checking response makes the system more transparent and explainable, and allows the user/application to react in a fast and informed way.

:Request_3
  rdf:type ex:RequestImdb ;
  ex:action :Obtain ;
  ex:childRequest :Request_3_1 ;
  ex:childRequest :Request_3_1_1 ;
  ex:childRequest :Request_3_1_2 ;
  ex:childRequest :Request_3_1_3 ;
  ex:controller :IMDB ;
  ex:data :Address ;
  ex:dataSubject :IMDBUser ;
  ex:purpose :Communication ;
  rdfs:label "Request 3" ;
  skos:prefLabel "Request 3" ;
.
:Request_3_1
  rdf:type ex:RequestImdb ;
  ex:action :Obtain ;
  ex:controller :IMDB ;
  ex:data :Address ;
  ex:dataSubject :IMDBUser ;
  ex:parentRequest :Request_3 ;
  ex:purpose :Communication ;
  rdfs:label "Request 3" ;
  skos:prefLabel "Request 3" ;
.
:Request_3_1_1
  rdf:type ex:RequestImdb ;
  ex:action :Acquire ;
  ex:controller :IMDB ;
  ex:data :Address ;
  ex:dataSubject :IMDBUser ;
  ex:parentRequest :Request_3 ;
  ex:purpose :Communication ;
  rdfs:label "Request 3" ;
  skos:prefLabel "Request 3" ;
.
:Request_3_1_2
  rdf:type ex:RequestImdb ;
  ex:action :Collect ;
  ex:controller :IMDB ;
  ex:data :Address ;
  ex:dataSubject :IMDBUser ;
  ex:parentRequest :Request_3 ;
  ex:purpose :Communication ;
  rdfs:label "Request 3" ;
  skos:prefLabel "Request 3" ;
.
:Request_3_1_3
  rdf:type ex:RequestImdb ;
  ex:action :Record ;
  ex:controller :IMDB ;
  ex:data :Address ;
  ex:dataSubject :IMDBUser ;
  ex:parentRequest :Request_3 ;
  ex:purpose :Communication ;
  rdfs:label "Request 3" ;
  skos:prefLabel "Request 3" ;
.

                

Acknowledgements

We would like to thank Harshvardhan J. Pandit for valuable information and advice that guided us in designing SAVE.