Skip to content

Tokens

External API clients need to present tokens to the DSH in order to authenticate, and to receive the appropriate permissions on MQTT topics in public DSH streams:

  • The API Client Authentication Service needs an API key to request a REST token from the DSH.
  • An API client needs a REST token to request an MQTT token from the DSH.
  • An API client needs an MQTT token to connect to the Messaging API.
  • Each token can contain claims that restrict what the bearer of the token can do.

Tip

See Authentication mechanism for more information.

REST token

The REST token is a JSON Web Token (JWT), which contains a set of REST claims. These claims describe the following:

  • Which other REST APIs the bearer of the token can connect to.
  • Which actions the bearer of the token can execute on those REST APIs.

Requesting a REST token

You can request a REST token from the DSH via a POST request:

  • Endpoint: /auth/v0/token on your platform. The full URL has the following form: https://api.<your-platform>.kpn-dsh.com/auth/v0/token.
  • HTTP method: POST
  • Authentication: apikey in the HTTP header of the request. You receive the API key from your platform administrator.
  • Success return: HTTP 200 OK, with the REST token in the body
  • Failure return: Any other HTTP status code

The body of your request is a JSON document with the following informal schema:

{
    "tenant": string,
    "exp": long,
    "claims": {string: object}
}
Key Description
tenant
  • Required key
  • This is the ID of your DSH tenant, which is associated with the API key used in the POST request.
  • You receive the correct value from your platform administrator.
exp
  • Optional key
  • This key defines the expiration time of the REST token as a UNIX timestamp (seconds since midnight of 1 January, 1970).
  • The DSH applies a maximum token lifetime of 30 days. The DSH replaces expiration times further in the future with this maximum.
  • If you don't define an expiration time, the DSH applies the default maximum of 30 days.
claims
  • Optional key
  • This key contains restrictions that apply when a client uses the REST token to request an MQTT token. It consist of a collection of string-object pairs:
    • The string specifies the API endpoint that the restrictions apply to. In this case, the string is datastreams/v0/mqtt/token. Note that these endpoints are always strings without a leading slash.
    • The object specifies the restrictions on MQTT tokens that are requested via that endpoint.
  • If you don't specify any claims, then the REST token defaults to the access rights as defined in the MQTT ACLs and Kafka ACLs.
  • If you do specify claims, then always include datastreams/v0/mqtt/token. If this endpoint isn't present in the claims, then clients can't request MQTT tokens.
  • See Claims key for more information.

The example below just uses the defaults, which results in a REST token with full access rights and an expiration time of 30 days:

{
    "tenant": "tenant-a"
}

The example below has specific claims, which is highly recommended. This REST token can only be used to request an MQTT token that allows the client ‘just-this-thermostat’ to subscribe to the MQTT topic house/kitchen/sensor in the public DSH stream ‘temperature’:

{
    "tenant": "tenant-a",
    "exp": 1498942700,
    "claims": {
        "datastreams/v0/mqtt/token": {
            "id": "just-this-thermostat",
            "exp": 1498122712,
            "tenant": "tenant-a",
            "claims": [
                        { "action": "subscribe",
                        "resource": {
                                "type": "topic",
                                "prefix": "/tt",
                                "stream": "temperature",
                                "topic": "house/kitchen/sensor"
                        }
                        }
                    ]
            }
    }
}

Contents of REST token

The REST token consists of a header, body, and signature, separated by a . character. The body of the token is a Base64-encoded JSON document. The example below shows the decoded body of a REST token:

{
   "gen":14,
   "endpoint":"api.<platform-dns-name>.kpn-dsh.com",
   "iss":"snqn8-s13",
   "claims":{"datastreams/v0/mqtt/token": {
            "id": "just-this-thermostat",
            "exp": 1498122712,
            "tenant": "tenant-a",
            "dshclc": { "custom-key": "some-value" }
            "claims": [
                        { "action": "subscribe",
                          "resource": {
                                "type": "topic",
                                "prefix": "/tt",
                                "stream": "temperature",
                                "topic": "house/kitchen/sensor"
                        }
                        }
                      ]
            }

   },
   "exp":1498942700,
   "tenant-id":"tenant-a",
}
Key Description
gen

