Subject: [GNAP] Signature Methods

From: Justin Richer <[email-masked]>
Date: Tue, 15 Jun 2021 13:49:13 -0400

In GNAP, most requests are signed in some way, or at least bound to a key being presented or referenced with the request. This is true for connections from the client instance to the AS and to the RS, as well as introspection requests from the RS to the AS. GNAP has always sought to be flexible with regard to cryptographic binding mechanisms, but there’s a question as to what should remain defined in the core document. Right now, core has six methods defined. The editors are proposing that we keep at least two and drop two, and the others could either both be kept, both be dropped, or one kept. The rationale for each proposal is discussed below:

Proposed to keep:

- HTTP Method Signatures: general purpose mechanism, being defined in HTTP WG. Can be bound to symmetric and asymmetric keys. Usable for native, web, and SPA clients. Suggested MTI for the AS (but not mandatory to use) for interoperability. Side note, possible use for AS to sign responses (but not explored here yet — that’s another topic).

- Mutual TLS: based on OAuth MTLS, ties the keys at the TLS layer to the application protocol (GNAP). 

Proposed to drop:

- OAuth PoP: expired draft, due to be replaced with new draft based on HTTP Message Signatures.

- OAuth DPoP: only works for asymmetric keys, requires key be presented in the header (duplicating information from GNAP messages). It was never meant to be a general purpose signing mechanism, though the FAPI group in OIDF is considering it as an option in current proposed work. 

This leaves the two JWS based methods, detached and attached. Since attached JWS depends on the detached JWS method to handle body-less requests like GET, DELETE, OPTIONS, etc., if we remove the detached method then we have to remove both. The methods could be pulled to an extension, left in core, or removed entirely. 

The editors would appreciate feedback on this proposal, including specific feedback on the JWS methods from implementors who are targeting them.

 — Justin

---

From: Nicolas Mora <[email-masked]>
Date: Sun, 20 Jun 2021 09:16:13 -0400

Hello,

> - Mutual TLS: based on OAuth MTLS, ties the keys at the TLS layer to the application protocol (GNAP).
[...]
> The editors would appreciate feedback on this proposal, including specific feedback on the JWS methods from implementors who are targeting them.
If I may, I'd like to keep the detached and attached methods in GNAP.

The attached method is easy to understand and implement, you have 
zillions of JOSE implementations in various languages and contexts, and 
from the point of view of the client, the detached method looks like this:

- step 1: build the request as a JSON object
- step 2: serialize a JWS in compact mode using the private key
- step 3: send the request to the AS

This makes it simple to implement on both sides, also, the signing and 
encryption capabilities adds a pretty good security layer to the request.

Also, this methods allows client without a secret or a private key, such 
as the public clients in OAuth2, because one can build an unsigned JWS.

If GNAP only uses HTTP Message Signing and Mutual TLS, it may be harder 
to implement, therefore lead to less implementation and adoption.

I wasn't there at that time but I've read that OAuth1 and SAML had this 
problem, and OAuth2 was made to avoid too much complexity.

/Nicolas

---

From: Justin Richer <[email-masked]>
Date: Mon, 21 Jun 2021 09:51:23 -0400

Hi Nicolas, thanks for the feedback! Some comments below.

> On Jun 20, 2021, at 9:16 AM, Nicolas Mora <[email-masked]> wrote:
> 
> Hello,
> 
> The attached method is easy to understand and implement, you have zillions of JOSE implementations in various languages and contexts, and from the point of view of the client, the detached method looks like this:
> 

The attached method is deceptive like that. While it seems that simple on the surface, there are a couple of major drawbacks to this approach:

- It only works for requests to JSON-based APIs. What about XML, Form, CBOR, or anything else? JWS would still work but you’d need a different encoding for the body.
- It only works when you have a message body, so it only works for POST and PUT in practice. You need a detached method for GET, HEAD, OPTIONS, and DELETE anyway.
- The receiving end needs to be able to handle application/jose instead of application/json. For most application frameworks, this means putting in a filter that translates the incoming JOSE object to a JSON payload that the underlying system can then parse into native objects for the API to consume. While of course it’s possible to do all the parsing by hand inside your handler methods, it’s not a good for adoption if we presume everything will need to be special-cased by hand.

These aspects alone are incredibly limiting for the attached method, but there’s even more than that. You have to replicate parts of the HTTP message inside the JWS somewhere in order to have them covered by the signature. The GNAP definitions currently do this inside the JWS header, but other proposals use the JWS payload itself. This is extra work for the client and leads to error cases that the server needs to explicitly detect by looking for information in multiple places (ie, a signed POST request was sent with a GET).
 
> 
> This makes it simple to implement on both sides, also, the signing and encryption capabilities adds a pretty good security layer to the request.
> 
> Also, this methods allows client without a secret or a private key, such as the public clients in OAuth2, because one can build an unsigned JWS.

Unsigned JWS is explicitly forbidden, as is “alg:none”. If you’re going to send an unsigned request, just send the plain JSON.

For token presentation, GNAP still allows bearer tokens to be requested by the client and granted by the AS.

