Re: [GNAP] Signature Methods

Justin Richer <> Mon, 21 June 2021 13:51 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id AC5843A1038 for <>; Mon, 21 Jun 2021 06:51:34 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -2.295
X-Spam-Status: No, score=-2.295 tagged_above=-999 required=5 tests=[RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_NONE=0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id rUZsxHd0hpS9 for <>; Mon, 21 Jun 2021 06:51:30 -0700 (PDT)
Received: from ( []) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by (Postfix) with ESMTPS id E3AC63A106E for <>; Mon, 21 Jun 2021 06:51:29 -0700 (PDT)
Received: from [] ( []) (authenticated bits=0) (User authenticated as jricher@ATHENA.MIT.EDU) by (8.14.7/8.12.4) with ESMTP id 15LDpOlo001922 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 21 Jun 2021 09:51:24 -0400
Content-Type: text/plain; charset="utf-8"
Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.\))
From: Justin Richer <>
In-Reply-To: <>
Date: Mon, 21 Jun 2021 09:51:23 -0400
Content-Transfer-Encoding: quoted-printable
Message-Id: <>
References: <> <>
To: Nicolas Mora <>
X-Mailer: Apple Mail (2.3608.
Archived-At: <>
Subject: Re: [GNAP] Signature Methods
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: GNAP <>
List-Unsubscribe: <>, <>
List-Archive: <>
List-Post: <>
List-Help: <>
List-Subscribe: <>, <>
X-List-Received-Date: Mon, 21 Jun 2021 13:51:35 -0000

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

> On Jun 20, 2021, at 9:16 AM, Nicolas Mora <> wrote:
> Hello,
> Le 2021-06-15 à 13 h 49, Justin Richer a écrit :
>> 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).
> [...]
>> 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.
> 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

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