You can ignore the generation (gen) key because the DSH uses it internally to process the token.

endpoint
  • This is the API server’s DNS name.
  • In the partial mediation process for authentication, an external client can use the endpoint to derive the address for requesting the MQTT token.
iss

The issuer (iss) key identifies the principal that issued the REST token.

claims
  • This is a collection of string-object pairs that define the restrictions on the REST token.
  • The bearer of this token can request an MQTT token that allows the client 'just-this-thermostat' to subscribe to the MQTT topic `house/kitchen/sensor` in the public DSH stream 'temperature'.
  • See Claims key for an overview of all options.
exp

This key defines the expiration time for the token as a UNIX timestamp (seconds since midnight of 1 January, 1970).

tenant-id
  • This key contains the ID of your DSH tenant
  • In the partial mediation process for authentication, an external client can use the tenant ID to request an MQTT token. The tenant ID is required when a client requests an MQTT token.

MQTT token

The MQTT token is a JSON Web Token (JWT), which contains a set of claims. These claims describe the following:

  • Which other REST APIs the bearer of the token can connect to.
  • Which actions the bearer of the token can execute on those REST APIs.

Note

If you connect via HTTP, then The Messaging API also requires the MQTT token. In other words, use the MQTT token to access both MQTT and HTTP.

Requesting an MQTT token

You can request an MQTT token from the DSH via a POST request:

  • Endpoint: datastreams/v0/mqtt/token on your platform. The full URL has the following form: https://api.<your-platform>.kpn-dsh.com/datastreams/v0/mqtt/token.
  • HTTP method: POST
  • Authentication: REST token in the Authorization: Bearer HTTP header of the request.
  • Success return: HTTP 200 OK, with the MQTT token in the body
  • Failure return: Any other HTTP status code

The body of your request is a JSON document with the following informal schema:

{
    "tenant": string,
    "id": string,
    "exp": long, 
    "claims": object, 
    "dshclc": object
}
Key Description
tenant
  • Required key
  • This is the ID of your DSH tenant, which is associated with the API key used in the request of the REST token.
id
  • Required key, which can be restricted by the "id" key in the claims of the REST token.
  • This the MQTT client ID that the client provides when it connects to the MQTT broker. It must have the following format:
    • It has a maximum of 64 characters.
    • It can only contain alphanumeric characters (a–z, A–Z, 0–9), and the at sign (@), hyphen (-), underscore (_), period (.) or colon (:).
  • The client ID must be unique across all connections to the DSH for the tenant mentioned in the tenant field. In other words, don't use one client ID for multiple clients, and don't request multiple overlapping MQTT tokens for one single client. See Client ID for more information.
exp
  • Optional key, which can be restricted by the "exp" and "relexp" keys in the claims of the REST token.
  • This field defines the expiration time of the MQTT token as a UNIX timestamp (seconds since midnight of 1 January, 1970).
  • The DSH applies a maximum token lifetime of 7 days. The DSH replaces expiration times further in the future with this maximum.
  • If you don't define an expiration time, the DSH applies the default maximum period of 7 days.
  • Many factors have an effect on the expiration time of the MQTT token. It's the minimum of these options:
    • The platform-defined maximum expiration time (7 days from now).
    • The absolute expiration time exp in the claims of the REST token.
    • Now + the relative expiration time relexp in the claims of the REST token, if it's specified.
    • The expiration time in the MQTT token request.
claims
  • Optional key, which can be restricted by the deepest "claims" key in the REST token.
  • This key contains restrictions that apply when a client uses the MQTT token to access an Messaging API. It consists of key-value pairs that define the MQTT topics that the token's bearer has access to, and its permission ("Publish" or "Subscribe").
  • If you don't specify any values for this key, then the MQTT token defaults to the claims set in the REST token.
  • See Claims key for more information.
