Subject: [Ace] Using OAuth and ACE-OAuth with MQTT

From: Jim Schaad <[email-masked]>
Date: Tue, 10 Mar 2020 16:10:29 -0700

Hannes,

This is going to be a long email and I hope that I do not get too many
things wrong in the process of getting it written up.

So the question that you raised is can the current MQTT profile use the
existing OAuth and ACE-OAuth protocols.  My assertion is that the answer is
yes and I will walk through the two different protocols in order to
demonstrate this.  For simplicilty I am only going to deal with one of the
TLS configurations that the MQTT profile envisions.

For TLS authentication, the server is to be validated by using an X.509
certificate and there is to be a method for the client to be able to
associate the identifier in the certificate with the OAuth token request.
This I assume is a well understood problem in the OAuth WG.  The client is
not authenticated to the server by TLS, this is deferred to MQTT protocol.
When using ACE-OAuth, this is generally going to be tied through the
audience field in some method.

The format of the scope field is defined in the MQTT document and the AS
will need to be able to parse that field and do the proper enforcement.  I
think this different than what a normal OAuth AS does where the scope is a
single value rather than a composite value.

The key which is placed in the token is going to be an asymmetric signing
key.  This is the standard thing for OAuth.  At some point in the future it
might be nice to allow for symmetric keys to be sent out, but for now the
ACE-OAuth is sufficient for dealing with that case.

Using OAuth

The client makes a request to an OAuth authorization server for a token.
The grant_type for the token is going to be "client_credentials", the scope
is a text string defined by the MQTT profile document.  Authorization is
needed for the connection.  My assumption is that this is now normally done
by the use of HTTPS rather than something like basic authentication.

**************************************

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&
scope=publish_topic1/topic2%2Epublish_topic3/+/stats%2Esubscribe_topic3/#

**************************************

The AS response with a standard message

**************************************

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8

{
 "access_token":"..... JWT token ......",
 "token_type":"bearer",
 "expires_in": 3600,
}

**************************************

The client now connects to the MQTT server using TLS, validating the
certificate of the server against it's trust anchors and the "known" name of
the MQTT server.

The client now sends an MQTT CONNECT message to the server passing the JWT
token in as part of the Authentication Data (section 2.2.4 of the MQTT
document).

****************************************************************

Using ACE-OAuth

*******

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/ace+json

{
  "scope": "publish_topic1/topic2 publish_topic3/+/stats
subscribe_topic3/#",
  "audience": "mqtts://mqtt.example.com"
}

******

For ACE-OAuth, the default value of grant_type is client_credentials so that
parameter is omitted.

*****

HTTP/1.1 200 OK
Content-Type: application/ace+json

{
 "access_token":"..... JWT token ......",
 "expires_in": 3600,
 "ace_profile" : "mqtt_tls"
}

As can be seen, there are only minimal differences between what is sent out
between the Vanilla and the ACE version of OAuth.  In both cases it is
assumed that the client is going to know which asymmetric key is going to be
used.  There are a couple of differences however:

1.  I have used the value of "bearer" for "token_type" in OAuth because that
seemed to me to be the one which mapped to the usage in a better manner.
The OAuth-ACE framework however registers the value of "PoP" and specifies
it as the default value.  It may make more sense to use that value in the
OAuth case as well.

2.  In the ACE-OAuth case, we can return a key to the user and thus be able
to do symmetric keys as well.  If you are already doing TLS and validating
signatures that way I would expect that this is not going to be a common
case.

3.  In the ACE-OAuth case, it is possible to return information about the
TLS key that the server would be using.  This would allow for situations
were the MQTT TLS connection is not doing certificate chain validation, but
instead using information passed in the rs_cnf field to validate either the
public key or the certificate directly.

---

From: Hannes Tschofenig <[email-masked]>
Date: Wed, 11 Mar 2020 07:34:15 +0000

Hi Jim,

I believe you are right that the functionality is supported. In retrospect it is good that Ludwig just imported the key transport necessary functionality with draft-ietf-ace-oauth-params-12. Hence, you can do pretty everything defined in draft-ietf-oauth-pop-key-distribution with the ACE-OAuth framework. Only one piece is missing in the IANA consideration section, namely the registration of "pop" in the "OAuth Access Token Types" registry. That needs to be added. Not a big deal though. I will send text to Ludwig.

I am happy.

Ciao
Hannes

PS: I am not sure whether the authentication mechanisms defined in draft-ietf-ace-mqtt-tls-profile are actually sound. Maybe I should do a formal analysis.

