Device Identity
This page describes how devices are represented and identified throughout Hono and its APIs.
The main purpose of Hono is to provide a uniform API for applications to interact with devices, regardless of the particular communication protocol the devices natively use. In order to do so, Hono uses a unique logical identifier to refer to each device individually.
Hono does not make any assumptions about the format of a device identifier (or device-id for short). It basically is a string which is defined at the time a device is being provisioned. Once created, the device can be referred to by this identifier when using Hono’s APIs until the device is being removed from the system.
Tenant
Hono supports the logical partitioning of devices into groups called tenants. Each tenant has a unique identifier, a string called the tenant-id, and can be used to provide a logical grouping of devices belonging e.g. to the same application scope or organizational unit. Each device can thus be uniquely identified by the tuple (tenant-id, device-id). This tuple is broadly used throughout Hono’s APIs when addressing a particular device.
Device Registration
Hono components use the Device Registration API to access device registration information. The API defines the assert Registration operation for verifying a device’s registration status.
In many real world scenarios there will already be a component in place which keeps track of devices and which supports the particular provisioning process being used to bring devices into life. In such cases it makes sense to simply implement the Device Registration API as a facade on top of the existing component.
In addition to that, Hono defines a Device Registry Management API, which can be implemented to take advantage of standardized operations for managing devices and credentials. This API is optional because Hono components do not require it during runtime.
Hono comes with a MongoDB and a JDBC based implementation of both APIs. The JDBC based implementation supports PostgreSQL and H2 out of the box. It can also be configured with an H2 based in-memory database which can be used for demonstration or testing purposes.
Device Authentication
Devices connect to protocol adapters in order to publish telemetry data or events. Downstream applications consuming this data often take particular actions based on the content of the messages. Such actions may include simply updating some statistics, e.g. tracking the average room temperature, but may also trigger more serious activities like shutting down a power plant. It is therefore important that applications can rely on the fact that the messages they process have in fact been produced by the device indicated by a message’s source address.
Hono relies on protocol adapters to establish a device’s identity before it is allowed to publish downstream data or receive commands. Conceptually, Hono distinguishes between two identities
- an identity associated with the authentication credentials (termed the authentication identity or auth-id), and
- an identity to act as (the device identity or device-id).
A device therefore presents an auth-id as part of its credentials during the authentication process which is then resolved to a device identity by the protocol adapter on successful verification of the credentials.
In order to support the protocol adapters in the process of verifying credentials presented by a device, the Credentials API provides means to look up secrets on record for the device and use this information to verify the credentials.
The Credentials API supports registration of multiple sets of credentials for each device. A set of credentials consists of an auth-id and some sort of secret information. The particular type of secret determines the kind of information kept. Please refer to the Standard Credential Types defined in the Credentials API for details. Based on this approach, a device may be authenticated using different types of secrets, e.g. a hashed password or a client certificate, depending on the capabilities of the device and/or protocol adapter.
Once the protocol adapter has resolved the device-id for a device, it uses this identity when referring to the device in all subsequent API invocations, e.g. when forwarding telemetry messages downstream.
Every device connecting to Hono needs to be registered in the scope of a single tenant as described above already. The Device Registration and Credentials APIs therefore require a tenant identifier to be passed in to their operations. Consequently, the first step a protocol adapter needs to take when authenticating a device is determining the tenant that the device belongs to.
The means used by a device to indicate the tenant that it belongs to vary according to the type of credentials and authentication mechanism being used.
Username/Password based Authentication
The MQTT, HTTP and AMQP protocol adapters support authentication of devices with a username/password based mechanism. In this case, a protocol adapter verifies that the password presented by the device during connection establishment matches the password that is on record for the device in the device registry.
During connection establishment the device presents a username and a password to the protocol adapter.
For example, a device that belongs to tenant example-tenant
and for which
hashed-password credentials with an auth-id of device-1
have been registered, would present a username of device-1@example-tenant
when authenticating to a protocol adapter.
The protocol adapter then extracts the tenant identifier from the username and invokes the Credentials API’s get Credentials operation in order to retrieve the hashed-password type credentials that are on record for the device.
Pre-Shared Key based Authentication
The CoAP protocol adapter supports authentication of devices using a pre-shared key (PSK) as part of a DTLS handshake. In this case, the protocol adapter verifies that the PSK used by the device to generate the DTLS session’s pre-master secret is the same as the key contained in the credentials that are on record for the device in the device registry.
During the DTLS handshake the device provides a psk_identity to the protocol adapter. For example, a device that
belongs to tenant example-tenant
and for which psk credentials
with an auth-id of device-1
have been registered, would present a PSK identity of device-1@example-tenant
during
the DTLS handshake.
The protocol adapter then extracts the tenant identifier from the PSK identity and invokes the Credentials API’s get Credentials operation in order to retrieve the psk type credentials that are on record for the device. The psk contained in the credentials are then used by the protocol adapter to generate the pre-master secret of the DTLS session being negotiated with the client. If both, the device and the protocol adapter use the same key for doing so, the DTLS handshake will succeed and the device has been authenticated successfully.
Client Certificate based Authentication
Devices can also use an X.509 (client) certificate to authenticate to protocol adapters. In this case, the protocol adapter tries to verify that a valid chain of certificates can be established starting with the client certificate presented by the device up to one of the trusted root certificates configured for the device’s tenant.
During connection establishment with the device, the protocol adapter tries to determine the tenant to which the device belongs and retrieve the tenant’s configuration information using the Tenant API. The adapter then uses the trust anchors that have been configured for the tenant to verify the client certificate.
The protocol adapter tries to look up the device’s tenant configuration using the Tenant API’s
get Tenant Information operation.
The adapter first invokes the operation using the issuer DN from the device’s client certificate.
If that fails and if the device has included the
Server Name Indication extension during the TLS handshake,
the adapter extracts the first label of the first host name conveyed in the SNI extension and invokes the get Tenant
Information operation with the extracted value as the tenant identifier. For example, a host name of
my-tenant.hono.eclipseprojects.io
would result in a tenant identifier of my-tenant
being used in the look-up.
Labels in host names may only consist of letters, digits and hyphens. In order to be able to refer to tenants which have an identifier that consists of other characters as well, the Device Registry Management API supports registering an alias for a tenant which can be used as an alternate identifier when looking up tenant configuration information.
Based on that, a tenant with identifier unsupported_id
that has been registered using alias my-tenant
,
can be referred to by a device by means of including a host name like my-tenant.hono.eclipseprojects.io
in the SNI
extension.
After having verified the client certificate using the trust anchor(s), the protocol adapter extracts the client certificate’s subject DN and invokes the Credentials API’s get Credentials operation in order to retrieve the x509-cert type credentials that are on record for the device.
JSON Web Token based Authentication
The MQTT protocol adapter supports authentication of devices with a JSON Web Token (JWT) based mechanism. In this case, the protocol adapter verifies the JWT by using the public key that is on record for the device in the device registry. Further more does the protocol adapter check if the JWT is valid. To be valid the JWT has to provide the following information in its header and payload.
The JWT header has to provide two fields that indicate the type of token (typ
) and the signing algorithm (alg
).
Both fields are mandatory and the type has to be JWT
. For the signing algorithm RS256
, PS256
, ES256
and their
respective stronger variants are supported. The algorithm specified in the header must match at least one of the
raw public key type credentials registered for the device.
The JWT payload must at least contain the claims iat
(“issued at”) and exp
(“expiration time”) with values provided
in Unix time. The iat
claim marks the timestamp the token was created at
and will also represent the start of its validity period. It must not be too far in the past or the future (allowing 10
minutes for skew). The nbf
(“not before”) claim is therefore not required and will be ignored. The exp
claim
signifies the point in time after which the token becomes invalid. The lifetime of the token must be at most 24 hours
plus skew.
During connection establishment the device presents a client identifier, a username and a password to the protocol adapter. The JWT has to be provided in the password field. The username will be ignored; however, some MQTT client libraries will not send the password unless the username is specified. There are two ways the device can provide the information about its tenant and authentication identifier:
- Either as claims inside the JWT payload, in which case the tenant-id and auth-id must be provided in the
iss
(“issuer”) andsub
(“subject”) claims, respectively, and theaud
(“audience”) claim must contain “hono-adapter” - or inside the client identifier, in which case the client identifier must have the following format:
*/tenant-id/[^/]*/auth-id. For example, a device that belongs to tenant
example-tenant
and for which rpk (raw public key) credentials with an auth-id ofdevice-1
have been registered, would present a client identifier oftenants/example-tenant/devices/device-1
when authenticating to the protocol adapter.
The protocol adapter then extracts the tenant identifier and invokes the Credentials API’s get Credentials operation in order to retrieve the rpk (raw public key) type credentials that are on record for the device. The key contained in the credentials is then used by the protocol adapter to verify the JWT provided by the client. If both, the JWT and the key originate from the same private key and the JWT’s header and claims are valid, than the device will be authenticated successfully.