dshclc
  • Optional key
  • dshclc stands for "DSH Client Claims".
  • It's a free-form object that is included literally as the "dshclc" key in the MQTT token.
  • The DSH platform ignores the contents of this field, but an API Client Authentication Service can use the "dshclc" key to communicate some configuration information to the MQTT/HTTP clients.
  • The DSH merges the object specified here with the one in the claims of the REST token, where the latter has priority in case of overlap. For example:
    • The REST token contains the object {“a”: 1, “b”: 2} for the "dshclc" key.
    • The MQTT token request sets the value to {“a”: 666, “c”: 3}.
    • The "dshclc" field in the returned MQTT token will be {“a”: 1, “b”: 2, “c”: 3}.

The example below requests an MQTT token without additional restrictions:

{
    "tenant": "tenant-a",
    "id": "just-this-thermostat"
}

The example below requests an MQTT token that lets the client ‘just-this-thermostat’ subscribe to 1 MQTT topic only, namely the topic house/kitchen/temperature of the public DSH stream ‘temperature’.

{ 
    "tenant": "tenant-a",
    "id": "just-this-thermostat",
    "claims": [
        {   "action": "subscribe",
            "resource": {
                "type": "topic",
                "prefix": "/tt",
                "stream": "temperature",
                "topic": "house/kitchen/sensor"
            }
        }
    ]
}

Contents of MQTT token

The MQTT token consists of a header, body, and signature, separated by a . character. The body of the token is a Base64-encoded JSON document. The example below shows the decoded body of an MQTT token:

{
  "iss": "0",
  "gen": 7,
  "exp": 1735115547,
  "iat": 1734514347,
  "endpoint": "mqtt.<platform-dns-name>.kpn-dsh.com",
  "ports": {
    "mqtts": [
      8883
    ],
    "mqttwss": [
      443,
      8443
    ]
  },
  "tenant-id": "tenant-a",
  "client-id": "just-this-thermostat",
  "claims": [
        {   "action": "subscribe",
            "resource": {
                "type": "topic",
                "prefix": "/tt",
                "stream": "temperature",
                "topic": "house/kitchen/sensor"
            }
        }
  ]
 "dshclc": {
    "custom-key": "some-value"
   }
}
Key Description
iss

The issuer (iss) key identifies the principal that issued the MQTT token.

gen

You can ignore the generation (gen) key because the DSH uses it internally to process the token.

exp

This key defines the expiration time for the token as a UNIX timestamp (seconds since midnight of 1 January, 1970).

iat

This key defines the time that the token was issued at (iat), as a UNIX timestamp (seconds since midnight of 1 January, 1970). Use this value to calculate the age of the token.

endpoint
  • This is the DNS name of the Messaging API.
  • An external MQTT client can use the endpoint to derive the address of the Messaging API.
ports

This key specifies the ports that an MQTT client needs to use to connect via MQTT over SSL (mqtts), or via MQTT over WebSockets (mqttwss). See Connecting via MQTT for more information.

tenant-id

This key contains the ID of the DSH tenant.

client-id

This the MQTT client ID that the client provides when it connects to the MQTT broker. The client ID must be unique across all connections to the DSH for the tenant mentioned in the tenant-id field. See Client ID for more information.

claims
  • This is a collection of objects that define the restrictions for the MQTT/HTTP client.
  • This MQTT token allows the client 'just-this-thermostat' to subscribe to the MQTT topic `house/kitchen/sensor` in the public DSH stream 'temperature'.
  • See Claims key for more information.
dshclc
  • Optional key
  • dshclc stands for "DSH Client Claims".
  • It's a free-form object that will be included literally as the "dshclc" key in the MQTT token.
  • The DSH platform ignores the contents of this key, but an API Client Authentication Service can use the "dshclc" key to communicate some configuration information to the MQTT/HTTP clients.

Guidelines