-----Original Message-----
From: Jim Schaad <[email-masked]>
Sent: Wednesday, March 11, 2020 12:10 AM
To: Hannes Tschofenig <[email-masked]>
Cc: 'Cigdem Sengul' <[email-masked]>; 'Ace Wg' <[email-masked]>
Subject: Using OAuth and ACE-OAuth with MQTT

Hannes,

This is going to be a long email and I hope that I do not get too many things wrong in the process of getting it written up.

So the question that you raised is can the current MQTT profile use the existing OAuth and ACE-OAuth protocols.  My assertion is that the answer is yes and I will walk through the two different protocols in order to demonstrate this.  For simplicilty I am only going to deal with one of the TLS configurations that the MQTT profile envisions.

For TLS authentication, the server is to be validated by using an X.509 certificate and there is to be a method for the client to be able to associate the identifier in the certificate with the OAuth token request.
This I assume is a well understood problem in the OAuth WG.  The client is not authenticated to the server by TLS, this is deferred to MQTT protocol.
When using ACE-OAuth, this is generally going to be tied through the audience field in some method.

The format of the scope field is defined in the MQTT document and the AS will need to be able to parse that field and do the proper enforcement.  I think this different than what a normal OAuth AS does where the scope is a single value rather than a composite value.

The key which is placed in the token is going to be an asymmetric signing key.  This is the standard thing for OAuth.  At some point in the future it might be nice to allow for symmetric keys to be sent out, but for now the ACE-OAuth is sufficient for dealing with that case.

Using OAuth

The client makes a request to an OAuth authorization server for a token.
The grant_type for the token is going to be "client_credentials", the scope is a text string defined by the MQTT profile document.  Authorization is needed for the connection.  My assumption is that this is now normally done by the use of HTTPS rather than something like basic authentication.

POST /token HTTP/1.1
Host: server.example.com

HTTP/1.1 200 OK

{
 "access_token":"..... JWT token ......",  "token_type":"bearer",
 "expires_in": 3600,
}

The client now connects to the MQTT server using TLS, validating the certificate of the server against it's trust anchors and the "known" name of the MQTT server.

The client now sends an MQTT CONNECT message to the server passing the JWT token in as part of the Authentication Data (section 2.2.4 of the MQTT document).

Using ACE-OAuth

*******

POST /token HTTP/1.1
Host: server.example.com

{
  "scope": "publish_topic1/topic2 publish_topic3/+/stats subscribe_topic3/#",
  "audience": "mqtts://mqtt.example.com"
}

******

For ACE-OAuth, the default value of grant_type is client_credentials so that parameter is omitted.

*****

HTTP/1.1 200 OK

