[GNAP] generic HTTP resource type

Jamey Sharp <jamey@minilop.net> Tue, 27 July 2021 01:04 UTC

Return-Path: <jamey@minilop.net>
X-Original-To: txauth@ietfa.amsl.com
Delivered-To: txauth@ietfa.amsl.com
Received: from localhost (localhost []) by ietfa.amsl.com (Postfix) with ESMTP id 677F23A0C7F for <txauth@ietfa.amsl.com>; Mon, 26 Jul 2021 18:04:14 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.098
X-Spam-Status: No, score=-2.098 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (1024-bit key) header.d=minilop.net
Received: from mail.ietf.org ([]) by localhost (ietfa.amsl.com []) (amavisd-new, port 10024) with ESMTP id UJ0iXXirI9t1 for <txauth@ietfa.amsl.com>; Mon, 26 Jul 2021 18:04:08 -0700 (PDT)
Received: from mail-pj1-x102f.google.com (mail-pj1-x102f.google.com [IPv6:2607:f8b0:4864:20::102f]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id C67E73A0C7C for <txauth@ietf.org>; Mon, 26 Jul 2021 18:04:08 -0700 (PDT)
Received: by mail-pj1-x102f.google.com with SMTP id b6so15412673pji.4 for <txauth@ietf.org>; Mon, 26 Jul 2021 18:04:08 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=minilop.net; s=google; h=date:from:to:subject:message-id:mime-version:content-disposition; bh=P26p5rE1wv86VDWlbWrlujsvzkBHtvBg0yvh3idvZ6I=; b=FieXwc6LiU22WCDBJMxpnRTmgWbW/cZ5R23haniKNKQGdK0F0Q/yzYBdw2BtraRm8v CtxUJOOiogiBGqPjGgmzyla0leSy2K9+851X7pWeCFUV/CgdAQS4JY3yx2drlyJDWOIO hgi9BHZ5YYwuBgt7gbBg3//9kgHbrlvdmQE9E=
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:subject:message-id:mime-version :content-disposition; bh=P26p5rE1wv86VDWlbWrlujsvzkBHtvBg0yvh3idvZ6I=; b=q9dj76FT1vXhFu+wBYHN0seoumut7eGa+VEdXkBjGjjAYPWEGAqsRWFBRxhl5R0N1u 139jZ0Z4aWUBQUAo0lGC5mDbGUjLJDqsqv4JOErk1VIIfTyF1HRZNdkDO3T94lptT/RY 9YxbxcOpwyu5fyQ8BqFN1WyBPxDeNM5u24cQvXlU7lGwDbsNJxnWSRjU9L/eYg5Pf3Sx fSl87aWtpG0/qHk2iIERGxgVS1IGkCMWIubMIummfa/X20IMBqA3r9DBZ5DULVUvj0it Hm2luScuWq0YIIlxhStQoz00+RCYUm7KU09P8IOm+J9VoggGWu/tP/qd5B4mjbMoewb/ hxcg==
X-Gm-Message-State: AOAM530iB68tCs4vmjVIXpW5iQCjtAGFbGmn5PImzJvhgck4grQPmgAM XXDFpDQAsTQY2CZGiJnGHAFEwUQNov5sbv+F
X-Google-Smtp-Source: ABdhPJw9q0P6yk74bMlEusfo7f/ane6hOzleb8wwi704yA86/5F5Dx2Sp1HrUJP0I1NhnM/+vDp1TA==
X-Received: by 2002:a17:902:8d96:b029:12b:ac49:79e7 with SMTP id v22-20020a1709028d96b029012bac4979e7mr16629439plo.18.1627347846995; Mon, 26 Jul 2021 18:04:06 -0700 (PDT)
Received: from eh (63-230-166-62.ptld.qwest.net. []) by smtp.gmail.com with ESMTPSA id fz10sm829330pjb.40.2021. for <txauth@ietf.org> (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Jul 2021 18:04:06 -0700 (PDT)
Received: by eh (sSMTP sendmail emulation); Mon, 26 Jul 2021 18:04:04 -0700
Date: Mon, 26 Jul 2021 18:04:04 -0700
From: Jamey Sharp <jamey@minilop.net>
To: txauth@ietf.org
Message-ID: <YP9bhNFEs3YPw1AD@eh>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"; format="flowed"
Content-Disposition: inline
Archived-At: <https://mailarchive.ietf.org/arch/msg/txauth/vmpC_NpQ-FLIRuSCOtnIOBSwpdU>
Subject: [GNAP] generic HTTP resource type
X-BeenThere: txauth@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: GNAP <txauth.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/txauth>, <mailto:txauth-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/txauth/>
List-Post: <mailto:txauth@ietf.org>
List-Help: <mailto:txauth-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/txauth>, <mailto:txauth-request@ietf.org?subject=subscribe>
X-List-Received-Date: Tue, 27 Jul 2021 01:04:14 -0000

In today's meeting, I asked about applying GNAP as the HTTP 
authentication method for arbitrary HTTP resources, such as static 
files, in the same way that Basic and Digest auth can be used today. 
Justin asked me to share the question here.

Because the current draft includes RS-first AS discovery using the 
standard WWW-Authenticate response header, it might work for this use 
case as-is, but I think it can be improved.

First: Am I correct in thinking that two access tokens retrieved from 
the same AS, by the same end user, with the same "access" list, should 
be indistinguishable to the client? Specifically, if a client receives 
two `WWW-Authenticate: GNAP` headers with the same "as_url" and "access" 
parameters, can it reuse the access token it got for the first request 
on the second request, without consulting the AS again?

If so, I think the WWW-Authenticate "access" parameter is equivalent to 
the "realm" parameter defined in RFC7235 and used in RFC7617 Basic auth. 
(Perhaps for consistency with HTTP auth, it should in fact be called 
"realm" when used in that header? RFC7235 even uses "scope" terminilogy 
to describe it.)

Without additional provisions, which I'm pretty sure are not currently 
in GNAP, checking for matching realm/access parameters still requires an 
extra unauthenticated request any time the client needs to access a URL 
it hasn't visited before, even if the response turns out to indicate 
that an earlier access token can be reused.

RFC7617 defines somewhat magic rules for when a client can proactively 
provide Basic-scheme credentials to a URL where it hasn't previously 
seen a WWW-Authenticate header, in order to avoid a round-trip in the 
common case where the same credentials are accepted at similar URLs. In 
theory, GNAP could specify something similar to make RS-first AS 
discovery more efficient, but that level of magic seems dangerous to me.

The Digest auth scheme in RFC7616 instead allows the server (in this 
context, the RS) to give an explicit list of URL prefixes which accept 
the same credentials, in the WWW-Authenticate "domain" parameter. I 
think that's a closer fit for GNAP, but rather than making it a header 
parameter, I think it's best to fold it into the token's access rights.

I propose standardizing a definition of a "type" value for the rights 
request that describes HTTP access rights generically, rather than 
describing actions appropriate to a specific API. I think that would 
make GNAP usable anywhere that Basic or Digest auth are currently used. 
It might also enable a wide variety of RESTful APIs and HTTP-based 
standards to use GNAP without needing to define custom rights types.

Here is a concrete suggestion as a starting point for discussion:

"access": [{
   "type": "http",
   "locations": ["https://example.com/protected/"],
   "datatypes": ["text/html", "image/*"],
   "actions": ["GET", "PUT", "DELETE"]

A resource request must match all fields to be allowed. If "datatypes" 
or "actions" are empty or absent, then all are permitted. (Permitting 
nothing is the same as not granting any rights at all.) The "locations" 
field is required to be present and non-empty though, and might work 
like the "domain" parameter in Digest: "The client can use this list to 
determine the set of URIs for which the same authentication information 
may be sent: any URI that has a URI in this list as a prefix [...] MAY 
be assumed to be in the same protection space."

This allows a client to request a limited set of methods or access to a 
limited portion of the protection space. It also allows the AS to inform 
the client of exactly which requests it may use the access token on, 
which may be different than what the client requested.

If I'm reading the current draft correctly, if a client sends an opaque 
resource reference like `"access": "WallyWorld"`, then the AS may choose 
to send back a non-opaque description of the rights granted by the 
returned access token, such as the above example for the hypothetical 
"http" rights type. Is that right?

I suppose the downside of the AS transforming an opaque reference into a 
full rights description is that the client can't indicate which rights 
types it understands. If a CMS supports a proprietary API for editing 
blog posts, but also supports WebDAV for file attachments, it might not 
be clear which rights type to use, yeah?

So here's an additional proposal: a client wishing to use this generic 
HTTP rights type should (must?) explicitly request it in the "access" 
rights request (and may also include the resource reference given in the 
"access" parameter of the WWW-Authenticate header, if any). It must 
specify the exact request URL in the "locations" field, and may also 
specify the method it tried to use in "actions". As usual, the AS may 
return a token granting rights to a wider range of locations or methods 
and is recommended to return the actual granted rights.

I hope that's reasonably clear and would love to discuss this further.