Bear in mind the following guidelines when you request an MQTT token.

  • Request tokens with specialized claims. It’s recommended to set restrictions in an MQTT token request:
    • If a token is compromised, it can’t be used for more than its intended use.
    • A token with restricted permissions is smaller and saves bandwidth.
  • Request tokens with a limited lifetime:
    • The default lifetime of an MQTT token is 7 days, which is long.
    • A shorter lifetime prevents abuse, for example a lifetime of 5 minutes.
    • A token must only be valid at connection time. As a consequence, a live connection won’t break when the token expires.
  • Use stable client IDs:
    • Use stable client IDs for external clients, instead of discard client IDs.
    • This makes it easier to attribute published messages to concrete clients.
    • It’s recommended to pass the client ID from the MQTT token as the client ID when establishing the connection with the Messaging API. See Client ID for more information.
  • Use the most recent MQTT token:
    • It’s possible to request multiple tokens for the same client ID, with an overlap in the lifetime.
    • As long as the tokens are valid, external clients can use them to connect to the platform.
    • However, the external clients can’t connect at the same time, because the client ID must be unique.
    • If a newer MQTT token for a specific client ID is used to connect to the Messaging API, then the platform invalidates the older requested tokens for that client ID.

Permissions

The permissions for MQTT topics are managed at 3 different levels:

  • In the MQTT ACL, which specifies the set of permissions that a Messaging API has for MQTT topics in public DSH streams.
  • In the claims of the REST token, which can add more restrictions for an API client that requests an MQTT token.
  • In the claims of the MQTT token, which can add even more restrictions for an API client that wants to connect to the Messaging API.

Topic patterns

At the different levels, one can specify the “publish” or “subscribe” permissions for specific MQTT topics in a DSH stream. These permissions consist of two parts:

  1. The action, namely “publish” or “subscribe”
  2. A topic pattern that defines the MQTT topics that the action applies to

Topic patterns can contain the following special characters:

  • A forward slash / to separate topic levels
  • A plus sign + as a single-level wildcard
  • A number sign # as a multi-level wildcard

Tip

See Topic Names and Topic Filters in the MQTT specification for more information.

The MQTT specification allows a topic filter (with wildcards) for the “subscribe” action, but it prohibits wildcards for the “publish” action. This leads to separate rules for the two actions when evaluating MQTT topics against topic patterns.

For the “publish” action, a specific MQTT topic matches the topic pattern if the following is true:

  • The MQTT topic starts with <topic-prefix>/<DSH-stream-name>/. Because the topic prefix is always “/tt”, this results in /tt/<DSH-stream-name>/.
  • After the prefix, the MQTT topic contains the following:
    • A topic level for each corresponding + wildcard in the topic pattern
    • 0 or more topic levels for any # wildcard in the topic pattern
    • The identical topic level for each level in the topic pattern that isn’t a wildcard

For the “subscribe” action, a specific MQTT topic matches the topic pattern if the following is true:

  • The MQTT topic starts with <topic-prefix>/<DSH-stream-name>/. Because the topic prefix is always “/tt”, this results in /tt/<DSH-stream-name>/.
  • After the prefix, the MQTT topic contains the following:
    • A topic level for each corresponding + wildcard in the topic pattern
    • 0 or more topic levels or + wildcards, and 0 or 1 # wildcard for any # wildcard in the topic pattern
    • The identical topic level for each level in the topic pattern that isn’t a wildcard

The table below gives several examples of topics that match and that don’t match for the topic prefix /tt, the DSH stream temperature and the topic pattern z/+/+/+/#:

Action Match No match
Publish
  • /tt/temperature/z/a/b/c
  • /tt/temperature/z/d/e/f/g/h
  • /tt/temperature/z/a/b
  • /tt/temperature/x/a/b/c
  • /tt/temperature/z/d/e/f/+/h
  • /tt/temperature/z/d/e/f/#
