[Ace] AD review of draft-ietf-ace-oauth-authz-24

Benjamin Kaduk <kaduk@mit.edu> Fri, 27 September 2019 01:52 UTC

Return-Path: <kaduk@mit.edu>
X-Original-To: ace@ietfa.amsl.com
Delivered-To: ace@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 75F48120232; Thu, 26 Sep 2019 18:52:11 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -4.199
X-Spam-Level:
X-Spam-Status: No, score=-4.199 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id sZglds-q7F6Q; Thu, 26 Sep 2019 18:52:04 -0700 (PDT)
Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 286DD120020; Thu, 26 Sep 2019 18:52:00 -0700 (PDT)
Received: from kduck.mit.edu ([24.16.140.251]) (authenticated bits=56) (User authenticated as kaduk@ATHENA.MIT.EDU) by outgoing.mit.edu (8.14.7/8.12.4) with ESMTP id x8R1ps9d029589 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 26 Sep 2019 21:51:57 -0400
Date: Thu, 26 Sep 2019 18:51:54 -0700
From: Benjamin Kaduk <kaduk@mit.edu>
To: draft-ietf-ace-oauth-authz.all@ietf.org
Cc: ace@ietf.org
Message-ID: <20190927015154.GY6424@kduck.mit.edu>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: inline
User-Agent: Mutt/1.12.1 (2019-06-15)
Archived-At: <https://mailarchive.ietf.org/arch/msg/ace/k5RzWwmuawvczrHN88JoE3vbH78>
Subject: [Ace] AD review of draft-ietf-ace-oauth-authz-24
X-BeenThere: ace@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "Authentication and Authorization for Constrained Environments \(ace\)" <ace.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/ace>, <mailto:ace-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/ace/>
List-Post: <mailto:ace@ietf.org>
List-Help: <mailto:ace-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/ace>, <mailto:ace-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 27 Sep 2019 01:52:12 -0000

Hi all,

The length of this review notwithstanding, this document is generally in
good shape -- there's a bunch of localized items to tighten up, and we
can flesh out the security considerations some more, but nothing too
drastic should be needed.  Perhaps the most far-reaching changes needed
will be to rename the "profile" claim, since that has already been
allocated to OIDC Core for a very different usage.  I also made a pull
request with a bunch of trivial editorial stuff that's easier to fix
than describe how to fix, up at
https://github.com/ace-wg/ace-oauth/pull/175 .

One general note before getting into the section-by-section comments:

There's a bunch of places where we talk about parameters that "MUST be
mapped to CBOR types as specified in Figure N"; we may want to point to
the IANA registry as authoritative and just give the figure reference
for description.

Abstract

   OAuth.  The framework is based on a set of building blocks including
   OAuth 2.0 and CoAP, thus making a well-known and widely used
   authorization solution suitable for IoT devices.  Existing

nit: It's easy to (mis)read this text as saying that just amalgamating
OAuth 2.0 and CoAP magically makes for a solution that is well-known and
widely used.  I'd suggest rewording slightly, perhaps "thus transforming
a well-known and widely used authorization solution into a form suitable
for IoT devices".

   specifications are used where possible, but where the constraints of
   IoT devices require it, extensions are added and profiles are
   defined.