> 
> If GNAP only uses HTTP Message Signing and Mutual TLS, it may be harder to implement, therefore lead to less implementation and adoption.

Other methods will still be available, but this discussion is about what goes in the core document. The registry will allow for extension of other signing methods, and the core spec will put parameters on what any new signing methods need to cover.

> 
> I wasn't there at that time but I've read that OAuth1 and SAML had this problem, and OAuth2 was made to avoid too much complexity.

The complexity is part of the story, for sure — but OAuth 2 is currently adding higher levels of protection through MTLS, DPoP, and HTTP Signatures, among a bunch of others. It’s really awkward in OAuth 2 because we need to work around an infrastructure that didn’t anticipate things. We :tried: to anticipate them, but it’s still a bit awkward. Avoiding complexity is actually one of the reasons the editors are suggesting dropping the GNAP-specific methods from the core and keeping the general-purpose methods of HTTP Message Signing and MTLS, which will find implementation and use elsewhere. OAuth 1 used a very fiddly custom signature scheme based around URL parameters, and it was really hard to get it right. That scheme also assumed shared secrets, which made it hard to secure properly. 

 — Justin

> 
> /Nicolas
> <OpenPGP_0xFE82139440BD22B9.asc>-- 
> TXAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/txauth

---

From: Nicolas Mora <[email-masked]>
Date: Mon, 21 Jun 2021 15:01:51 -0400

Hello Justin, thanks for your comments,

If I wasn't clear, my point is to keep attached and detached methods in 
the core GNAP protocol, in addition to the other available signatures 
methods mentioned.

Although, DPoP and PoP signatures can be dropped from the core specs, 
their complexity and security levels are covered with other methods.

My objective is to have an easy-to-use signature method in GNAP core, to 
allow more app and services to adopt GNAP.
Although there might have drawbacks in such methods, it would be the 
administrator's responsibility to allow or not some methods with some 
resources and some clients.

> - It only works for requests to JSON-based APIs. What about XML, Form, CBOR, or anything else? JWS would still work but you’d need a different encoding for the body.
You can specify a header typ or cty for that, and state some typ/cty 
values that are acceptable for GNAP requests for example.

> - It only works when you have a message body, so it only works for POST and PUT in practice. You need a detached method for GET, HEAD, OPTIONS, and DELETE anyway.
I concur, and yes, I don't see detached method usable for every use case.

> - The receiving end needs to be able to handle application/jose instead of application/json. For most application frameworks, this means putting in a filter that translates the incoming JOSE object…
That will the responsibility of the client or client library.
I can only speak for myself but I don't see it more difficult to call a 
  parse method with the JWS payload and a JSON library than calling a 
getClaims() method on a JWT.

Also, an advantage of using a JWS is that you can compress its payload. 
The "ZIP: def" header is defined in the JWE RFC only, not the JWS RFC, 
but the JWS RFC doesn't explicitly forbids it.
I didn't even thought of it before I saw it in the smarthealth JWS 
format specification [1]. Now I would like it everywhere! :-)

> These aspects alone are incredibly limiting for the attached method, but there’s even more than that. You have to replicate parts of the HTTP message inside the JWS somewhere in order to have them…
I agree with you, but then I have a question regarding that: why does 
the HTTP parameters must be part of the header or the payload in 
addition to the HTTP request?
I asked myself this question when I read an earlier GNAP specification. 
I assumed the goal is to add entropy and another check for the client to 
make before sending a request, i.e. are you sure you're asking the 
proper question? Isn't is a duplicate from a previous request?

I told myself such parameters (uri and htm) could be replaced by a jti, 
but, again, this idea is from a limited point of view and I'm pretty 
sure I don't see the big picture.

> Unsigned JWS is explicitly forbidden, as is “alg:none”. If you’re going to send an unsigned request, just send the plain JSON.
My bad, thanks for the clarification

> Other methods will still be available, but this discussion is about what goes in the core document. The registry will allow for extension of other signing methods, and the core spec will put parame…
That's what I'm afraid of: having attached and detached signatures 
methods in an extension.

I'd rather have those methods in the core document. So the core GNAP 
spec would cover most use cases: SPA, website, app, fridge, TV, embedded 
sensor, satellite, etc.
All those use cases will have the same goal, but can choose one 
signature method that fit its needs, and its security requirements.

> The complexity is part of the story, for sure — but OAuth 2 is currently adding higher levels of protection through MTLS, DPoP, and HTTP Signatures, among a bunch of others. It’s really awkward in…

I agree, I chose to implement all those oauth2 client authentication 
schemes, and it's quite complex.
The most difficult part is that all those methods are extensions, so 
they know the core specs but not each other, therefore I have to make 
choices for all of those to work together.

That's the reason I prefer the detached and attached methods in the core 
specs.

/Nicolas

[1] https://spec.smarthealth.cards/#health-cards-are-small

---

From: Dave Tonge <[email-masked]>
Date: Mon, 21 Jun 2021 23:03:03 +0200

I'm definitely in favour of simplification.

Mutual TLS is an interesting one. I would prefer that it isn't included in
core as it mixes the transport and application layers and in my experience
is fairly brittle (not the spec, but how it is implemented in a lot of
places).

