Hi all,

I read -03 end to end this week, after the adoption call had closed,
as someone who has built and run sender-constrained deployments with
both DPoP and mTLS. I think the case for a third mechanism is real
where the signature has to cover more of the message than DPoP was
designed to, and where TLS termination makes mTLS impractical. I also
think the draft is not yet at the point where a reader can implement
the resource server side without guessing, and these comments are
offered toward that, whatever the group decides on adoption. They are
in document order. I am happy to turn any of them into pull requests
against the GitHub repo.

Section 2.3, token request. The only signal that the client wants a
bound token is a signature tagged httpsig-oauth-token-request. That
works. But section 6 says the request MUST fail with an error when the
signature is bad and never says which error. RFC 6749 gives
invalid_request and invalid_client, and DPoP added invalid_dpop_proof
because neither of those tells the client what to fix. This draft
needs its own (invalid_httpsig or similar), and a sentence on what an
AS that does not support this profile does with the signature: ignore
it or reject the request.

Section 2.3, the nonce. The nonce is client-generated, "a random unique
value that the AS can use to prevent signature replay within the small
validity time window". That puts a replay cache keyed on client-chosen
values at every AS and every RS. DPoP started in the same place and
added the server-provided nonce (RFC 9449 section 8, use_dpop_nonce)
because it turned the replay problem from a cache into a check. I think
this draft should offer the same option from the start rather than
retrofit it later. It would also close a gap in the fourth check in
section 8, which rejects a created value too far in the past but says
nothing about one in the future beyond clock skew.

Sections 4 and 5, key encoding. The pub signature parameter is a
Structured Fields Byte Sequence, which is standard base64 with padding.
The htsk confirmation member carries the same octets as base64url
without padding. Both are right for their containers, and the examples
already show the same key both ways, but nothing in the text points at
the difference. One sentence in section 5 saying that the two
encodings of one key differ, and that the examples carry the same key
in both forms would save implementers a debugging session.

Section 6, the token response. The draft is clear that a bound token
has token_type httpsig. It's not clear what an RS does when a token
with an htsk or jwk confirmation arrives in a Bearer authorization
header, which is the first thing an attacker who stole the token
will try. Section 8 should say that a token carrying a confirmation
MUST be rejected when presented under any scheme other than HTTPSig,
and that the RS decides on the confirmation in the token, not on the
scheme in the header. That is the salient point of the "Bearer plus
cnf" question on the list, and I think the answer belongs in the text
either way.

Section 6.2, introspection. RFC 7662 already returns token_type. Say
that an introspection response for a bound token returns token_type
httpsig alongside cnf, so an RS that only sees the introspection
response can apply the same rule as above.

Sections 7 and 8, the resource request. There is no error path. RFC
6750 section 3 defines the WWW-Authenticate challenge with
invalid_token and insufficient_scope, and DPoP extended it. This draft
needs the equivalent for the HTTPSig scheme: how the RS signals a
missing signature, a bad signature, an expired created, and a replayed
nonce, and whether a server nonce, if adopted, is delivered the way
DPoP delivers it. Related, the HTTPSig authentication scheme itself isn't
in the section 10 IANA list. It needs a registration in the HTTP
Authentication Scheme registry (RFC 9110 section 16.4).

Refresh tokens. DPoP section 5 binds refresh tokens issued to public
clients to the same key. This draft is silent on refresh tokens. Either
the same binding applies, and the text should say so and say how the
refresh request is signed, or it doesn't, and the security
considerations should say why that's acceptable.

Metadata. The editor's note in section 2 asks whether to add AS and RS
metadata. I think yes. A client that supports both DPoP and HTTPSig has
no way to learn which one a given AS or RS accepts without trying.
Something like httpsig_key_binding_methods_supported and
httpsig_signature_algorithms_supported in RFC 8414 metadata, and a
matching parameter in RFC 9728 resource metadata would do it.

Section 2.1, key rotation. The text says a client can add and retire
keys without changing its registration, which is right. It does not
say how an AS treats a token request signed with a kid it has not yet
fetched, or how long a retired key stays valid for tokens already
bound to it. A sentence or two would cover it.

Section 11, security considerations. I understand this is TBD, and I'd
rather contribute text than list gaps. The subsections I would
expect, and can draft: replay and the nonce cache; key compromise
against token lifetime; downgrade to Bearer (the section 6 point
above); a request that carries both a DPoP proof and an HTTPSig
signature; key reuse across resource servers as a tracking vector,
which the privacy section already notes; and why an attacker-controlled
alg parameter is not a problem here, since the alg is bound into the
confirmation the AS issued, which the draft does but never says. One
typo in the current bullets, "vailidty".

References. HTTPAUTH cites RFC 7235, which RFC 9110 obsoletes.

Appendix C, test vectors. The editor's note asks for end-to-end vectors
with keys. I can produce a set (Ed25519 and P-256, a full token
request, the issued token with cnf, an introspection response, a
resource request, and a negative case each for wrong tag, replayed
nonce and stale created) and submit them as a pull request. I would
rather do that after the key-encoding note above is settled so the
vectors do not have to be redone.

On the wider question of whether the working group wants a third
sender-constraining mechanism, my experience is that the choice between
DPoP and mTLS is already made by deployment constraints rather than by
preference. This draft fits a third constraint that neither covers
well, signing enough of the request that a resource server can trust
what it received, not only who sent it. I think the draft should say
that in its introduction rather than leave it to the editor's note
there, and the guidance should be a normative section rather than an
appendix.

Ron Bar-Tor
roniam.dev
_______________________________________________
OAuth mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to