-
Notifications
You must be signed in to change notification settings - Fork 4
feat: device authentication #42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Since it's getting a little bit complicated now, with the package supporting multiple flows, could we add a small markdown file into
|
@mortenpi Added docs to the PR now. |
* refactor, use dex well known conf, use env for client id * Add docs for device flow * Move auth_suffix under states * tests for device auth * Use custom config endpoint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly cosmetic stuff on the text, but also a little bit of bikeshedding on the configuration endpoint.
Co-authored-by: Morten Piibeleht <[email protected]>
Co-authored-by: Morten Piibeleht <[email protected]>
Co-authored-by: Morten Piibeleht <[email protected]>
Co-authored-by: Morten Piibeleht <[email protected]>
Co-authored-by: Morten Piibeleht <[email protected]>
auth_suffix::String | ||
challenge::String | ||
response::String | ||
response::Union{String, Dict{String, Any}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels like it would have been cleaner to bifurcate the state here to a separate RequestLoginDevice
state. Then we wouldn't have to overload the same state and handling method with logic from both flows. But not going to insist a change in this PR.
server::String | ||
challenge::String | ||
response::String | ||
auth_suffix::String |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, a separate ClaimDeviceToken
state may have been cleaner.
string(state.server, "/challenge"), | ||
device_endpoint, | ||
method = "POST", | ||
input = IOBuffer("client_id=$(get(ENV, "JULIA_PKG_AUTHENTICATION_DEVICE_CLIENT_ID", "device"))&scope=openid email profile offline_access"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nkottary @tanmaykm One final concern I have here is the scope=
value. The OAuth2 standard doesn't specify what the value should be here (in fact, it's optional). The specific scopes (openid email profile offline_access
) seem very Dex specific? So this wouldn't work with a different IdP?
I think we need to add that to the configuration endpoint to. E.g. optional device_token_scope
value, which defines the scope PkgAuthentication SHOULD request (if present). The scope from the server MUST minimally provide package server access (but can be broader).
Another option would be to maybe omit scope by default, but I don't think Dex allows that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The specific scopes (openid email profile offline_access) seem very Dex specific? So this wouldn't work with a different IdP?
These are standard openid scopes. We can't omit scope, we need those to retrieve information back from the idp. Some of them may not apply to non-openid providers, but then seems to me like we will be with openid in the near future. It's quite easy though to allow configuration of scopes via the configuration endpoint... we should probably do the change in PkgAuthentication.jl? The server side change can happen when necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My main argument here is that PkgAuthentication shouldn't be assuming a random set of scopes. It's implementing OAuth, not OpenID.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's implementing OAuth, not OpenID.
We use OpenID with JuliaHub. Hence the scopes are as they are. No one else uses PkgAuthentication.jl AFAIK. So I think we are good? But of-course, would be nice to make that configurable.
Implements device auth flow. As far as the state changes and interface is concerned, device auth flow is the same as the current browser challenge flow. The main advantage of device flow is that it avoids race conditions with the regular browser token because it is treated differently in the backend. Device token feature is not currently deployed on juliahub.com so this PR needs to be tested on development instances.
Working of this PR:
Please see the changes in auth-flow.md file.
Authenticating with device tokens:
The interface does not change for the user.
PkgAuthentication.authenticate()
can be called and it will seamlessly decide on what authentication mechanism to use.