9. Licensing
This tutorial covers the Licensing system in the dAIEDGE Middleware, enabling users to request access to hardware resources protected by policies.
Overview
When a hardware resource has a policy defined, users must obtain a valid license to access it. The licensing workflow involves:
- Generating a Key Pair: Creating a key pair to sign the license request presentation.
- Requesting a License: Submitting a request with Verifiable Credentials and the signed presentation.
- Validating the Request: The license manager reviews and validates the request.
- Issuing the License: If validated, a license is issued on the blockchain.
Prerequisites
- Completed Authentication, Wallet Management, and Identity Management tutorials
- Completed Verifiable Credentials (if the policy requires specific credentials)
- Completed Policy Management (to understand the policies enforcing the license requirement)
IDENTITY_OWNER_ROLEassigned to your DID (required to generate a key pair)
Step 1: Generate Key Pair
Before requesting a license, you need a key pair to sign the Verifiable Presentation that will be sent with your request. This key pair is linked to your DID.
Requires IDENTITY_OWNER_ROLE on the DID.
Endpoint
POST /api/v1/identities/{did}/generate-key-pairRequest
curl -X POST https://middleware-daiedge.bisite.usal.es/api/v1/identities/did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7/generate-key-pair \
-H "Content-Type: application/json" \
-H "x-session-id: {SESSION_ID}" \
-d '{
"walletId": "000007e2a9f5c1b8d4e7a3f6",
"password": "WalletPass123!",
"algorithm": "Ed25519",
"purpose": "sigAuth",
"duration": 31536000
}'Request Body
| Field | Type | Required | Description |
|---|---|---|---|
walletId | string | Yes | Your wallet ID |
password | string | Yes | Wallet password |
algorithm | string | Yes | Key algorithm: Secp256k1 or Ed25519 |
purpose | string | Yes | Key purpose: veriKey, sigAuth, or enc |
duration | number | No | Key validity duration in seconds (default: 1 year) |
Response (200 OK)
{
"publicKey": "c9XdZ+l0q5LBR/o+T/tME2o4oUarZ7+7etLJzjpEYNM=",
"privateKey": "Hio6aM/ZHS8rPlo0Mnl3IWo3RkGovTOL32gSAYiC2kNz1d1n6XSrksFH+j5P+0wTajihRqtnv7t60snOOkRg0w==",
"algorithm": "Ed25519",
"encoding": "base64",
"purpose": "sigAuth",
"expiration": "2025-11-28T14:44:35.821Z"
}Important: Save the privateKey returned in the response. You will need it to request the license in Step 2.
Note: Use _without_preload_content as shown above — the standard method returns None due to a known client bug.
Verify Public Key
You can verify that the public key has been correctly added to your DID Document by resolving the DID. The public key is used to verify the signature of the Verifiable Presentation during license validation.
Endpoint: GET /api/v1/identities/{did}/resolve
Response:
{
"document": {
"id": "did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640",
"verificationMethod": [
{
"id": "did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640#controller",
"type": "EcdsaSecp256k1RecoveryMethod2020",
"controller": "did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640",
"blockchainAccountId": "eip155:1337:0x7018205409a98fb9580B53e268d58C96d58BA640"
},
{
"id": "did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640#delegate-2",
"type": "Ed25519VerificationKey2018",
"controller": "did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640",
"publicKeyBase64": "c9XdZ+l0q5LBR/o+T/tME2o4oUarZ7+7etLJzjpEYNM="
}
],
"authentication": [
"did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640#controller",
"did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640#delegate-2"
],
"assertionMethod": [
"did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640#controller",
"did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640#delegate-2"
],
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/secp256k1recovery-2020/v2",
"https://w3id.org/security/v3-unstable"
]
}
}If the key is missing or expired, license validation will fail.
Step 2: Request a License
Request a license for a specific hardware resource. You must provide the hardware ID, your DID, your Verifiable Credentials (if required by the policy), and the private key generated in Step 1.
Endpoint
POST /api/v1/licenses/requestsRequest
curl -X POST https://middleware-daiedge.bisite.usal.es/api/v1/licenses/requests \
-H "Content-Type: application/json" \
-H "x-session-id: {SESSION_ID}" \
-d '{
"hardwareId": "0000019a9bec41233f591170b9ccee66e618a8ae45e1cbf749190e92f89119f6",
"did": "did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"credentials": [
"eyJhbGciOiJFZERTQSIs..."
],
"key": "base64_encoded_private_key_from_step_1"
}'Request Body
| Field | Type | Required | Description |
|---|---|---|---|
hardwareId | string | Yes | ID of the hardware you want to access |
did | string | Yes | Your DID — must be the same DID used to generate the key pair in Step 1 |
credentials | array | Yes | List of Verifiable Credentials (JWT strings) satisfying the policy |
key | string | Yes | The private key from Step 1 (base64 encoded, as returned by the API) |
Response (200 OK)
{}The request is now in PENDING status, waiting for validation by a License Manager.
Error Responses
| Code | Error | Cause |
|---|---|---|
| 400 | INVALID_CREDENTIALS_FORMAT | Credentials array is malformed |
| 400 | HARDWARE_POLICY_MISMATCH | Provided VCs do not satisfy the hardware policy |
| 400 | INVALID_KEY_FORMAT | Private key format invalid or DID mismatch |
| 404 | HARDWARE_NOT_FOUND | Hardware ID does not exist |
| 404 | HARDWARE_POLICY_NOT_FOUND | Hardware has no policy defined |
Step 3: List License Requests (License Manager)
A user with the LICENSE_MANAGER_ROLE can view pending license requests.
Endpoint
GET /api/v1/licenses/requestsRequest
curl -X GET "https://middleware-daiedge.bisite.usal.es/api/v1/licenses/requests?page=1" \
-H "x-session-id: {SESSION_ID}"Response (200 OK)
{
"requests": [
{
"id": "000008f3b7a6d2c9e5f1a8b4",
"uid": "000007e2a9f5c1b8d4e7a3f6",
"did": "did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"hid": "0000019a9bec41233f591170b9ccee66e618a8ae45e1cbf749190e92f89119f6",
"created": 1697000000000,
"status": "PENDING"
}
],
"page": 1,
"totalPages": 1,
"total": 1
}Step 4: Validate and Issue License (License Manager)
The License Manager validates the request and issues the license on the blockchain.
Validation Process
The validation process involves matching the User Policy (assigned to the requester’s DID) against the Hardware Policy (assigned to the hardware resource). The License Manager verifies that the Verifiable Credentials presented in the request satisfy the constraints defined in these policies.
Note
Key Verification: The validation also checks the signature of the Verifiable Presentation using the public key in the user’s DID Document. If the key used to sign the request has expired or is not present in the DID Document, validation will fail.
Endpoint
POST /api/v1/licenses/requests/{id}/validateRequest
curl -X POST https://middleware-daiedge.bisite.usal.es/api/v1/licenses/requests/000008f3b7a6d2c9e5f1a8b4/validate \
-H "Content-Type: application/json" \
-H "x-session-id: {SESSION_ID}" \
-d '{
"walletId": "000009a4c8e5b2d7f9a3c6e1",
"password": "WalletPass123!",
"did": "did:ethr:development:0xAdminDID...",
"singleUse": false,
"duration": 2592000
}'Request Body
| Field | Type | Required | Description |
|---|---|---|---|
walletId | string | Yes | License Manager’s wallet ID |
password | string | Yes | Wallet password |
did | string | Yes | License Manager’s DID (must have LICENSE_MANAGER_ROLE) |
singleUse | boolean | No | If true, the license is valid for one use only (default: false) |
duration | number | No | License validity duration in seconds (0 = infinite) |
Response (200 OK)
{
"id": "0000019ac570a8f5727f778880d6a0e3",
"uid": "0000019a95ee982dc1729b661cfc3116",
"did": "did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640",
"hid": "0000019ac53012fb47b1e8648650764f47f97355249fb144e71f601edb303ead",
"license": {
"@context": [
"http://www.w3.org/ns/odrl.jsonld",
{
"vlab": "http://vlab.example.org/ns#"
}
],
"uid": "urn:vlab:license:0000019ac570a8f429811fe78985d681",
"type": "Agreement",
"profile": "http://vlab.example.org/odrl-profile",
"assigner": "did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640",
"assignee": "did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640",
"permission": [
{
"target": "urn:vlab:device:0000019ac53012fb47b1e8648650764f47f97355249fb144e71f601edb303ead",
"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"
}
]
}
]
},
"created": 1764249086197
}Returns the issued ODRL license agreement.
Step 5: List Your Licenses
Users can view their issued licenses.
Endpoint
GET /api/v1/licensesRequest
curl -X GET "https://middleware-daiedge.bisite.usal.es/api/v1/licenses?page=1" \
-H "x-session-id: {SESSION_ID}"Get License Details
curl -X GET "https://middleware-daiedge.bisite.usal.es/api/v1/licenses/{LICENSE_ID}" \
-H "x-session-id: {SESSION_ID}"Revoke a License
Requires LICENSE_MANAGER_ROLE.
curl -X DELETE https://middleware-daiedge.bisite.usal.es/api/v1/licenses/{LICENSE_ID} \
-H "Content-Type: application/json" \
-H "x-session-id: {SESSION_ID}" \
-d '{
"did": "did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7",
"walletId": "0000019a95f732ce0adb8f69ccc7d362",
"password": "WalletPass123!"
}'Response (200 OK)
{
"licenses": [
{
"id": "0000019ac570a8f5727f778880d6a0e3",
"uid": "0000019a95ee982dc1729b661cfc3116",
"did": "did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640",
"hid": "0000019ac53012fb47b1e8648650764f47f97355249fb144e71f601edb303ead",
"license": {
"@context": [
"http://www.w3.org/ns/odrl.jsonld",
{
"vlab": "http://vlab.example.org/ns#"
}
],
"uid": "urn:vlab:license:0000019ac570a8f429811fe78985d681",
"type": "Agreement",
"profile": "http://vlab.example.org/odrl-profile",
"assigner": "did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640",
"assignee": "did:ethr:development:0x7018205409a98fb9580b53e268d58c96d58ba640",
"permission": [
{
"target": "urn:vlab:device:0000019ac53012fb47b1e8648650764f47f97355249fb144e71f601edb303ead",
"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"
}
]
},
{
"target": "urn:vlab:device:0000019ac53012fb47b1e8648650764f47f97355249fb144e71f601edb303ead",
"action": [
{
"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"
}
]
}
]
},
"created": 1764249086197
}
],
"page": 1,
"totalPages": 1,
"total": 1
}Step 6: List Accessible Hardware
Check which hardware resources you can access based on your Verifiable Credentials, DID policy and the hardware policies. The response includes a list of accessible hardware devices for every Verifiable Credential that the provided DID has associated.
Endpoint
GET /api/v1/licenses/devices?did={did}&page={page}Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
did | string | Yes | Your DID |
page | number | No | Page number (default: 1) |
Request
curl -X GET "https://middleware-daiedge.bisite.usal.es/api/v1/licenses/devices?did=did:ethr:development:0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb7&page=1" \
-H "x-session-id: {SESSION_ID}"Response (200 OK)
{
"vcs": [
{
"id": "0000019a9b39952bad9a53740f7ce5ed",
"hardwareIds": [
"0000019adf4404ae5dcc0f2bcee2e53d4ebf13c5be1b095ae1ba0a8be6f78b10",
"0000019ac53012fb47b1e8648650764f47f97355249fb144e71f601edb303ead"
]
}
],
"page": 1,
"totalPages": 1,
"total": 1
}Next Steps
- Benchmarking - Use your license to execute benchmarks on protected hardware.