nit: from a rhetorical point of view, it's probably better to reiterate
why the extensions are added and profiles defined ("to better serve the
IoT case") than to just stop with a flat declaration of what is done.

Section 1

   Authorization is the process for granting approval to an entity to
   access a resource [RFC4949].  The authorization task itself can best
   be described as granting access to a requesting client, for a
   resource hosted on a device, the resource server (RS).  This exchange

I had to pause for a while after reading this and ponder whether I
agreed with it.  I think that my reticence stems from some friction
between the most generic abstract definition of "resource" and a more
specific one used in the web/HTTP world and, to a lesser extent, the
world of URIs and URNs in general.  The resources we are discussing here
are not always specific named resources, but can also refer to
attributes or capabilities mediated by a RS; similarly, we may be
creating/modifying named resources as part of the resource access
performed by a client in the OAuth model.  I don't think it's wise to
diverge from the RFC 4949 definition just yet, but am still considering
whether adding some additional clarifying text here is worthwhile.

Section 3

It's probably worth adding (informative) references for HTTP/2, MQTT,
BLE, and QUIC.

   A fourth building block is the compact CBOR-based secure message

"compact CBOR" has the "PIN number" nature and is probably redundant.

   format COSE [RFC8152], which enables application layer security as an
   alternative or complement to transport layer security (DTLS [RFC6347]

I'm undecided whether it's better to think of this as "application layer
security" or "object-level security".

   or TLS [RFC8446]).  COSE is used to secure self-contained tokens such
   as proof-of-possession (PoP) tokens, which is an extension to the
   OAuth tokens.  The default token format is defined in CBOR web token

nit: I think there's a singular/plural mismatch in "is an extension",
which currently seems to be talking about the PoP tokens themselves.

Section 3.1

   Refresh Tokens:
      Refresh tokens are credentials used to obtain access tokens.
      Refresh tokens are issued to the client by the authorization
      server and are used to obtain a new access token when the current
      access token becomes invalid or expires, or to obtain additional
      access tokens with identical or narrower scope (access tokens may
      have a shorter lifetime and fewer permissions than authorized by
      the resource owner).  Issuing a refresh token is optional at the

nit: I'd suggest "such access tokens" in the parenthetical.

      A refresh token in OAuth 2.0 is a string representing the
      authorization granted to the client by the resource owner.  The
      string is usually opaque to the client.  The token denotes an

Apparently I'd forgotten that this couldn't be binary.

   Proof of Possession Tokens:
      An access token may be bound to a cryptographic key, which is then

Can refresh tokens not be PoP?

      The proof-of-possession (PoP) security concept assumes that the AS
      acts as a trusted third party that binds keys to access tokens.

nit: I think we're describing the PoP model used by ace, not the generic
PoP concept.

   Scopes and Permissions:
      In OAuth 2.0, the client specifies the type of permissions it is
      seeking to obtain (via the scope parameter) in the access token
      request.  In turn, the AS may use the scope response parameter to
      inform the client of the scope of the access token issued.  As the
      client could be a constrained device as well, this specification
      defines the use of CBOR encoding as data format, see Section 5, to
      request scopes and to be informed what scopes the access token
      actually authorizes.

nit: I think there's a word missing in "the use of CBOR encoding as data
format".

Section 3.2

   One application of COSE is OSCORE [I-D.ietf-core-object-security],
   which provides end-to-end confidentiality, integrity and replay
   protection, and a secure binding between CoAP request and response
   messages.  In OSCORE, the CoAP messages are wrapped in COSE objects
   and sent using CoAP.

   This framework RECOMMENDS the use of CoAP as replacement for HTTP for
   use in constrained environments.

Do we have a reason to mention OSCORE if we're not going to make a
recommendation about its use?

Section 4

If the description for step (C) is going to refer to the "profile (see
step B)", then we need to mention the profile as an example of the
Access Information in step (B).

                                                               The RS
      verifies that the token is integrity protected by the AS and
      compares the claims contained in the access token with the
      resource request.  [...]

I note that this verification of "integrity protected by the AS"
implicitly also includes verification of the source authentication
(i.e., signature or keyed MAC in key known only to AS and RS, in the
non-introspection case); do we want to make that more explicit in the
text?

Section 5

   Credential Provisioning
      For IoT, it cannot be assumed that the client and RS are part of a
      common key infrastructure, so the AS provisions credentials or
      associated information to allow mutual authentication.  These
      credentials need to be provided to the parties before or during
      the authentication protocol is executed, and may be re-used for
      subsequent token requests.

nit: either "before or during the execution of the authentication
protocol" or "before or during the authentication protocol's execution".
And just to double-check that we mean the authentication protocol of
provisioning in the last sentence, not the authorization protocol that
occurs between the client and RS.

   OAuth 2.0 requires the use of TLS both to protect the communication
   between AS and client when requesting an access token; between client
   and RS when accessing a resource and between AS and RS if
   introspection is used.  In constrained settings TLS is not always
   feasible, or desirable.  Nevertheless it is REQUIRED that the data
   exchanged with the AS is encrypted, integrity protected and protected
   against message replay.  It is also REQUIRED that the AS and the
   endpoint communicating with it (client or RS) perform mutual
   authentication.  [...]

This seems to leave open the possibility that client/RS interactions are
not encrypted, integrity protected, and/or replay protected; is that
intentional?  (We do require later on that all resource access gets the
"usual protections" other than the authz-info endpoint, so this is
mostly just an editorial remark.)

   In OAuth 2.0 the communication with the Token and the Introspection
   endpoints at the AS is assumed to be via HTTP and may use Uri-query
   parameters.  When profiles of this framework use CoAP instead, this
   framework REQUIRES the use of the following alternative instead of

nit: REQUIRES is not an RFC 2119 keyword (just REQUIRED).

   Uri-query parameters: The sender (client or RS) encodes the
   parameters of its request as a CBOR map and submits that map as the
   payload of the POST request.  Profiles that use CBOR encoding of
   protocol message parameters MUST use the media format 'application/
   ace+cbor', unless the protocol message is wrapped in another Content-
   Format (e.g. object security).  [...]

Is the bit starting at "Profiles that use CBOR" directly tied to the
CBOR-map submission to the AS, or a more general requirement on all
protocol flows (that would better be split off in its own paragraph)?

