@@ -31,7 +31,7 @@ so some information might change depending on which version and branch you're us
3131 * [ Authenticating as Resource Owner] ( #authenticating-as-resource-owner )
3232 * [ Authenticating as Resource Server] ( #authenticating-as-resource-server )
3333 + [ Requesting client credentials] ( #requesting-client-credentials )
34- + [ Sending the credentials to the RS (CSS specific)] ( #sending-the-credentials-to-the-rs-- css-specific- )
34+ + [ Sending the credentials to the RS (CSS specific)] ( #sending-the-credentials-to-the-rs-css-specific )
3535 + [ Requesting a PAT as RS] ( #requesting-a-pat-as-rs )
3636 * [ Resource registration] ( #resource-registration )
3737 + [ About identifiers] ( #about-identifiers )
@@ -49,7 +49,10 @@ so some information might change depending on which version and branch you're us
4949 - [ Include ` sub ` claim in access token] ( #include-sub-claim-in-access-token )
5050 + [ Use token] ( #use-token )
5151 * [ Policies] ( #policies )
52- + [ Client application identification] ( #client-application-identification )
52+ + [ Additional constraints] ( #additional-constraints )
53+ - [ Client application identification] ( #client-application-identification )
54+ - [ Purpose] ( #purpose )
55+ - [ Verifiable Credentials] ( #verifiable-credentials )
5356 * [ Adding or changing policies] ( #adding-or-changing-policies )
5457 * [ Policy backups] ( #policy-backups )
5558 * [ Data aggregation] ( #data-aggregation )
@@ -363,9 +366,47 @@ This base URL will be updated in the future once we have settled on a fixed valu
363366##### Additional claims
364367
365368Besides claims that identify the user and client, additional claims can also be provided containing additional information.
366- Currently, the only additional claim that is supported is the ` purpose ` claim.
367- This can be provided with a ` claim_token_format ` of ` http://www.w3.org/ns/odrl/2/purpose ` ,
368- and with the ` claim_token ` being the IRI of the purpose.
369+ These claims can be used to add extra constraints to ODRL policies.
370+
371+ The purpose claim can be provided with a ` claim_token_format ` of ` http://www.w3.org/ns/odrl/2/purpose ` ,
372+ and with the ` claim_token ` being the IRI of the purpose,
373+ e.g., ` "https://w3id.org/dpv#ScientificResearch" ` .
374+
375+ Verifiable Credentials (VCs) can also be provided as additional claims using the token format ` urn:solidlab:uma:credentials:jwt:vc ` .
376+ The ` claim_token ` should be a signed JWT containing a ` vc ` claim with the credential data.
377+ For example, a decoded payload could be:
378+ ``` json
379+ {
380+ "exp" : 1784989353 ,
381+ "nbf" : 1784902953 ,
382+ "jti" : " urn:uuid:fecdb1de-d2d8-40a1-90ff-0e3cc8bfa3e9" ,
383+ "iss" : " http://localhost:28080/alice" ,
384+ "vc" : {
385+ "type" : [
386+ " VerifiableCredential" ,
387+ " http://localhost:28080/UserHcpRelationVC"
388+ ],
389+ "issuer" : " http://localhost:28080/alice" ,
390+ "issuanceDate" : " 2026-07-24T14:22:33.924Z" ,
391+ "expirationDate" : " 2026-07-25T14:22:33.924Z" ,
392+ "credentialSubject" : {
393+ "principal" : " alice" ,
394+ "rs:HCPs" : {
395+ "@id" : " ex:users/0" ,
396+ "rs:assignedPatientId" : " https://ex.example.com/users/123"
397+ },
398+ "@id" : " https://rs.example.com/named-graphs#qr-data" ,
399+ "@context" : {
400+ "rs" : " https://rs.example.com/vocab#" ,
401+ "ex" : " https://ex.example.com/"
402+ }
403+ },
404+ "@context" : [
405+ " https://www.w3.org/ns/credentials/v1"
406+ ]
407+ }
408+ }
409+ ```
369410
370411#### Customizing OIDC verification
371412
@@ -481,15 +522,21 @@ ex:permission a odrl:Permission ;
481522```
482523This policy says that the above WebID has access to the ` create ` scope on ` <http://localhost:3000/alice/private/> ` .
483524
484- ### Client application identification
525+ ### Additional constraints
526+
527+ Beyond specifying which user and resource a permission applies to,
528+ policies can also include constraints that add further conditions.
529+ Constraints use the ` odrl:constraint ` predicate and follow the general pattern of
530+ a ` odrl:leftOperand ` , ` odrl:operator ` , and ` odrl:rightOperand ` ,
531+ where the left operand identifies what to check, the operator defines how to compare,
532+ and the right operand provides the expected value.
485533
486- It is possible to create policies that restrict access based on the client application being used.
487- This can only be done when using an OIDC ID token for authentication.
488- The ` azp ` claim of the token will be used.
534+ #### Client application identification
489535
490- To restrict a policy to a certain client application,
491- a constraint needs to be added to the policy.
492- For this, we use the odrl: deliveryChannel left operand.
536+ It is possible to restrict access based on the client application being used.
537+ This can only be done when using an OIDC ID token for authentication,
538+ and uses the ` azp ` or ` client_id ` claim of the token.
539+ The left operand ` odrl:deliveryChannel ` is used to refer to the client application.
493540
494541To restrict a policy to only permit access when using the application ` http://example.com/client ` ,
495542the policy should look as follows:
@@ -510,6 +557,75 @@ ex:constraint odrl:leftOperand odrl:deliveryChannel ;
510557 odrl:rightOperand <http://example.com/client> .
511558```
512559
560+ #### Purpose
561+
562+ It is possible to restrict access based on the purpose for which the resource is being accessed.
563+ This requires that the client provides a purpose claim during the token exchange,
564+ as described in the [ Additional claims] ( #additional-claims ) section above.
565+ The left operand ` odrl:purpose ` is used to refer to the provided purpose.
566+
567+ To restrict a policy to only permit access for the purpose ` https://w3id.org/dpv#ScientificResearch ` :
568+ ``` ttl
569+ @prefix ex: <http://example.org/1707120963224#> .
570+ @prefix odrl: <http://www.w3.org/ns/odrl/2/> .
571+
572+ ex:usagePolicy a odrl:Agreement ;
573+ odrl:uid ex:usagePolicy ;
574+ odrl:permission ex:permission .
575+ ex:permission a odrl:Permission ;
576+ odrl:action odrl:read ;
577+ odrl:target <http://localhost:3000/alice/private/> ;
578+ odrl:assignee <https://woslabbi.pod.knows.idlab.ugent.be/profile/card#me> ;
579+ odrl:constraint ex:constraint .
580+ ex:constraint odrl:leftOperand odrl:purpose ;
581+ odrl:operator odrl:eq ;
582+ odrl:rightOperand <https://w3id.org/dpv#ScientificResearch> .
583+ ```
584+
585+ #### Verifiable Credentials
586+
587+ Policies can also restrict access based on attributes contained in a Verifiable Credential.
588+ This requires that the client provides a VC claim during the token exchange,
589+ as described in the [ Additional claims] ( #additional-claims ) section above.
590+
591+ VC constraints follow the [ ODRL VC profile] ( https://gitlab.com/gaia-x/lab/policy-reasoning/odrl-vc-profile )
592+ and use a slightly different vocabulary.
593+ The predicate ` ovc:constraint ` is used instead of ` odrl:constraint ` ,
594+ and ` ovc:leftOperand ` instead of ` odrl:leftOperand ` ,
595+ where the left operand value is a JSONPath expression evaluated against the credential data.
596+ The ` ovc:rightOperand ` still works the same as in standard ODRL constraints.
597+
598+ To restrict access to users whose VC contains
599+ ` rs:assignedPatientId: "https://ex.example.com/users/123" `
600+ inside the ` rs:HCPs ` object of the credential subject:
601+ ``` ttl
602+ @prefix ex: <http://example.org/1707120963224#> .
603+ @prefix odrl: <http://www.w3.org/ns/odrl/2/> .
604+ @prefix ovc: <https://w3id.org/gaia-x/ovc/1/> .
605+
606+ ex:usagePolicy a odrl:Agreement ;
607+ odrl:uid ex:usagePolicy ;
608+ odrl:permission ex:permission .
609+ ex:permission a odrl:Permission ;
610+ odrl:action odrl:read ;
611+ odrl:target <http://localhost:3000/research/data> ;
612+ ovc:constraint ex:constraint .
613+ ex:constraint ovc:leftOperand "$.credentialSubject['rs:HCPs']['rs:assignedPatientId']" ;
614+ odrl:operator odrl:eq ;
615+ odrl:rightOperand "https://ex.example.com/users/123" .
616+ ```
617+
618+ Optionally, you can also require the credential to be of a specific type by adding
619+ the ` ovc:credentialSubjectType ` property.
620+ This requires the ` type ` field in the credential to contain the specified value:
621+ ``` ttl
622+ ex:constraint ovc:leftOperand "$.credentialSubject['rs:HCPs']['rs:assignedPatientId']" ;
623+ odrl:operator odrl:eq ;
624+ odrl:rightOperand "https://ex.example.com/users/123" ;
625+ ovc:credentialSubjectType "http://localhost:28080/UserHcpRelationVC" .
626+ ```
627+
628+
513629## Adding or changing policies
514630
515631For more details, see the [ policy management API documentation] ( policy-management.md ) .
0 commit comments