Subscribe
  • /tt/temperature/z/a/b/c
  • /tt/temperature/z/d/e/f/g/h
  • /tt/temperature/z/d/e/f/+/h
  • /tt/temperature/z/d/e/f/#
  • /tt/temperature/x/a/b/c
  • /tt/temperature/z/a/b/#

Claims key

An API client can request more restrictions for the REST token and the MQTT token, using the “claims” key. These restrictions can contain topic patterns, but also a client ID, expiration time, etc. If the REST token and the MQTT token don’t contain a “claims” key, then no further restictions apply, and the API client receives the permissions as set in the MQTT ACL of the API in question.

The sections below list the keys that you can use when you request specific claims for a REST token or an MQTT token.

REST token request

The “claims” key in the request for a REST token specifies limitations on the MQTT token. It has the following informal schema:


"claims":{string: {
            "id": string,
            "exp": long,
            "relexp": long,
            "tenant": string,
            "dshclc": object,
            "claims": [
                        { "action": "subscribe"|"publish",
                          "resource": {
                                "type": "topic",
                                "prefix": "/tt",
                                "stream": string,
                                "topic": string
                        }
                        }
                      ]
            }
   }

Key Description
claims
  • The top-level "claims" key consists of a collection of string-object pairs:
    • The string specifies the API endpoint that the restrictions apply to. In this case, the string is always datastreams/v0/mqtt/token. Note that these endpoints are always strings without a leading slash.
    • The object specifies the restrictions on MQTT tokens that are requested via that endpoint.
  • If you specify restrictions in the "claims" key, then you must always include the datastreams/v0/mqtt/token endpoint. If it's absent, the API client that receives the REST token won't be able to request an MQTT token.
id

This key specifies the ID of the MQTT/HTTP client that connects to the Messaging API. The API client won't be able to connect to the API if its client ID doesn't match the value in this key.

A single REST token can't contain restrictions for multiple specific MQTT client IDs. If you add a restriction for the MQTT client ID, then you can use the 1 single REST token to request MQTT tokens for 1 single MQTT client only.

exp

This key defines the absolute expiration time of the MQTT token, as a UNIX timestamp (seconds since midnight of 1 January, 1970).

relexp

This key defines the relative expiration time of the MQTT token, in seconds. It reflects the maximum lifetime of the MQTT token. A value of "300" results in a maximum lifetime of 5 minutes.

tenant

This key contains the tenant ID for the Messaging API in question. It specifies that the API client can only request an MQTT token for the tenant ID in question.

dshclc
  • dshclc stands for "DSH Client Claims".
  • It's a free-form object that will be included literally as the "dshclc" key in the MQTT token.
  • The DSH platform ignores the contents of this key, but an API Client Authentication Service can use the "dshclc" key to communicate some configuration information to the MQTT/HTTP clients.
claims

The lower-level "claims" key is a collection of objects that reflect permissions on MQTT topics. These objects contain the following keys:

  • action: the action, either "publish" or "subscribe"
  • resource: the MQTT topic in question, defined using the keys below:
    • type: The type is always "topic".
    • prefix: The prefix of MQTT topics in public DSH streams is always "/tt".
    • stream: The name of the public DSH stream.
    • topic: The MQTT topic that the permission applies to. You can use a topic pattern here, see Topic patterns for more information.

MQTT token request

The claims in the request for an MQTT token limit the MQTT topics that the MQTT/HTTP client can access. They have the following informal schema:


"claims": [
        {   "action": "subscribe"|"publish",
            "resource": {
                "type": "topic",
                "prefix": "/tt",
                "stream": string,
                "topic": string
            }
        }
    ]

Key Description
action

The action, either "publish" or "subscribe".

resource

The MQTT topic in question, defined using the keys below:

  • type: The type is always "topic".
  • prefix: The prefix of MQTT topics in public DSH streams is always "/tt".
  • stream: The name of the public DSH stream.
  • topic: The MQTT topic that the permission applies to. You can use a topic pattern here, see Topic patterns for more information.