Also, some IESG members have not liked the "MUST [...], unless [...]"
construction, as it makes the MUST "no longer a MUST".  So perhaps we
could rephrase this as a positive statement, such as "CBOR-encoded
protocol messages that appeare at the outermost encoding layer MUST use the
media type "application/ace+cbor or, for CoAP, the corresponding
Content-Format's short ID of 19".

Section 5.1

   Instead of the initial Unauthorized Resource Request message, other
   discovery methods may be used, or the client may be pre-provisioned
   with the address of the AS.

nit: I suggest "pre-provisioned with an RS-to-AS mapping" so that we
don't have the "the AS" construct that implies there is only a single
AS.

Section 5.1.1

   Note: These conditions ensure that RS can handle requests
   autonomously once access was granted and a secure channel has been
   established between C and RS.  The authz-info endpoint MUST NOT be
   protected as specified above, in order to allow clients to upload
   access tokens to RS (cf.  Section 5.8.1).

I have some editorial suggestions here that I'll put into a pull requeste.

Section 5.1.2

It may not be worth having an attempt at a printable version of the
cnonce in the comments in Figure 4.

Section 5.1.2.1

   o  A RS sending a "cnonce" parameter in an an AS Request Creation
      Hints message MUST store information to validate that a given
      cnonce is fresh.  How this is implemented internally is out of
      scope for this specification.  Expiration of client-nonces should
      be based roughly on the time it would take a client to obtain an
      access token after receiving the AS Request Creation Hints
      message.

nit: I suggest to add something like "with some allowance for slop".

Section 5.2

   The grant type is selected depending on the use case.  In cases where
   the client acts on behalf of the resource owner, authorization code
   grant is recommended.  If the client acts on behalf of the resource
   owner, but does not have any display or very limited interaction
   possibilities it is recommended to use the device code grant defined
   in [I-D.ietf-oauth-device-flow].  In cases where the client does not
   acts autonomously the client credentials grant is recommended.

The context seems to suggest that this last sentence was intended as
"cases where the client acts autonomously"; is that correct?

Section 5.5

   well.  Non-constrained clients interacting with constrained resource
   servers can use the specifications in section 3.1 of [RFC6749] and of
   section 4.2 of [RFC6819].

nit: Section 4.2 of RFC 6819 isn't exactly a "specification" per se; we
might want to reword this.

Section 5.6

   For the AS to be able to issue a token, the client MUST be
   authenticated and present a valid grant for the scopes requested.
   Profiles of this framework MUST specify how the AS authenticates the
   client and how the communication between client and AS is protected.

We should probably list what attributes this protection entails --
confidentiality+integrity, of course, and we already mentioned both
sides of the mutual authentiation; do we need anything else like replay
protection?

   The default name of this endpoint in an url-path is '/token', however
   implementations are not required to use this name and can define
   their own instead.