{

As can be seen, there are only minimal differences between what is sent out between the Vanilla and the ACE version of OAuth.  In both cases it is assumed that the client is going to know which asymmetric key is going to be used.  There are a couple of differences however:

1.  I have used the value of "bearer" for "token_type" in OAuth because that seemed to me to be the one which mapped to the usage in a better manner.
The OAuth-ACE framework however registers the value of "PoP" and specifies it as the default value.  It may make more sense to use that value in the OAuth case as well.

2.  In the ACE-OAuth case, we can return a key to the user and thus be able to do symmetric keys as well.  If you are already doing TLS and validating signatures that way I would expect that this is not going to be a common case.

3.  In the ACE-OAuth case, it is possible to return information about the TLS key that the server would be using.  This would allow for situations were the MQTT TLS connection is not doing certificate chain validation, but instead using information passed in the rs_cnf field to validate either the public key or the certificate directly.

IMPORTANT NOTICE: The contents of this email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please notify the sender immediately and do not disclose the contents to any other person, use it for any purpose, or store or copy the information in any medium. Thank you.

---

From: Hannes Tschofenig <[email-masked]>
Date: Tue, 17 Mar 2020 11:37:39 +0000

Hi Jim, Hi Ludwig,

I created a PR at https://github.com/hannestschofenig/ace-oauth-params/pull/1

I wasn't quite sure how to set two registry values, namely (a) Additional Token Endpoint Response Parameters and (b) HTTP Authentication Scheme(s).
For (a) I used "none" and for (b) I used "Bearer".

Ciao
Hannes

-----Original Message-----
From: Hannes Tschofenig
Sent: Wednesday, March 11, 2020 8:34 AM
To: Jim Schaad <[email-masked]>
Cc: 'Cigdem Sengul' <[email-masked]>; 'Ace Wg' <[email-masked]>
Subject: RE: Using OAuth and ACE-OAuth with MQTT

Hi Jim,

I am happy.

Ciao
Hannes

-----Original Message-----
From: Jim Schaad <[email-masked]>
Sent: Wednesday, March 11, 2020 12:10 AM
To: Hannes Tschofenig <[email-masked]>
Cc: 'Cigdem Sengul' <[email-masked]>; 'Ace Wg' <[email-masked]>
Subject: Using OAuth and ACE-OAuth with MQTT

Hannes,

Using OAuth

POST /token HTTP/1.1
Host: server.example.com

HTTP/1.1 200 OK

{

Using ACE-OAuth

*******

POST /token HTTP/1.1
Host: server.example.com

{

******

*****

HTTP/1.1 200 OK

{

---

From: Seitz Ludwig <[email-masked]>
Date: Tue, 17 Mar 2020 11:41:02 +0000

I'm sorry if I'm being daft here, but what is the difference to 
https://tools.ietf.org/html/draft-ietf-ace-oauth-authz-33#section-8.5  ?

/Ludwig

-----Original Message-----
From: Hannes Tschofenig <[email-masked]> 
Sent: den 17 mars 2020 12:38
To: Jim Schaad <[email-masked]>; Seitz Ludwig <[email-masked]>
Cc: 'Cigdem Sengul' <[email-masked]>; 'Ace Wg' <[email-masked]>
Subject: RE: Using OAuth and ACE-OAuth with MQTT

Hi Jim, Hi Ludwig,

Ciao
Hannes

-----Original Message-----
From: Hannes Tschofenig
Sent: Wednesday, March 11, 2020 8:34 AM
To: Jim Schaad <[email-masked]>
Cc: 'Cigdem Sengul' <[email-masked]>; 'Ace Wg' <[email-masked]>
Subject: RE: Using OAuth and ACE-OAuth with MQTT

Hi Jim,

I am happy.

Ciao
Hannes

-----Original Message-----
From: Jim Schaad <[email-masked]>
Sent: Wednesday, March 11, 2020 12:10 AM
To: Hannes Tschofenig <[email-masked]>
Cc: 'Cigdem Sengul' <[email-masked]>; 'Ace Wg' <[email-masked]>
Subject: Using OAuth and ACE-OAuth with MQTT

Hannes,

Using OAuth

POST /token HTTP/1.1
Host: server.example.com

HTTP/1.1 200 OK

{

Using ACE-OAuth

*******

POST /token HTTP/1.1
Host: server.example.com

{

******

*****

HTTP/1.1 200 OK

{

---

From: Hannes Tschofenig <[email-masked]>
Date: Tue, 17 Mar 2020 11:50:10 +0000

Ludwig, you are right. I missed that. I was incorrectly looking at draft-ietf-ace-oauth-params-12 where all the parameters are.
I will delete my PR.

Ciao
Hannes

-----Original Message-----
From: Seitz Ludwig <[email-masked]>
Sent: Tuesday, March 17, 2020 12:41 PM
To: Hannes Tschofenig <[email-masked]>; Jim Schaad <[email-masked]>
Cc: 'Cigdem Sengul' <[email-masked]>; 'Ace Wg' <[email-masked]>
Subject: RE: Using OAuth and ACE-OAuth with MQTT

/Ludwig

-----Original Message-----
From: Hannes Tschofenig <[email-masked]>
Sent: den 17 mars 2020 12:38
To: Jim Schaad <[email-masked]>; Seitz Ludwig <[email-masked]>
Cc: 'Cigdem Sengul' <[email-masked]>; 'Ace Wg' <[email-masked]>
Subject: RE: Using OAuth and ACE-OAuth with MQTT

Hi Jim, Hi Ludwig,

Ciao
Hannes

-----Original Message-----
From: Hannes Tschofenig
Sent: Wednesday, March 11, 2020 8:34 AM
To: Jim Schaad <[email-masked]>
Cc: 'Cigdem Sengul' <[email-masked]>; 'Ace Wg' <[email-masked]>
Subject: RE: Using OAuth and ACE-OAuth with MQTT

Hi Jim,

I am happy.

Ciao
Hannes

-----Original Message-----
From: Jim Schaad <[email-masked]>
Sent: Wednesday, March 11, 2020 12:10 AM
To: Hannes Tschofenig <[email-masked]>
Cc: 'Cigdem Sengul' <[email-masked]>; 'Ace Wg' <[email-masked]>
Subject: Using OAuth and ACE-OAuth with MQTT

Hannes,

Using OAuth

POST /token HTTP/1.1
Host: server.example.com

HTTP/1.1 200 OK

{

Using ACE-OAuth

*******

POST /token HTTP/1.1
Host: server.example.com

{

******

*****

HTTP/1.1 200 OK

{