System Local API Token Usecase with MQTT APIs
This guide explains how to:
- Retrieve JSON Web Key Sets (
JWKS) for token validation. - Monitor local API tokens for specific systems.
- Use MQTT topics for secure and efficient communication.
Please go through the Introduction Guide For MQTT Setup sections before proceeding with the use-case. Please make sure we have system EMS created in the DRIVR platform and the MQTT client is set up properly.
Let's create a use-case for local API token management using MQTT APIs. The following operations will be covered:
A smart building uses an IoT-based energy management system to securely communicate with its components. LocalApiTokens can be used to authenticate users which have a cloud account on a device local API, even when the device is intermittently offline. This enables the possibility to interact with a device on a local network or during a provisioning state without requiring an open unauthenticated API.
Subscribe to the JWKS topic to retrieve the JSON Web Key Sets for token validation.
SUB drivr/v1/{slug}/jwks
Sample Example:
Request:
SUB drivr/v1/company-example/jwks
Response:
Topic: drivr/v1/company-example/jwks QoS: 0 Retained
{
"keys": [
{
"n": "yZo9h-IC6RGIl1S7-Dyo1ONtPHKZdV8tUr8dPc4......",
"e": "AQAB",
"kty": "RSA",
"kid": "REqC0cg_tuDw3B36TRwBtJ-....."
}
]
}
Subscribe to the local API token topic to monitor tokens for a specific EMS system.
Note: We cannot create the local API token using MQTT APIs. It can only be created using GraphQL APIs.
Short-Lived Local API Token Creation Mutation Example
mutation LApiToken {
createLocalApiToken(
systemUuid: "792b6149-1daa-488f-b07a-f684503b0586",
requestedDevice: "smart-bulb",
duration: "1D"
) {
jwt
uuid
}
}
Response:
{
"data": {
"createLocalApiToken": {
"jwt": "CLOUD-eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ.....",
"uuid": "c606707f-198f-46f5-883e-68794ce81159"
}
}
}
Permanent Local API Token Creation Mutation Example
mutation createPermanentLocalApiTokenPermanent {
createPermanentLocalApiToken(
systemUuid: "792b6149-1daa-488f-b07a-f684503b0586",
name: "permanent-token-smart-light"
) {
jwt
uuid
}
}
Response:
{
"data": {
"createPermanentLocalApiToken": {
"jwt": "CLOUD-eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJiNzBmMzMwYS1jOGQxLTRiZj...",
"uuid": "b70f330a-c8d1-4bf8-8763-d59d455f9c1e"
}
}
}
The tokens are JWT tokens which are signed by DRIVR with an asynchronous API key. They should be able to include:
- All the roles the User has for a specific device.
- A uuid which uniquely identifies the token.
- The uuid of the system which the token is valid for.
- The user uuid and name.
- The validity of the token (which might be indefinite for specific use cases).
As the tokens are JWT tokens the device may accept them directly when being passed as the device has the public key available which is used to sign the JWT token.
The token follows the OpenID standard in parameter names and includes the following parameters:
- jti: The UUID of the token for example 530886ea-da07-4927-ade0-b49c05d655f4 (Following the standard).
- sub: The UUID of the entity (normally a User) which the token has been generated for (Following the standard).
- iss: The issuer of the token. This references to the OpenID URL of the domain which corresponds to the API URL (Following the standard).
- aud: The audience this token is for. This corresponds to the UUID of the System this token is generated for (Following the standard).
- exp: The UNIX timestamp when the token expires (Following the standard).
- nbf: The time from which the token should be accepted (Following the standard).
- iat: The time the token was created (Following the standard).
- name: The name of the user (Private additional information).
- typename: The entity type of the user configuration.
- roles: A list of roles the user has on the aud / audience / System. This includes the uuid and the name of the roles the user has in this context.
An example payload for this is:
{
"jti": "530886ea-da07-4927-ade0-b49c05d655f4",
"sub": "1ad6fb1a-c38e-4d68-ad44-248b88d5fd13",
"iss": "https://test.api.drivr.cloud",
"aud": "f3a20f70-3021-42f5-b9b9-9ea62e2eac2a",
"exp": 1730913498,
"nbf": 1730740638,
"iat": 1730740698,
"name": "Marie Curie",
"typename": "USER",
"roles": [
{
"uuid": "2faa6870-91b0-4b3a-84e8-8bbbd8becbd0",
"name": "System Maintainer"
}
]
}
This translates to a JWT token which looks like
CLOUD-
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI1MzA4ODZlYS1kYTA3LTQ5MjctYWRlMC1iNDljMDVkNjU1ZjQiLCJzdWIiOiIxYWQ2ZmIxYS1jMzhlLTRkNjgtYWQ0NC0yNDhiODhkNWZkMTMiLCJpc3MiOiJodHRwczovL2FkYW0uYXBpLmRyaXZyLmNsb3VkIiwiYXVkIjoiZjNhMjBmNzAtMzAyMS00MmY1LWI5YjktOWVhNjJlMmVhYzJhIiwiZXhwIjoxNzMwOTEzNDk4LCJuYmYiOjE3MzA3NDA2MzgsImlhdCI6MTczMDc0MDY5OCwibmFtZSI6Ik1hcmllIEN1cmllIiwidHlwZW5hbWUiOiJVU0VSIiwicm9sZXMiOlt7InV1aWQiOiIyZmFhNjg3MC05MWIwLTRiM2EtODRlOC04YmJiZDhiZWNiZDAiLCJuYW1lIjoiU3lzdGVtIE1haW50YWluZXIifV19.kaIIr5Jn25hvG-kHB2yiJlggpaJ7OUHfCjXK5_wJZeMsgC3I3w_8FXc4_n7C1730T55Ze6Awsq_28d-Cdxmokv5Gh3WPnDoFCGtqqnDK-VEChtl6UwNvc6a4cHHKVFapRjvdRklCtqWL__mpU5D41hVqU9ROrmdZvu-Vh7pyezzNGwRPPNeWcczBtSQ7NtWdLxYzpIcGPOiM8NCck5H4CcL7qE5ly95Ns_gZvV15iYOlKe53XqB8IGCg9ImLFOKsXruuCzWZKTzFNP-PqRHPgOCB0LdYIxg16uFKCZuEG2U2bIyFG0UHwMmtBy7tDy7Hivsl_j_QThOGeErOFS3lGQ
SUB drivr/v1/{slug}/authorization/localApiTokens/{systemUuid}
Sample Example:
Request:
SUB drivr/v1/company-example/authorization/localApiTokens/792b6149-1daa-488f-b07a-f684503b0586
Response:
Topic: drivr/v1/company-example/authorization/localApiTokens/792b6149-1daa-488f-b07a-f684503b0586 QoS: 0
[
{
"uuid": "b70f330a-c8d1-4bf8-8763-d59d455f9c1e",
"createdAt": "2025-05-12T14:59:06.718846",
"updatedAt": "2025-05-12T14:59:06.936417",
"status": "ACTIVATED",
"expiresAt": null,
"notBefore": "2025-05-12T14:59:06+00:00",
"systemUuid": "792b6149-1daa-488f-b07a-f684503b0586",
"roles": [
{
"uuid": "8d86661d-985d-4878-a8f5-69723acfa364",
"name": "Domain Owner"
}
],
"token": "CLOUD-eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJiNzBmMzMwYS1jO....",
"subject": {
"uuid": "3348037a-9f5d-425e-b593-11e6e7437b74",
"name": "DrivrUser",
"type": "USER"
}
},
{
"uuid": "c606707f-198f-46f5-883e-68794ce81159",
"createdAt": "2025-05-12T14:50:31.670217",
"updatedAt": "2025-05-12T14:50:31.894824",
"status": "ACTIVATED",
"expiresAt": "2025-05-13T14:50:31.672467",
"notBefore": "2025-05-12T14:50:31+00:00",
"systemUuid": "792b6149-1daa-488f-b07a-f684503b0586",
"roles": [
{
"uuid": "8d86661d-985d-4878-a8f5-69723acfa364",
"name": "Domain Owner"
}
],
"token": "CLOUD-eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjNjA2NzA3Zi0xOThmLTQ2ZjUtODgzZS0....",
"subject": {
"uuid": "3348037a-9f5d-425e-b593-11e6e7437b74",
"name": "DrivrUser",
"type": "USER"
}
}
]
Please note: Use the JWKS endpoint or information from the JWK topic above to validate tokens securely