We may get questions about the relationship between this "default" and
BCP 190; unfortunately, I haven't had a time to internalize the changes
proposed for draft-nottingham-rfc7320bis yet to see whether they would
affect us.  (To be clear, "leave it as-is for now and see if we get
complaints from the experts" is the right thing to do.)

Section 5.6.1

   The client sends a POST request to the token endpoint at the AS.  The
   profile MUST specify how the communication is protected.  The content

In the previous section we said that maybe even other transports than
coaps or https would be possible; are we limited to those that have POST
verbs?
Also, a similar comment as above about what attributes the protection
entails seems to apply.

   o  The "scope" parameter MAY be encoded as a byte string instead of
      the string encoding specified in section 3.3 of [RFC6749], in
      order allow compact encoding of complex scopes.

"scope" is a space-separated list (in the string encoding); is 0x20
still the list separator in the binary encoding?

   o  A client MUST be able to use the parameters from
      [I-D.ietf-ace-oauth-params] in an access token request to the
      token endpoint and the AS MUST be able to process these additional
      parameters.

[we might get someone complaining that if support for these is mandatory
they might as well be in the core document.  I don't mind the split, but
be forewarned.]

    Figure 5: Example request for an access token bound to a symmetric
                                   key.

I wouldn't be surprised is some reviewers asked for more text to clarify
that the AS-generated symmetric key is the default, so we don't need any
extra parameters to indicate that's what's being requested.

I'm a little surprised that OSCORE didn't provide some more scrutable
diagnostic notation for the OSCORE CoAP option.  To check: h is set, n is 1,
k is not set, the (1-byte) partial IV is 0x05, s is 5, and the rest of
the option is the kid context?

   Figure 7 shows a request for a token where a previously communicated
   proof-of-possession key is only referenced.  Note that the client
   performs a password based authentication in this example by
   submitting its client_secret (see Section 2.3.1 of [RFC6749]).  Note

RFC 6749 says about the bare "client_secret" that "[i]ncluding the
client credentials in the request-body using the two parameters is NOT
RECOMMENDED and SHOULD be limited to clients unable to directly utilize
the HTTP Basic authentication scheme (or other password-based HTTP
authentication schemes)."  I know this is "just an example", so our
obligations are somewhat weak, but I still think we should note that
this is not recommended by 6749 (but since there is no CoAP analogue of
HTTP Basic, it's the only plain-password scheme available).

   that this example uses the "req_cnf" parameter from
   [I-D.ietf-ace-oauth-params].

Er, the "req_cnf" parameter is exactly how the previously communicated
key is being referenced.  So we should not have a separate "Note" that
doesn't link back to the point of the example.

   Refresh tokens are typically not stored as securely as proof-of-
   possession keys in requesting clients.  Proof-of-possession based
   refresh token requests MUST NOT request different proof-of-possession
   keys or different audiences in token requests.  Refresh token
   requests can only use to request access tokens bound to the same
   proof-of-possession key and the same audience as access tokens issued
   in the initial token request.

This is perhaps something of a philosophical question, but if a refresh
token is only usable at the token endpoint, in some sense its audience
is definitionally the AS.  So there's a little bit of a mismatch in
treating it as having the audience value that the access tokens issued
from it will have.  I don't know the background for audience-restriced
refresh tokens in regular OAuth 2.0, though, so hopefully someone can
educate me.

Section 5.6.2

   Note that the AS decides which token type and profile to use when
   issuing a successful response.  It is assumed that the AS has prior

Would it be useful to note that this can be shaped by the "req_cnf"
contents?

   token_type:
      This parameter is OPTIONAL, as opposed to 'required' in [RFC6749].
      By default implementations of this framework SHOULD assume that
      the token_type is "pop".  If a specific use case requires another
      token_type (e.g., "Bearer") to be used then this parameter is
      REQUIRED.

When we are "weakening" the formal requirements of the parent spec like
this, we should be careful about what happens when someone is trying to
use the ACE stuff but ends up needing to go over HTTPS like traditional
OAuth -- do they have to fall back to the OAuth required behavior in
that case or are we trying to preempt that as well?


Given that we're requiring support for them, I think including the
parameters from draft-ietf-ace-oauth-params in Figure 8 (and removing
the note above it) would be helpful to the reader.  We probably also
want to leave some room for future extensions when we talk about it
("summarizes the parameters that may be part of the Access Information"
could maybe be read as restrictive, though it's clearly not meant to
be).

     "cnf" : {
       "COSE_Key" : {
         "kty" : "Symmetric",
         "kid" : b64'39Gqlw',
         "k" : b64'hJtXhkV8FJG+Onbc6mxCcQh'
       }
     }
   }

       Figure 9: Example AS response with an access token bound to a
                              symmetric key.

In light of the related discussion on cwt-proof-of-possession (resulting
in the removal of a bunch of text), do we want to say anything about the
scope of the 'kid' (that is, which participants are expecting to receive
and understand that value)?

Section 5.6.3

   The error responses for CoAP-based interactions with the AS are
   equivalent to the ones for HTTP-based interactions as defined in
   Section 5.2 of [RFC6749], with the following differences:

"equivalent [...] with the following differences" is going to get
complaints from the IESG.  I suggest "generally equivalent".

   o  A response code equivalent to the CoAP code 4.00 (Bad Request)
      MUST be used for all error responses, except for invalid_client
      where a response code equivalent to the CoAP code 4.01
      (Unauthorized) MAY be used under the same conditions as specified
      in Section 5.2 of [RFC6749].

6749 has a case where 401 MUST be used, but I think it does not apply to
us (since WWW-Authenticate would have to have been used).  I'm not sure
whether it makes sense to note that or not, though.

Section 5.6.4.3

   responses.  Furthermore profiles MUST define proof-of-possession
   methods, if they support proof-of-possession tokens.

nit: define the *methods* or the *list* of allowed ones?

   A profile MUST specify an identifier that MUST be used to uniquely
   identify itself in the "profile" parameter.  The textual
   representation of the profile identifier is just intended for human
   readability and MUST NOT be used in parameters and claims.

This seems like an opportunity for a registry...just like we have in
Section 8.7.  I'd suggest mentioning that registry here.

Section 5.6.5

Perhaps the title of Figure 12 should include both requests and
responses?

Section 5.7.1

   map with a "token" entry containing either the access token or a
   reference to the token (e.g., the cti).  Further optional parameters
   [...]
   The same parameters are required and optional as in Section 2.1 of
   [RFC7662].

This seems somewhat problematic, in that 7662 is pretty clear that the
"token" value is, well, the actual token.  So if we want to be able to
use "cti" instead, then we need to have some text saying that we're
deviating from 7662 and the specification for how "cti" is used there.

   {
     "token" : b64'7gj0dXJQ43U',
     "token_type_hint" : "pop"
   }

                         Figure 14: Decoded token.

nit: I think this is a decoded payload, not a decoded token.

Section 5.7.2

   cnonce  OPTIONAL.  A client-nonce previously provided to the AS by
      the RS via the client.  See Section 5.6.4.4.

I think this statement is only true after the token in question has been
properly validated at the RS.  Before that, all we can say is that it is
the client-nonce provided to the AS by the client, since there is
nothing to enforce that the client actually provided the same value that
was generated by the RS.

Section 5.7.4

"scope" is showing up with the key 9 a lot; I have mixed feelings about
having the CBOR map key value be aliased across different contexts (but
it's probably too late to change without disruption anyway).

Section 5.8

   In order to facilitate offline processing of access tokens, this
   document uses the "cnf" claim from
   [I-D.ietf-ace-cwt-proof-of-possession] and specifies the "scope"
   claim for JWT- and CWT-encoded tokens.

[looks like draft-ietf-oauth-token-exchange is going to beat us for the
JWT version of "scope":
https://www.iana.org/assignments/jwt/jwt.xhtml#claims ]

   The "scope" claim explicitly encodes the scope of a given access
   token.  This claim follows the same encoding rules as defined in
   Section 3.3 of [RFC6749], but in addition implementers MAY use byte
   strings as scope values, to achieve compact encoding of large scope
   elements.  The meaning of a specific scope value is application
   specific and expected to be known to the RS running that application.

I think I commented above about the use of 0x20 as the list separator;
whatever we do there should be applied here as well (or the text
otherwise consolidated to only need to say it once).

Section 5.8.1

   The access token, containing authorization information and
   information about the key used by the client, needs to be transported
   to the RS so that the RS can authenticate and authorize the client
   request.

nit(?): do we want to talk about the "confirmation method" rather than
the "key", out of some sense of remaining generic?

   This specification RECOMMENDS that an RS stores only one token per
   proof-of-possession key, meaning that an additional token linked to
   the same key will overwrite any existing token at the RS.

I might consider mentioning that this greatly simplifies implementation,
as not only is there not a need for the extra storage, but when a
request comes in using a given key, there's no need to resolve which
token to use with that request (and whether there would be different
access decisions made depending on which token was used), since the key
can be used directly for dispatch (e.g., with DTLS raw public key).

   If the payload sent to the authz-info endpoint does not parse to a
   token, the RS MUST respond with a response code equivalent to the
   CoAP code 4.00 (Bad Request).

Do we want this to specifically be about "parse to a token" with no need
to be a valid token?  (What error do we return for a syntactically valid
but semantically invalid token?)

   Profiles MUST specify whether the authz-info endpoint is protected,
   including whether error responses from this endpoint are protected.
   Note that since the token contains information that allow the client
   and the RS to establish a security context in the first place, mutual
   authentication may not be possible at this point.

We'll need some careful reasoning about this for the security
considerations, since the authz-info transaction can impact what profile
the RS thinks is in use.  E.g., whether a network attacker could
cause the client to think that a different (vulnerable) profile is in
use than the one the RS expects to use.

   The RS MAY make an introspection request to validate the token before
   responding to the POST request to the authz-info endpoint.
   [...]
   A RS MAY use introspection on a token received through the authz-info
   endpoint, e.g. if the token is an opaque reference.  Some transport

We should probably deduplicate the "MAY use introspection"s.

Section 5.8.1.1

I think we whould make an explicit note at the end of the list of claims
that we specify processing for, that additional processing is done (in a
profile-specific manner?) for other claims in the token.

   If the access token contains any other claims that the RS cannot
   process the RS MUST discard the token.  If this was an interaction

Just to double-check: this is overriding the JWT/CWT default so that all
token claims are comprehension-mandatory?  It might be worth making this
deviation from the core [JC]WT more explicitly a deviation.

Section 5.8.2

   If an RS receives a request from a client, and the target resource
   requires authorization, the RS MUST first verify that it has an
   access token that authorizes this request, and that the client has
   performed the proof-of-possession for that token.

As written, this sounds like it's okay to only do proof-of-possession
when posting tokens to the authz-info endpoint and not bind the
proof/key to the current request.  Is that intended?

   The response code MUST be 4.01 (Unauthorized) in case the client has
   not performed the proof-of-possession, or if RS has no valid access
   token for the client.  If RS has an access token for the client but
   not for the resource that was requested, RS MUST reject the request

nit: I suggest "but the token does not authorize access for".

Section 5.8.3

   o  The RS verifies the validity of the token by performing an
      introspection request as specified in Section 5.7.  This requires
      the RS to have a reliable network connection to the AS and to be
      able to handle two secure sessions in parallel (C to RS and AS to
      RS).

nit: isn't the second one RS to AS, not AS to RS?

      specification defines the following approach: The claim "exi"
      ("expires in") can be used, to provide the RS with the lifetime of
      the token in seconds from the time the RS first receives the
      token.  This approach is of course vulnerable to malicious clients
      holding back tokens they do not want to expire.  Such an attack

It also has suboptimal behavior if the RS loses state (e.g., by
rebooting), and possibly requires the RS to store indefinitely all
tokens with an "exi" value.  I have mixed feelings about specifying it
at all, though I concede it probably does have some value.  Regardless,
I think a dedicated subsection in the security considerations is in
order.

Section 5.8.4

   The AS provides the client with key material that the RS uses.  This
   can either be a common symmetric pop-key, or an asymmetric key used
   by the RS to authenticate towards the client.  Since there is no

Can you walk me through how a symmetric PoP key would be used for mutual
authentication (i.e., authentication of RS to client)?  It's easy/common
to do the PoP the other way, making the client prove it knows the key
associated with the token, but the other direction is not always
possible, depending on the protocol.

   o  The client knows a default validity period for all tokens it is
      using.  This information could be provisioned to the client when
      it is registered at the AS, or published by the AS in a way that
      the client can query.

Just to double-check: this validity period is time since issuance?  I'm
not sure whether this is sufficiently obvious that it goes without
saying (but it might be).

   o  The client performs an introspection of the token.  Although this
      is not explicitly forbidden, how exactly a client does
      introspection is not currently specified for OAuth.

I'm pretty sure this is overtaken by events (sorry for my part in
that!).  E.g., draft-ietf-oauth-jwt-introspection-response discusses
clients doing introspection, and even RFC 7662 itself discusses using a
client secret to authenticate to the introspection endpoint.  I think
there's another document between those two that's also relevant, but
can't find it right now :(

Section 6

There could perhaps be some security considerations relating to
discovery of RSes/resources thereon, but since we don't really talk
about that much to begin with, it's probably okay to skip the security
considerations discussion as well.

Both the client and the RS need to have their own respective long-term
credentials with the AS; we should talk about protecting those
credentials, what is risked/lost if the credentials are compromised,
how to recover from compromise, and the general key management
lifecycle (per BCP 107).

We should probably mention revocation in some fashion (even if only to
say that it's unlikely in practice) -- right now we just have one
passing mention as an optional responsibility of the AS, in Appendix B.

   A large range of threats can be mitigated by protecting the contents
   of the access token by using a digital signature or a keyed message
   digest (MAC) or an Authenticated Encryption with Associated Data

I won't be surprised if someone asks for examples of that "large range
of threats", so be prepared to answer...

   (AEAD) algorithm.  Consequently, the token integrity protection MUST
   be applied to prevent the token from being modified, particularly
   since it contains a reference to the symmetric key or the asymmetric
   key.  [...]

nit: "key used for proof of possession" (though my previous remark about
limiting to keys may apply as well).

   key.  If the access token contains the symmetric key, this symmetric
   key MUST be encrypted by the authorization server so that only the
   resource server can decrypt it.  Note that using an AEAD algorithm is
   preferable over using a MAC unless the message needs to be publicly
   readable.

nit(?) is "the message" here still "the token" like it was for the rest
of the paragraph?

   If the token is intended for multiple recipients (i.e. an audience
   that is a group), integrity protection of the token with a symmetric
   key is not sufficient, since any of the recipients could modify the
   token undetected by the other recipients.  Therefore a token with a

I can't decide whether we should clarify that this is "integrity
protection of the token with a symmetric key shared by the AS and RS"
(as opposed to a symmetric PoP key).

   It is important for the authorization server to include the identity
   of the intended recipient (the audience), typically a single resource
   server (or a list of resource servers), in the token.  Using a single
   shared secret with multiple resource servers to simplify key
   management is NOT RECOMMENDED since the benefit from using the proof-
   of-possession concept is significantly reduced.

I think we should word this more clearly with respect to "single shared
secret" -- is this the credential used by the RS to authenticate itself
to the client?  I'm not even sure if this text is intended to be
describing a workflow using symmetric or asymmetric keys.

              Profiles MUST specify how confidentiality protection is
   provided, and additional protection can be applied by encrypting the
   token, for example encryption of CWTs is specified in Section 5.1 of
   [RFC8392].

We should probably be a little more precise about what the additional
protection is -- it's not exactly protection for the PoP key, since
that's transmitted alongside the token in the authorization info (i.e.,
outside the token contents), but it does provide protection when the
token is subsequently used.
also, nit: comma splice

Section 6.1

I think we should have a little bit more discussion about what attacks
are possible even when a client hard-codes a list of trustworthy ASes,
e.g., when a device in one AS's purview is compromised and tries to get
the client to use a different (possibly also compromised, or maybe just
buggy) AS than the one that's supposed to be responsible for the device
in question.  In short, yes, spoofing is only possible within that set
of trusted ASes, but spoofing can still cause problems.

Are there any AS parameters other than URI that might be useful for an
out-of-band-configured list of valid values?

Section 6.2

      client MUST be able to determine whether an AS has the authority
      to issue access tokens for a certain RS.  This can be done through
      pre-configured lists, or through an online lookup mechanism that
      in turn also must be secured.

nit: I suggest "for example" to preempt anyone complaining about this
being needlessly prescriptive.

Section 6.4

   There may be use cases were different profiles of this framework are
   combined.  For example, an MQTT-TLS profile is used between the
   client and the RS in combination with a CoAP-DTLS profile for
   interactions between the client and the AS.  Ideally, profiles should
   be designed in a way that the security of system should not depend on
   the specific security mechanisms used in individual protocol
   interactions.

I think the IESG is going to pounce on this "ideally" -- what can we do
to ensure this is the case and/or warn when it isn't?  Can we just
say that profiles MUST NOT make assume that the same profile is used for
the different types of interactions?

Section 6.6

   inadvertently communicating with the wrong RS.  The correct values
   for "audience" can either be provisioned to the client as part of its
   configuration, or provided by the RS as part of the "AS Request
   Creation Hints" Section 5.1.2 or dynamically looked up by the client

I'm not sure that the AS Request Creation Hints are a big help here,
since they are untrusted input and it seems like bogus hints could cause
the client to obtain a token for a "wrong" RS.

Section 6.7

   First an attacker could perform a denial of service attack against
   the introspection endpoint at the AS in order to prevent validation
   of access tokens.  To mitigate this attack, an RS that is configured
   to use introspection MUST NOT allow access based on a token for which
   it couldn't reach the introspection endpoint.

I'm not sure that "mitigate" is quite right, as the attack (denial of
service) succeeds!  Probably we want something like "To maintain the
security of the system" instead.
nit: comma after First (and Second, in the next paragraph).

   an introspection call.  RS can mitigate such attacks by implementing
   a rate limit on how many introspection requests they perform in a
   given time interval and rejecting incoming requests to authz-info for
   a certain amount of time, when that rate limit has been reached.

I think the rate limit can be partially per client IP address (but a
global limit will probably still be necessary, too).

Section 7

Introspection could potentially output a lot of information from a given
token; some of the claims that might be found in a JWT or CWT can have
privacy considerations.  Though for constrained usage, it is likely that
the claims set will be pretty stripped down, so that might be more of an
exceptional case.  (When signed-only CWT/JWT are used, similar
considerations apply to the same claims, which is mostly covered already
under the "if access tokens are only integrity protected" part.

   information as possible in an unencrypted response.  Means of
   encrypting communication between C and RS already exist, more
   detailed information may be included with an error response to
   provide C with sufficient information to react on that particular
   error.

nit: I think the sentence is supposed to start with "When" or "If".

Section 8.X

I might consider adding a sentence to the toplevel Section 8 that notes
"this document creates several registries with a registration policy of
Expert Review; guidelines to the experts are given in Section 8.16" so
that we have a heads-up that these guidelines exist while we're reading
through the rest of the sections.  Though, perhaps most people aren't
reading it straight through like I am...

Section 8.3

   Name  The OAuth Error Code name, refers to the name in Section 5.2.
      of [RFC6749], e.g., "invalid_request".

We should refer to the OAuth registry as the authority on names, not the
immutable RFC.  (Similarly for the other mappings registries; I won't
repeat it each time, though for the later ones we're already doing the
right thing.)

Section 8.5

We should check what capitalization we want for the token type name, as
it's used all-lowercase elsewhere in the document but appears here as
"PoP".

Section 8.9

   Note that the mappings of parameters corresponding to claim names
   intentionally coincide with the CWT claim name mappings from
   [RFC8392].

I tried to spot-check this but couldn't find any that match up; am I
looking in the wrong place?

Section 8.11

   Reference  This contains a pointer to the public specification of the
      grant type abbreviation, if one exists.

Do we have some copy/paste issue with the "grant type abbreviation"
going on here (and elsewhere)?

Section 8.12

"scope" is already registered by draft-ietf-oauth-token-exchange (for
the same meaning).
"profile" is already registered by OIDC Core, for a "profile page URL".
So we will probably have to change to (e.g.) "ace_profile" everywhere.
:( :( :(

Section 8.13

The entry for "scope" should maybe also point to the oauth draft that
defined it for JWT.

(We can't get "profile" here, either.)

Section 8.14

I think for the media type we still want to use the IESG as the contact.

Section 8.16

   o  Specifications are required for the standards track range of point
      assignment.  Specifications should exist for specification
      required ranges, but early assignment before a specification is
      available is considered to be permissible.  Specifications are

This seems to be attempting to re-explain things already in RFC 8126,
but introduces some divergence along the way (which is bad).  I do note
that RFC 7120 covers early allocations, but specifically excludes doing
so from Expert Review registries.  I think technically that would
exclude using the early allocation procedure even for the "standards
action" or "specification required" ranges, though the experts would
still have leeway to make allocations under essentially the same
circumstances.

      document cannot have points assigned outside of that range.  The
      length of the encoded value should be weighed against how many
      code points of that length are left, the size of device it will be
      used on, and the number of code points left that encode to that
      size.

seems to duplicate "number of code points of that length that are left".

Section 10.1

We may get some debate about whether IANA registries are properly
Normative of Informative references, but we can wait for that to happen
-- no need to do anything now.

Section 10.2

If we're using RFC 4949 for terminology definitions, I think that makes
it a normative reference.

If we REQUIRE CBOR when used with CoAP, that also feels like a normative
reference.

I also think 7519 needs to be normative, since we mandate some of its
processing rules.

Appendix A

   Proof-of-Possession:

      This framework makes use of proof-of-possession tokens, using the
      "cnf" claim [I-D.ietf-ace-cwt-proof-of-possession].  A
      semantically and syntactically identical request and response
      parameter is defined for the token endpoint, to allow requesting
      and stating confirmation keys.  This aims at making token theft

nit: the wording here is a little weird in terms of specifying what is
identical.  I'm not sure I have a great suggestion for improvement,
though; what I'm coming up with is a lot more words.

Appendix C

Skimming through the main text, a couple more items we may want to list
here:

- optional procedures for client discovery of RS/resources/permissions
  (Section 4)
- optionally define new grant types (Section 5.2)
- optional use of client certificate as client credentials (Section 5.3)

   o  Specify the security protocol the client and RS must use to
      protect their communication (e.g., OSCORE or DTLS over CoAP).

IIRC both DTLS over CoAP and CoAP over DTLS are defined; do we need
specifically one of them?

Appendix D

   o  The symmetric key shared between client or RS and AS (if any).

I suggest splitting this into separate bullet points for client/AS and
RS/AS, to avoid chance of confusion.

Appendix E.1

      the Access Information contains the public key of the RS.  For
      communication security this example uses DTLS RawPublicKey between
      the client and the RS.  The issued token will have a short
      validity time, i.e., "exp" close to "iat", to protect the RS from
      replay attacks.  The token includes the claim such as "scope" with

With DTLS RPK I don't think replay is a huge concern; the short lifetime
seems more of a bound on how soon the authorization might be
invalidated.

In Figure 18 and the other example request payloads, let's use a
higher-entropy client_secret than "qwerty" (or "ytrewq"), so as to not
give anyone bad ideas.

I'm not 100% sure, but the << "access_token" : b64'SlAV32hkKG ...', >>
snippet doesn't seem to decode to the start of the expanded token
contents shown in Figure 19.

Do we want to update the times in the tokens/etc. to be closer to "now"?

   Messages C and F are shown in Figure 20 - Figure 21.

      C: The client then sends the PoP access token to the authz-info
      endpoint at the RS.  This is a plain CoAP request, i.e., no
      transport or application layer security is used between client and
      RS since the token is integrity protected between the AS and RS.
      The RS verifies that the PoP access token was created by a known
      and trusted AS, is valid, and has been issued to the client.  The

How can the RS check that the token "has been issued to the client"?
(How does it identify the client at this point to do so?)

      The client sends the CoAP request GET to /temperature on RS over
      DTLS.  The RS verifies that the request is authorized, based on
      previously established security context.
      F: The RS responds with a resource representation over DTLS.

nit: we should probably be consistent about whether we mention the CoAP
layer in the request+response.

Appendix E.2

   Note: In this example the client does not know the exact door it will
   be used to access since the token request is not send at the time of
   access.  So the scope and audience parameters are set quite wide to
   start with and new values different form the original once can be
   returned from introspection later on.

Maybe add "and tailored to the RS performing introspection"?

      A: The client sends the request using POST to the token endpoint
      at AS.  The request contains the Audience parameter set to
      "PACS1337" (PACS, Physical Access System), a value the that the
      online door in question identifies itself with.  The AS generates

Didn't we just say that the client doesn't know the exact door it is
going to be talking to?

      an access token as an opaque string, which it can match to the
      specific client, a targeted audience and a symmetric key.  The

So we're handing out a symmetric PoP key for a long-lived token that may
be used at multiple resources?  Isn't that the example we gave earlier
that lets RSes impersonate the client to each other?

In Figure 22, should we show the communications security layer between
client and AS?

The introspection response in Figure 25 only has a 'kid' element for the
confirmation claim (that corresponds to a symmetric key); how is the RS
supposed to know/learn the corresponding key so as to be able to verify
the client's proof of possession?

Thanks!

-Ben