For the publisher/subscriber clients to connect to the broker, they have to present a token in their CONNECT messages.
The system consists of four entities:
- The client authorization server: The client authorization server will acquire a token on behalf of the device. Currently emulated with Curl.
- Client: Clients publish and subscribe to topics with the MQTT broker. mosquitto_pub and mosquitto_sub clients are modified as ACE clients.
- The MQTT broker: The MQTT broker is the default Mosquitto broker. It uses an extended mosquitto_auth_plugin to connect to the ACE backend.
- The Authorization Server: The Authorization server is implemented in Express/Node.js. The database is in MongoDB and stores client registrations, tokens, and policies.
Supports dynamic client registration according to IETF RFC 7591 Dynamic Client Registration and, to a certain extent, the experimental IETF RFC 7592 Dynamic Client Registration Management.
Used by the CAS to request Proof of Possession tokens. These tokens must be generated by the AS and consumed by the RS. A Proof of Possession token is an access token bound to a cryptographic key. RS uses the PoP key to authenticate the client. Access tokens are opaque to the client.
The introspection interface is used by the MQTT Broker/RS to pass a token for introspection. This is done using an extension of the Mosquitto auth plugin. Access tokens are currently reference tokens. In the future, it is planned to support self-contained tokens. If the access token is self-contained, then the RS may not need to introspect. On the other hand, RS may still want to introspect a self-contained token if the authorization decisions are very dynamic. Access tokens that are not introspected may need to be revoked by the authorisation server (no standard specification supports this).
Topics are resources. Wildcard topics are not supported at the moment.
The resource owner is the entity that can authoritatively talk about the resource. In our system, resource owner is the topic owner.
A policy binds (client_id) to a (resource_name) owned by (owner_name). The policy supports two types of permissions:“pub” and “sub”.
Example policy:
{
"resource_name" : "resource name",
"owner_name" : "owner name",
"client_id" : "client id",
“scopes” : [“pub”, “sub”],
“policy_expires_at”: "data"
}
More complex policies can be supported, for instance, by XACML, and are left for future work.
We use tokens by reference. An example token kept by AS:
{
"profile": "mqtt_tls",
"token_value_hash": "token value hash" ,
"token_type" : "pop",
"iss": "Nominet",
"sub": "client_id",
"aud": "topic",
"exp": "expiration time",
"scope": "pub",
"cnf": "pop key"
}
Limitations: We currently do not support multiple topics in tokens.
Other ideas for scope
:
- Make scope a special word such as
action_topic
. The acceptable verbs for action are “pub” and “sub”. The topic follows the same model as MQTT, including the wildcards. - Create a Base64 encoding for
[“permission”:”pub”, “topic”:”/topic/sensor1/#”]
and use this string for
scope
.
This system requires the following before authentication/authorization can take place:
- Privacy policies regarding which topics can be published/subscribed to are configured at the Authorisation Server by the Resource Owner. The definitions for topic, resource and resource owner, and policy are presented in the Definitions section.
- Clients and the broker are registered with the AS. For this, AS provides dynamic client registration endpoint.
- Both publisher and subscriber discovered the MQTT broker, and subscriber learned about the topics published by the MQTT broker.
- AS returns tokens to pub/sub clients if RO has a policy for the client. [PASSED].
- AS does not returns tokens to pub/sub clients if RO does not have a policy for the client. [PASSED].
- The pub/sub clients can pass the token to the broker in CONNECT request. [PASSED]
- The broker can use the introspect interface to validate token. [PASSED]
- The broker can deny Publish connections if topic is not covered in token. [PASSED]
- The broker can use stored tokens to check subscribe permissions when a new message to the topic published and denies forwarding messages not covered by topic. [PASSED]
- The broker does not accept expired tokens. [PASSED]
- Digest Algorithm defaults to SHA256.
- The Token is encoded base32 because it is passed as a username to the mosquitto broker, and is not allowed to have the "+" character. (crypto.random function to generate the username may use + character).
- The subscribers are not disconnected immediately at connection time if their token does not match the SUBSCRIBE request. This is because ACL checks are temporarily disabled in the mosquitto broker. But, they are never forwarded the messages published to unauthorised topics.
- Auth plugin (and also ACE) does not support wildcards.
- Does not support multiple topics in a single token.
- Auth plugin does not support curl --cacert option.