Purely in terms of aesthetics, I don't like the http signatures spec, but
if it is going to become mainstream then it makes sense to make it the
primary signing mechanism. As you mentioned the good thing about it is that
it can work for all HTTP requests, and can also be used for signing
responses.

I think some work will need to be done to get the http signature spec
supported by standard HTTP client libraries in popular languages. This will
make it a lot easier for implementers (i.e. I can call

```
myHttpClientLibary.post({
  body: {...},
  uri: "https://example.com/continue",
  sign: {
    key: {} // reference to key to use to sign,
    digest: "SHA-256"
    additionalHeaders: ["authorization", "content-type"]
  }
})
```

So my suggestion would be to only have the http signature spec in core.

GNAP is a new protocol - I see no need to add unnecessary optionality.

Dave

On Tue, 15 Jun 2021 at 19:50, Justin Richer <[email-masked]> wrote:

> In GNAP, most requests are signed in some way, or at least bound to a key
> being presented or referenced with the request. This is true for
> connections from the client instance to the AS and to the RS, as well as
> introspection requests from the RS to the AS. GNAP has always sought to be
> flexible with regard to cryptographic binding mechanisms, but there’s a
> question as to what should remain defined in the core document. Right now,
> core has six methods defined. The editors are proposing that we keep at
> least two and drop two, and the others could either both be kept, both be
> dropped, or one kept. The rationale for each proposal is discussed below:
>
> Proposed to keep:
>
> - HTTP Method Signatures: general purpose mechanism, being defined in HTTP
> WG. Can be bound to symmetric and asymmetric keys. Usable for native, web,
> and SPA clients. Suggested MTI for the AS (but not mandatory to use) for
> interoperability. Side note, possible use for AS to sign responses (but not
> explored here yet — that’s another topic).
>
> - OAuth DPoP: only works for asymmetric keys, requires key be presented in
> the header (duplicating information from GNAP messages). It was never meant
> to be a general purpose signing mechanism, though the FAPI group in OIDF is
> considering it as an option in current proposed work.
>
>
> This leaves the two JWS based methods, detached and attached. Since
> attached JWS depends on the detached JWS method to handle body-less
> requests like GET, DELETE, OPTIONS, etc., if we remove the detached method
> then we have to remove both. The methods could be pulled to an extension,
> left in core, or removed entirely.
>
> The editors would appreciate feedback on this proposal, including specific
> feedback on the JWS methods from implementors who are targeting them.
>
>
>  — Justin
> --
> TXAuth mailing list
> [email-masked]

-- 
Dave Tonge
CTO
<http://www.google.com/url?q=http%3A%2F%2Fmoneyhubenterprise.com%2F&sa=D&sntz=1&usg=AFQjCNGUnR5opJv5S1uZOVg8aISwPKAv3A>
t: +44 (0)117 280 5120

Moneyhub Enterprise is a trading style of Moneyhub Financial Technology
Limited which is authorised and regulated by the Financial Conduct
Authority ("FCA"). Moneyhub Financial Technology is entered on the
Financial Services Register (FRN 809360) at *https://register.fca.org.uk/
<https://register.fca.org.uk/>*. Moneyhub Financial Technology is
registered in England & Wales, company registration number  06909772 .
Moneyhub Financial Technology Limited 2019 ©

DISCLAIMER: This email (including any attachments) is subject to copyright,
and the information in it is confidential. Use of this email or of any
information in it other than by the addressee is unauthorised and unlawful.
Whilst reasonable efforts are made to ensure that any attachments are
virus-free, it is the recipient's sole responsibility to scan all
attachments for viruses. All calls and emails to and from this company may
be monitored and recorded for legitimate purposes relating to this
company's business. Any opinions expressed in this email (or in any
attachments) are those of the author and do not necessarily represent the
opinions of Moneyhub Financial Technology Limited or of any other group
company.

-- 

Moneyhub Enterprise is a trading style of Moneyhub Financial Technology 
Limited which is authorised and regulated by the Financial Conduct 
Authority ("FCA"). Moneyhub Financial Technology is entered on the 
Financial Services Register (FRN 809360) at https://register.fca.org.uk/ 
<https://register.fca.org.uk/>. Moneyhub Financial Technology is registered 
in England & Wales, company registration number 06909772. Moneyhub 
Financial Technology Limited 2020 © Moneyhub Enterprise, Regus Building, 
Temple Quay, 1 Friary, Bristol, BS1 6EA. 

DISCLAIMER: This email 
(including any attachments) is subject to copyright, and the information in 
it is confidential. Use of this email or of any information in it other 
than by the addressee is unauthorised and unlawful. Whilst reasonable 
efforts are made to ensure that any attachments are virus-free, it is the 
recipient's sole responsibility to scan all attachments for viruses. All 
calls and emails to and from this company may be monitored and recorded for 
legitimate purposes relating to this company's business. Any opinions 
expressed in this email (or in any attachments) are those of the author and 
do not necessarily represent the opinions of Moneyhub Financial Technology 
Limited or of any other group company.