WICG / dbsc

Other
296 stars 24 forks source link

how are endpoints conveyed from server to browser? #45

Open bc-pi opened 5 months ago

bc-pi commented 5 months ago

It's not clear how the secure session endpoint(s) are to be conveyed from server to browser. Is this the purpose of the "path" part of the Sec-Session-Registration? I'm clearly missing something but I think some additional clarity/explanation in the document is needed in this area.

arnar commented 5 months ago

Yes, the path is meant to be the URL to the endpoint. I agree this is not clear at all.

bc-pi commented 5 months ago

Thanks for confirming the intent and lack of clarity :)

There are some other things related to the Sec-Session-Registration that could use some additional clarity/explanation. I'll just dump a few here rather than opening issues.

What does it mean to have more than Sec-Session-Registration header? i.e. why is it defined as a list structured header so there can "be more than one registration on one response"? What is the intent? Why would a sever send more than one and what's the resultant behavior from the browser? Maybe I'm missing something but I wasn't able to grasp any of this from the readme.

Why are Byte Sequences apparently used for the challenge and authorization values? Those values are sent back to the server unchanged. Treatment as sf-binary suggests encoding/decoding that I don't think is needed/intended.

What scheme is supposed to be used when sending the authorization value to the registration endpoint in the Authorization header? That's just a syntax question but I must admit I don't really understand the intent/value of the authorization part of the response header.

bc-pi commented 5 months ago

Just noticed that Sec-Session-Challenge has challenge=<base64url encoded challenge> which is not sf-binary but similarly suggests encoding/decoding. And different that Sec-Session-Registration...

arnar commented 5 months ago

What does it mean to have more than Sec-Session-Registration header?

It means the browser will process each individually, generating keys for each and call each registration endpoint.

The case for multiple concurrent sessions with overlapping scopes is for example that you have two off-the-shelf apps running under the same domain (and sign-in), but each has dbsc support built in. A second use case is to use separate sessions for each user if you support multiple users being signed in simultaneously. That ensures e.g. that each key only "belongs" to one user, and can be safely deleted if that user signs out and the browser is instructed to end that session.

Since multiple sessions are supported in the first place, then it seems ok to allow multiple registrations on the same response. I.e. the answer becomes "why not?" in a way. For the first case, you'd want to do that on a login if the two systems share the same sign-in stack; and for the second you might want to do that when you "upgrade" a set of unbound sessions to bound ones.

(This is arguably maybe too much flexibility)

I don't really understand the intent/value of the authorization part of the response header.

This is meant as a way for e.g. a sign-in system to pass a credential to the DBSC registration endpoint. The idea comes directly from how we use an authorization grant: At the end of a successful signin we can issue a single-use authorization token, which we use to establish refresh tokens for native apps. (On web we just set cookies right away.)

This is maybe superfluous, e.g. sign-in can always just set some cookie to pass that credential to the DBSC endpoint. But passing a single-use value in particular feels more explicit -- e.g. it will not appear on any other unrelated requests, even concurrent requests to the DBSC endpoint in the case of the multi-login example above.

The idea is also somewhat that a DBSC registration and a refresh endpoint could just be fairly thin wrappers around existing OAuth 2 infra: Registration is an authz_code->RT exchange, the (bound) RT is the session_identifier, and the refresh endpoint is a RT->AT of sorts.

Does this make sense?

bc-pi commented 5 months ago

Thanks @arnar, that definitely helps my understanding of some things. There does seem to be opportunity for additional clarity in current readme/spec/explainer on these topics (and others). I do realize that's easier said than done. But take it for whatever it's worth from someone with some spec experience in things not dissimilar to DBSC and looking at it with relatively fresh eyes.

kmonsen commented 5 months ago

Thanks @bc-pi, we are very grateful for the feedback and are for sure taking it to heart. One of the issues is that we have worked on this for some time so fresh eyes are for sure useful here.

bc-pi commented 5 months ago

... the authorization part of the response header.

Does this make sense?

Yeah, thanks. I sort of assumed something along those lines. But assuming only gets you so far.

Again, what scheme is used to send the value back? "Bearer" seems kinda/maybe implied but not stated anywhere and maybe I'm way off...

Also similar to https://github.com/WICG/dbsc/issues/41#issuecomment-2055075522 (though slightly different yes) the use of structured fields byte sequence doesn't seem quite appropriate.

kmonsen commented 5 months ago

If by value you mean the result of a header, it is sent as an out of band request to the endpoint as described in the explainer:

"POST /securesession/startsession HTTP/1.1 Host: auth.example.com Accept: application/json Content-Type: application/json Content-Length: nn Cookie: whatever_cookies_apply_to_this_request=value;

" Note that I will update this to have the JWT in the header and not base64 encode it.
bc-pi commented 5 months ago

... multiple registrations on the same response. ... "why not?" ... (This is arguably maybe too much flexibility)

Finding the right line is undoubtedly difficult but offhand it seems like the cases you mention are not the prototypical expected use and could be accomplished when needed with additional requests/responses. I would typically lean towards fewer options and simplicity where possible in specs. But I might be too biased in that direction.

bc-pi commented 5 months ago

If by value you mean the result of a header, it is sent as an out of band request to the endpoint as described in the explainer:

In this case I was talking about the value of the authorization parameter/thing in the response header and how that is sent back in that out of band request. The readme suggests it's in the authorization request header and a claim in the JWT. The former needs more explanation for things like what auth-scheme is used and both are problematic with respect to being sent in the response header as a structured fields byte sequence.

kmonsen commented 5 months ago

I'll convert that to a string as well. My intention is to set it as received in the JWT: authorization": "", // optional, only if set in registration header

Open to if something different should be done.

arnar commented 5 months ago

Again, what scheme is used to send the value back?

Tbh I hadn't thought about it further than for regular "Bearer" -- if we do decide the authorization value is worth having, then we need to fill in those gaps. Getting the kind of feedback we're getting here from you and others is exactly what we wanted to get before fully fleshing things out.

bc-pi commented 5 months ago

Getting the kind of feedback we're getting here from you and others is exactly what we wanted to get before fully fleshing things out.

Thanks, I am endeavoring to give constructive feedback. It can be difficult, however, when such feedback can range from purely syntactical stuff like treatment of this authorization thing being kinda broken to whether or not a general construct like it is necessary or useful enough to include in a "spec". I'm trying though :)