8.5. Policy Management
This tutorial covers the Policy Management system in the dAIEDGE Middleware, enabling fine-grained access control using ODRL (Open Digital Rights Language) policies.
Overview
Policies allow you to:
- Define usage constraints for hardware resources
- Control who can access specific services (benchmarking types)
- Require specific Verifiable Credential claims for access
- Manage access at both user (DID) and hardware levels
What are ODRL Policies?
ODRL is a W3C standard for expressing permissions, prohibitions, and obligations. In dAIEDGE:
- DID Policies: Define what services a user identity can access
- Hardware Policies: Define what services a hardware resource can provide
Prerequisites
- Completed Authentication, Wallet Management, and Identity Management tutorials
- Understanding of Verifiable Credentials (for constraint-based policies)
LICENSE_MANAGER_ROLEfor creating/editing/removing policies
Required Role
All write operations (create, edit, delete) require the LICENSE_MANAGER_ROLE:
| Operation | Required Role |
|---|---|
| Get DID Policy | Owner of the DID |
| Get Hardware Policy | Owner of the hardware |
| Create/Edit/Delete DID Policy | LICENSE_MANAGER_ROLE |
| Create/Edit/Delete Hardware Policy | LICENSE_MANAGER_ROLE |
Policy Structure
Policies follow the ODRL specification with dAIEDGE-specific extensions:
{
"@context": [
"http://www.w3.org/ns/odrl.jsonld",
{
"vlab": "http://vlab.example.org/ns#"
}
],
"uid": "urn:vlab:policy:user:did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"type": "Set",
"assigner": "did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"profile": "http://vlab.example.org/odrl-profile",
"permission": [
{
"target": "http://vlab.example.org/platform/all",
"action": [
{
"type": "vlab:allowService",
"refinement": {
"type": "vlab:serviceType",
"value": "TYPE1"
}
}
],
"constraint": [
{
"leftOperand": "vlab:vcClaim",
"operator": "eq",
"rightOperand": "Group1",
"vlab:vcType": "vlab:CertifiedBenchmarker",
"vlab:vcPath": "$.credentialSubject.group"
}
]
}
]
}Key Fields
| Field | Description |
|---|---|
@context | ODRL and vLab vocabulary namespaces |
uid | Unique policy identifier (must match resource) |
type | Policy type (always “Set”) |
assigner | DID of the policy issuer |
profile | Policy profile |
permission | Array of permission rules |
Permission Structure
| Field | Description |
|---|---|
target | Resource the permission applies to |
action | Array of allowed actions |
constraint | Optional conditions (e.g., VC claims) for user policies |
Constraint Fields (User Policies)
| Field | Description |
|---|---|
leftOperand | The operand to evaluate (e.g., vlab:vcClaim) |
operator | Comparison operator (eq or neq) |
rightOperand | Value to compare against (e.g., Group1) |
vlab:vcType | Type of verifiable credential required |
vlab:vcPath | JSON path to the claim in the VC |
Service Types
| Service Type | Description |
|---|---|
TYPE1 | Basic benchmarking service |
TYPE2 | Intermediate benchmarking service |
TYPE3 | Advanced benchmarking service |
Constraint Operators
| Operator | Description |
|---|---|
eq | Equal to |
neq | Not equal to |
DID Policies
DID policies control what services a user identity can access.
UID Format
urn:vlab:policy:user:{DID}Example: urn:vlab:policy:user:did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7
Step 1: Create a DID Policy
Define access rules for a user identity.
Endpoint
POST /api/v1/policies/dids/{target_did}Request
curl -X POST https://middleware-daiedge.bisite.usal.es/api/v1/policies/dids/did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7 \
-H "Content-Type: application/json" \
-H "x-session-id: {SESSION_ID}" \
-d '{
"walletId": "0000029f3c8e5a1d7b4e9f2c",
"password": "WalletPass123!",
"did": "did:ethr:development:0x1A4c6E9b2D5f7A3c8E1b4D6f9A2c5E7b1D4f6A8c",
"policy": {
"@context": [
"http://www.w3.org/ns/odrl.jsonld",
{ "vlab": "http://vlab.example.org/ns#" }
],
"uid": "urn:vlab:policy:user:did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"type": "Set",
"assigner": "did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"profile": "http://vlab.example.org/odrl-profile",
"permission": [
{
"target": "http://vlab.example.org/platform/all",
"action": [
{
"type": "vlab:allowService",
"refinement": {
"type": "vlab:serviceType",
"value": "TYPE1"
}
},
{
"type": "vlab:allowService",
"refinement": {
"type": "vlab:serviceType",
"value": "TYPE2"
}
}
],
"constraint": [
{
"leftOperand": "vlab:vcClaim",
"operator": "eq",
"rightOperand": "Group1",
"vlab:vcType": "vlab:CertifiedBenchmarker",
"vlab:vcPath": "$.credentialSubject.group"
}
]
}
]
}
}'Request Body
| Field | Type | Required | Description |
|---|---|---|---|
walletId | string | Yes | Your wallet ID |
password | string | Yes | Wallet password |
did | string | Yes | Your DID (must have LICENSE_MANAGER_ROLE) |
policy | object | Yes | ODRL policy object |
Policy Validation Rules
- UID must match:
urn:vlab:policy:user:{target_did} - Action type must be:
vlab:allowService - Service type must be:
TYPE1,TYPE2, orTYPE3 - Constraint operator must be:
eqorneq - Constraint value must be:
Group1orGroup2
Response (200 OK)
{}Error Responses
| Code | Error | Cause |
|---|---|---|
| 404 | WALLET_NOT_FOUND | Wallet doesn’t exist |
| 400 | WRONG_PASSWORD | Wallet password incorrect |
| 400 | INVALID_USER_DID | Your DID format invalid |
| 400 | INVALID_TARGET_DID | Target DID format invalid |
| 400 | ALREADY_EXISTS | Policy already exists for this DID |
| 400 | INVALID_POLICY_FORMAT | Policy doesn’t match ODRL schema |
| 400 | INVALID_POLICY_UID | UID doesn’t match target DID |
| 400 | INVALID_PERMISSIONS | Permission targets are invalid |
| 403 | INVALID_WALLET | Wallet doesn’t belong to you |
| 403 | LICENSE_MANAGER_ROLE_REQUIRED | Missing required role |
| 500 | TRANSACTION_ERROR | Blockchain transaction failed |
Step 2: Get a DID Policy
Retrieve the policy for a DID you own.
Endpoint
GET /api/v1/policies/dids/{did}Request
curl -X GET "https://middleware-daiedge.bisite.usal.es/api/v1/policies/dids/did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7" \
-H "x-session-id: {SESSION_ID}"Response (200 OK)
{
"@context": [
"http://www.w3.org/ns/odrl.jsonld",
{ "vlab": "http://vlab.example.org/ns#" }
],
"uid": "urn:vlab:policy:user:did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"type": "Set",
"assigner": "did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"profile": "http://vlab.example.org/odrl-profile",
"permission": [
{
"target": "http://vlab.example.org/platform/all",
"action": [
{
"type": "vlab:allowService",
"refinement": {
"type": "vlab:serviceType",
"value": "TYPE1"
}
}
],
"constraint": [
{
"leftOperand": "vlab:vcClaim",
"operator": "eq",
"rightOperand": "Group1",
"vlab:vcType": "vlab:CertifiedBenchmarker",
"vlab:vcPath": "$.credentialSubject.group"
}
]
}
]
}Error Responses
| Code | Error | Cause |
|---|---|---|
| 400 | INVALID_TARGET_DID | DID format invalid |
| 400 | POLICY_MISMATCH | Stored policy doesn’t match blockchain hash |
| 403 | NOT_OWNER_DID | You don’t own this DID |
| 404 | POLICY_NOT_FOUND | No policy exists for this DID |
Step 3: Edit a DID Policy
Update an existing DID policy.
Endpoint
PUT /api/v1/policies/dids/{target_did}Request
curl -X PUT https://middleware-daiedge.bisite.usal.es/api/v1/policies/dids/did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7 \
-H "Content-Type: application/json" \
-H "x-session-id: {SESSION_ID}" \
-d '{
"walletId": "000003a8d4f7b2c9e6a1d5f8",
"password": "WalletPass123!",
"did": "did:ethr:development:0x2C5e7A9b1D4f8B3c6E9a2D5f7A1c4E6b9D2f5A8c",
"policy": {
"@context": [
"http://www.w3.org/ns/odrl.jsonld",
{ "vlab": "http://vlab.example.org/ns#" }
],
"uid": "urn:vlab:policy:user:did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"type": "Set",
"assigner": "did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"profile": "http://vlab.example.org/odrl-profile",
"permission": [
{
"target": "http://vlab.example.org/platform/all",
"action": [
{
"type": "vlab:allowService",
"refinement": {
"type": "vlab:serviceType",
"value": "TYPE1"
}
},
{
"type": "vlab:allowService",
"refinement": {
"type": "vlab:serviceType",
"value": "TYPE2"
}
},
{
"type": "vlab:allowService",
"refinement": {
"type": "vlab:serviceType",
"value": "TYPE3"
}
}
]
}
]
}
}'Response (200 OK)
{}Error Responses
Same as create, plus:
| Code | Error | Cause |
|---|---|---|
| 404 | POLICY_NOT_FOUND | No policy exists to edit |
Step 4: Remove a DID Policy
Delete a DID policy.
Endpoint
DELETE /api/v1/policies/dids/{target_did}Request
curl -X DELETE https://middleware-daiedge.bisite.usal.es/api/v1/policies/dids/did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7 \
-H "Content-Type: application/json" \
-H "x-session-id: {SESSION_ID}" \
-d '{
"walletId": "000004b7e5a9c3d8f2b6a1e4",
"password": "WalletPass123!",
"did": "did:ethr:development:0x3D6f8A1c4E7b9C2d5F8a1D4e6B9c2F5a8D1e4B7c"
}'Request Body
| Field | Type | Required | Description |
|---|---|---|---|
walletId | string | Yes | Your wallet ID |
password | string | Yes | Wallet password |
did | string | Yes | Your DID (must have LICENSE_MANAGER_ROLE) |
Response (200 OK)
{}Error Responses
| Code | Error | Cause |
|---|---|---|
| 404 | WALLET_NOT_FOUND | Wallet doesn’t exist |
| 404 | POLICY_NOT_FOUND | No policy exists to remove |
| 400 | WRONG_PASSWORD | Wallet password incorrect |
| 400 | INVALID_USER_DID | Your DID format invalid |
| 400 | INVALID_TARGET_DID | Target DID format invalid |
| 403 | INVALID_WALLET | Wallet doesn’t belong to you |
| 403 | LICENSE_MANAGER_ROLE_REQUIRED | Missing required role |
| 500 | TRANSACTION_ERROR | Blockchain transaction failed |
Hardware Policies
Hardware policies control what services a hardware resource can provide.
UID Format
urn:vlab:policy:device:{hardware_id}Example: urn:vlab:policy:device:0000019a9bec41233f591170b9ccee66e618a8ae45e1cbf749190e92f89119f6
Note: Hardware ID format is the raw hex string — not a 0x-prefixed bytes32.
Target Format
urn:vlab:device:{hardware_id}Example: urn:vlab:device:0000019a9bec41233f591170b9ccee66e618a8ae45e1cbf749190e92f89119f6
Step 5: Create a Hardware Policy
Define what services a hardware resource can provide.
Endpoint
POST /api/v1/policies/hardware/{hardware_id}Request
curl -X POST https://middleware-daiedge.bisite.usal.es/api/v1/policies/hardware/0000019a9bec41233f591170b9ccee66e618a8ae45e1cbf749190e92f89119f6 \
-H "Content-Type: application/json" \
-H "x-session-id: {SESSION_ID}" \
-d '{
"walletId": "000005c8f6a2d9e4b7c1f5a8",
"password": "WalletPass123!",
"did": "did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640",
"policy": {
"@context": [
"http://www.w3.org/ns/odrl.jsonld",
{ "vlab": "http://vlab.example.org/ns#" }
],
"uid": "urn:vlab:policy:device:0000019a9bec41233f591170b9ccee66e618a8ae45e1cbf749190e92f89119f6",
"type": "Set",
"assigner": "did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640",
"profile": "http://vlab.example.org/odrl-profile",
"permission": [
{
"target": "urn:vlab:device:0000019a9bec41233f591170b9ccee66e618a8ae45e1cbf749190e92f89119f6",
"action": [
{
"type": "vlab:allowService",
"refinement": {
"type": "vlab:serviceType",
"value": "TYPE1"
}
},
{
"type": "vlab:allowService",
"refinement": {
"type": "vlab:serviceType",
"value": "TYPE2"
}
}
]
}
],
"constraint": [
{
"leftOperand": "vlab:vcClaim",
"operator": "eq",
"rightOperand": "Group1",
"vlab:vcType": "vlab:CertifiedBenchmarker",
"vlab:vcPath": "$.credentialSubject.group"
}
]
}
}'Response (200 OK)
{}Error Responses
| Code | Error | Cause |
|---|---|---|
| 404 | WALLET_NOT_FOUND | Wallet doesn’t exist |
| 404 | HARDWARE_NOT_FOUND | Hardware doesn’t exist |
| 400 | WRONG_PASSWORD | Wallet password incorrect |
| 400 | INVALID_USER_DID | Your DID format invalid |
| 400 | ALREADY_EXISTS | Policy already exists for this hardware |
| 400 | INVALID_POLICY_FORMAT | Policy doesn’t match ODRL schema |
| 400 | INVALID_POLICY_UID | UID doesn’t match hardware ID |
| 400 | INVALID_PERMISSIONS | Permission targets don’t match hardware ID |
| 403 | INVALID_WALLET | Wallet doesn’t belong to you |
| 403 | LICENSE_MANAGER_ROLE_REQUIRED | Missing required role |
| 500 | TRANSACTION_ERROR | Blockchain transaction failed |
Step 6: Get a Hardware Policy
Retrieve the policy for hardware you own.
Endpoint
GET /api/v1/policies/hardware/{hardware_id}Request
curl -X GET "https://middleware-daiedge.bisite.usal.es/api/v1/policies/hardware/0000019a9bec41233f591170b9ccee66e618a8ae45e1cbf749190e92f89119f6" \
-H "x-session-id: {SESSION_ID}"Response (200 OK)
{
"@context": [
"http://www.w3.org/ns/odrl.jsonld",
{ "vlab": "http://vlab.example.org/ns#" }
],
"uid": "urn:vlab:policy:device:0000019a9bec41233f591170b9ccee66e618a8ae45e1cbf749190e92f89119f6",
"type": "Set",
"assigner": "did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640",
"profile": "http://vlab.example.org/odrl-profile",
"permission": [
{
"target": "urn:vlab:device:0000019a9bec41233f591170b9ccee66e618a8ae45e1cbf749190e92f89119f6",
"action": [
{
"type": "vlab:allowService",
"refinement": {
"type": "vlab:serviceType",
"value": "TYPE1"
}
},
{
"type": "vlab:allowService",
"refinement": {
"type": "vlab:serviceType",
"value": "TYPE2"
}
}
]
}
],
"constraint": [
{
"leftOperand": "vlab:vcClaim",
"operator": "eq",
"rightOperand": "Group1",
"vlab:vcType": "vlab:CertifiedBenchmarker",
"vlab:vcPath": "$.credentialSubject.group"
}
]
}Error Responses
| Code | Error | Cause |
|---|---|---|
| 400 | POLICY_MISMATCH | Stored policy doesn’t match blockchain hash |
| 403 | NOT_OWNER_DID | You don’t own this hardware |
| 404 | HARDWARE_NOT_FOUND | Hardware doesn’t exist |
| 404 | USER_DID_NOT_FOUND | Hardware owner DID not found |
| 404 | POLICY_NOT_FOUND | No policy exists for this hardware |
Step 7: Edit a Hardware Policy
Update an existing hardware policy.
Endpoint
PUT /api/v1/policies/hardware/{hardware_id}Request
curl -X PUT https://middleware-daiedge.bisite.usal.es/api/v1/policies/hardware/0000019a9bec41233f591170b9ccee66e618a8ae45e1cbf749190e92f89119f6 \
-H "Content-Type: application/json" \
-H "x-session-id: {SESSION_ID}" \
-d '{
"walletId": "0000019a95f732ce0adb8f69ccc7d362",
"password": "WalletPass123!",
"did": "did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"policy": { "...": "updated policy object" }
}'Request body structure is the same as Step 5: Create a Hardware Policy.
Error Responses
Same as create, plus:
| Code | Error | Cause |
|---|---|---|
| 404 | POLICY_NOT_FOUND | No policy exists to edit |
Step 8: Remove a Hardware Policy
Delete a hardware policy.
Endpoint
DELETE /api/v1/policies/hardware/{hardware_id}Request
curl -X DELETE https://middleware-daiedge.bisite.usal.es/api/v1/policies/hardware/0000019a9bec41233f591170b9ccee66e618a8ae45e1cbf749190e92f89119f6 \
-H "Content-Type: application/json" \
-H "x-session-id: {SESSION_ID}" \
-d '{
"walletId": "000006d9f7b3a5e8c2d6f1a4",
"password": "WalletPass123!",
"did": "did:ethr:development:0x5F8a1C4d7E9b2A5c8D1f4E7a9C2d5F8b1A4c7E9f"
}'Response (200 OK)
{}Next Steps
- Benchmarking - Use policies to control benchmark access
- Licenses - Request licenses based on policies - WIP
Related Topics
- Verifiable Credentials - Claims used in constraints
- Role Management - Obtain
LICENSE_MANAGER_ROLE - Hardware Registration - Register hardware for policies