<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<font face="Helvetica, Arial, sans-serif">Sigh... I'm just getting
to updating the spec. I'll share updated XML and HTML later today.<br>
<br>
Comments inline...<br>
</font><br>
<div class="moz-cite-prefix">On 2/28/19 11:44 AM, Filip Skokan
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CALAqi_9VTWyb+iKeuTdkOpey6DFLuDXQegc_HBAiyO5jU-EtNA@mail.gmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div>You're welcome George, please find my
feedback inline.</div>
<br clear="all">
<div>
<div dir="ltr"
class="gmail-m_-6211326437220515853gmail_signature">Best,<br>
<b>Filip</b></div>
</div>
<br>
</div>
<br>
<div class="gmail_quote">
<div dir="ltr" class="gmail_attr">On Thu, 28 Feb
2019 at 16:56, George Fletcher <<a
href="mailto:gffletch@aol.com" target="_blank"
moz-do-not-send="true">gffletch@aol.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px
0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF"> <font face="Helvetica,
Arial, sans-serif">First, thank you very
much for your feedback and I sincerely
apologize for not getting back to you
sooner!<br>
<br>
Comments inline.<br>
</font><br>
<div
class="gmail-m_-6211326437220515853gmail-m_8583783033288155317moz-cite-prefix">On
1/18/19 5:46 AM, Filip Skokan wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div>Hello George,</div>
<div><br>
</div>
<div>I've re-read the document and
updated my past feedback draft. Here
goes</div>
<div><br>
</div>
<div><b>Section 3.2??</b></div>
<div><br>
</div>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">>
and as such it is RECOMMENDED that the
device secret be implemented as a JWE
encrypted for the??<br>
> Authorization Server.</blockquote>
<div><br>
</div>
<div>This recommendation suggests that
the AS does not store the device
secret state, why is JWE?? recommended
over any opaque value representing the
device secret state stored on AS side?</div>
</div>
</div>
</blockquote>
We can relax this to allow for a client only
vs server state solution. As to JWE, I often
recommend it because it makes it easy to do
key rotation and good security hygiene says
keys should be rotated. That say, I agree that
we don't have to be prescriptive around how in
that the value is opaque to the client.<br>
</div>
</blockquote>
<div><br>
</div>
<div>FS: ??????</div>
<blockquote class="gmail_quote" style="margin:0px
0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF">
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div><br>
</div>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">>
The client MAY provide the
"device_secret" to the /token endpoint
during refresh token requests.</blockquote>
<div><br>
</div>
<div>Why? What's the AS supposed to do,
refresh the device secret too?
Validate it as well? Should the AS
rotate the secret, is the client
expected to update the shared storage
with every new device secret it
receives? Given the previous
recommendation to use a JWE, how to
handle rotation or revocation, if it's
just an opaque value leading to a
record on the side, should the used
ones be marked as consumed and when
re-used revoke the grant as a whole?</div>
</div>
</div>
</blockquote>
So we have the requirement that the server
should be able to update the device secret if
needed. This provides a way for the device
secret to be "rotated". As to issuing of
access_tokens in the refresh_token grant flow,
then I'd suggest that the device_secret
represent the device to which the
refresh_token was issued. This creates a
tighter binding between the refresh_token and
the device.<br>
<br>
Yes, if an "old" device_secret is used, I
would reject the entire /token grant_type
flow.<br>
<br>
Note that support for other grant_types other
than refresh_token may require device_secret
validation.<br>
<br>
Also, my expectation is that device_secrets
contain a unique id (like a jti) that can be
used on the server side for management,
blacklisting, etc.<br>
</div>
</blockquote>
<div><br>
</div>
<div>FS: If the intention is for the server to
rotate it using its policies it should be
required to be present. e.g. if a refresh token
is received at the token endpoint which has the
"device_sso" scope the device_secret is a
required parameter? Too strict? Dunno, but this
way it looks like it's up to the client to
control the rotation by including it or not.
That way, as an implementer i'm forced to load
the device_secret by either reference or other
means (decode/decrypt) and i can easily confirm
the refresh token and device secret belong to
one another and that the device secret is not
expired / revoked or similar.<br>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
I'm updating the spec to say SHOULD instead of MAY. If there is
general agreement, I don't mind making it a MUST in the case of a
refresh_token that "contains" a device_sso scope.<br>
<blockquote type="cite"
cite="mid:CALAqi_9VTWyb+iKeuTdkOpey6DFLuDXQegc_HBAiyO5jU-EtNA@mail.gmail.com">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px
0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF">
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div><br>
</div>
<div><b>Section 3.3</b></div>
<div><br>
</div>
<div>Why would an app already in
possession of a device_secret go
through browser based code flow when
it can do token exchange? If that one
was rejected, then a browser based
code flow? And the point of providing
the previously rejected device_secret
is?</div>
</div>
</div>
</blockquote>
It's required so that the id_token can be
issued with the device_secret hash (ds_hash).
This allows the id_token, access_token and
refresh_token to be bound to the
device_secret. This constrains these tokens to
that device.<br>
</div>
</blockquote>
<div><br>
</div>
<div>FS: I'm not sure I follow. I know ID Token
being returned from refresh token grant or token
exchange in this case is optional, but still, as
a client if I get a device secret from the
shared storage my instinct reaction is to do the
token exchange, not to start a regular flow. It
just looks to me like this is out there without
an explanation on WHY a client would ever do a
regular auth flow when it's already in
possession of a device secret.</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
GFF: So if a device_secret and id_token exist when the native app
loads, it doesn't need to do the initial browser based flow. The
only time the browser based flow is required is if the device_secret
and associated id_token are NOT present on the device or the user
want to login with a different identity.<br>
<blockquote type="cite"
cite="mid:CALAqi_9VTWyb+iKeuTdkOpey6DFLuDXQegc_HBAiyO5jU-EtNA@mail.gmail.com">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px
0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF">
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div><br>
</div>
<div><b>Section 3.4</b></div>
<div><br>
</div>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">>
ds_hash??<br>
> The exact binding between the
ds_hash and device_secret is not
specified by this profile. As this<br>
> binding is managed solely by the
Authorization Server, the AS can
choose how to protect the<br>
> relationship between the id_token
and device_secret.</blockquote>
<div><br>
</div>
<div>Why not use the same boilerplate
used for other *_hash ID Token
properties?</div>
</div>
</div>
</blockquote>
We can. Partly because if the device_secret
contains a randomly generated unique id (e.g.
jti) then it might not really be required to
hash the whole device secret. I should
probably update the spec with this and am also
interested in your thoughts.<br>
</div>
</blockquote>
<div><br>
</div>
<div>FS: The device_secret being either opaque or
JWT it's always unique, else it doesn't serve
it's purpose right. Ergo, i'd say the ds_hash is
calculated the same way other hash properties
are. <br>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
I think one problem here is that if the device_secret is updated, it
will have a different hash value and now the ds_hash in the id_token
won't validate against the device_secret. I want to keep the binding
but not require issuing new id_tokens when the device_secret
changes. In this context, maybe hash is the wrong working and we
should change the claim name to 'ds_id' or something like that.<br>
<blockquote type="cite"
cite="mid:CALAqi_9VTWyb+iKeuTdkOpey6DFLuDXQegc_HBAiyO5jU-EtNA@mail.gmail.com">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px
0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF">
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div><br>
</div>
<div>e.g.</div>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">>
OPTIONAL. Device Secret hash value.
Its value is the base64url encoding of
the left-most half of<br>
> the hash of the octets of the
ASCII representation of the
device_secret value, where the hash<br>
> algorithm used is the hash
algorithm used in the alg Header
Parameter of the ID Token's JOSE<br>
> Header. For instance, if the alg
is RS256, hash the device_secret value
with SHA-256, then take<br>
> the left-most 128 bits and
base64url encode them. The ds_hash
value is a case sensitive string.</blockquote>
<div><br>
</div>
<div><b>Section 4.1</b></div>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex"><br>
> The client MUST use the HTTP
Basic Authentication method from RFC<br>
> 6749 to authenticate the request
to the token endpoint.</blockquote>
<div>??</div>
<div>1) client_secret_basic without
client_secret makes little sense and
in general an AS will issue a client
secret when client's
token_endpoint_auth_method is client
secret based.</div>
</div>
</div>
</blockquote>
So what is the preferred way for a PKCE client
to present it's client_id? Given the current
token exchange spec, I believe the only way is
in the HTTP Authorization header. Happy for
suggestions here.<br>
</div>
</blockquote>
<div><br>
</div>
<div>FS: OIDC Core Section 9 gives a name to such
auth method, it's "none" and the client_id is
provided in the body of the request and the
Token Exchange spec also mentions "Client
authentication to the authorization server is
done using the normal mechanisms provided by
OAuth 2.0.". Again this goes to the next point,
i'd just stick to the boilerplate and not force
a client to use a specific authentication
scheme.</div>
<div>??</div>
<blockquote class="gmail_quote" style="margin:0px
0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF"> <br>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div>2) I wouldn't specify the required
authentication method at the token
endpoint, i'd say something along the
lines of "the client authenticates
using its registered token endpoint
authentication method". Albeit this is
most likely going to be "none" but we
shouldn't rule out dynamically
registered clients with secrets or
private_key_jwt auth.</div>
</div>
</div>
</blockquote>
This is a good point as I'd like to look at
how this works with dynamic client
registrations using private_key_jwt. I'll see
about updating the text accordingly.<br>
</div>
</blockquote>
<div><br>
</div>
<div>FS: ????<br>
</div>
<div>??</div>
<blockquote class="gmail_quote" style="margin:0px
0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF">
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div><br>
</div>
<div>Furthermore any AS implementation
probably has the "client
authentication" abstracted before any
specific grant type processing and it
would be a hassle to add extra auth
processing based on the grant type.</div>
</div>
</div>
</blockquote>
Fair point.<br>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div><br>
</div>
<div><b>dtto in 4.2</b>, the example
should be a non-normative example</div>
</div>
</div>
</blockquote>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
GFF: I consider all examples non-normative. Should I explicitly
state that?<br>
<blockquote type="cite"
cite="mid:CALAqi_9VTWyb+iKeuTdkOpey6DFLuDXQegc_HBAiyO5jU-EtNA@mail.gmail.com">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px
0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF">
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div><br>
</div>
<div><b>Section 4.3</b></div>
<div><br>
</div>
<blockquote class="gmail_quote"
style="margin:0px 0px 0px
0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">>
If that session expires, all
refresh_tokens associated with it MUST
be invalidated.</blockquote>
<div><br>
</div>
<div>Regardless of present
offline_access scope and consent on
the initial authorization request?</div>
</div>
</div>
</blockquote>
Good point. I need to address the
'offline_access' scope scenario. I believe
that even in an offline_access scenario, the
server can invalidate the refresh_token so the
concept needs to stay. Effectively, there
needs to be a way for the id_token to
reference something for the long-lived
"session" such that if that session is
revoked, the token exchange failed.<br>
<br>
session_id could possibly be replaced with
refresh_token_id for the offline_access case.
Thoughts?<br>
</div>
</blockquote>
<div><br>
</div>
<div>FS: I probably skimmed though 4.3 the first
time, because point of it 2 says the token
endpoint should verify binding between an id
token and a device secret. Where did id_token
come from? The client doesn't send one, just
sends the refresh token and possibly? the device
secret.</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
GFF: the id_token is specified in the 'subject_token' parameter of
the token exchange profile<br>
<blockquote type="cite"
cite="mid:CALAqi_9VTWyb+iKeuTdkOpey6DFLuDXQegc_HBAiyO5jU-EtNA@mail.gmail.com">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px
0px 0px 0.8ex;border-left:1px solid
rgb(204,204,204);padding-left:1ex">
<div bgcolor="#FFFFFF">
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div><br>
</div>
<div><b>Section 4.4</b></div>
<div><br>
</div>
<div>
<ul>
<li>expires_in should be RECOMMENDED
or OPTIONAL to be in line with the
rest of the specifications</li>
<li>refresh_token REQUIRED? The
point is to obtain an ID and
Access tokens, i'd expect issuing
a refresh token is left to the AS
policy discretion</li>
</ul>
</div>
</div>
</div>
</blockquote>
Yes, we should leave it up to the AS. What I'd
like to describe is that if the new client
SHOULD receive a refresh_token for it's own
flows, then the AS needs to provide one
because the refresh_token is issued to the new
client_id. That said, there could be some
flows (though unlikely in a mobile
environment) where the AS does NOT issue
refresh_tokens so it shouldn't be REQUIRED.<br>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div><br>
</div>
<div>Example response has a few nits</div>
<div>
<ul>
<li>has "Issued_token_type" property
name (capital I)</li>
<li>should be marked as
non-normative</li>
<li>token_type although
case-insensitive value should be
"Bearer" to be inline with the
rest of the specs</li>
</ul>
</div>
</div>
</div>
</blockquote>
Thanks!<br>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div><br>
</div>
<div><b>Section 6.1.??</b></div>
<div><br>
</div>
<div>`sid` would already be registered
by both front and back-channel specs,
wouldn't it?</div>
<div><br>
</div>
<div><b>6.2.1. is probably a leftover
copy-paste</b></div>
</div>
</div>
</blockquote>
<b>Thank you!! This is very helpful!</b><br>
<blockquote type="cite">
<div dir="ltr">
<div dir="ltr">
<div><br>
</div>
<div>
<div dir="ltr"
class="gmail-m_-6211326437220515853gmail-m_8583783033288155317gmail_signature">Best,</div>
</div>
<div
class="gmail-m_-6211326437220515853gmail-m_8583783033288155317gmail_signature">Filip</div>
</div>
</div>
</blockquote>
<br>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<br>
</body>
</html>