Skip to content

Conversation

nkottary
Copy link
Member

@nkottary nkottary commented Apr 30, 2025

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.

@mortenpi
Copy link
Member

mortenpi commented May 6, 2025

Since it's getting a little bit complicated now, with the package supporting multiple flows, could we add a small markdown file into docs/ that summarizes things a bit? I think it should cover:

  • How device token flow works (with references to the standard if that's a thing?)
  • How the current flow works.
  • The fallback logic.
  • Assumptions around refresh tokens.

@nkottary
Copy link
Member Author

nkottary commented May 6, 2025

@mortenpi Added docs to the PR now.

@nkottary nkottary marked this pull request as ready for review May 6, 2025 10:21
nkottary added 2 commits May 22, 2025 05:13
* 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
Copy link
Member

@mortenpi mortenpi left a 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.

@nkottary nkottary marked this pull request as ready for review May 23, 2025 15:00
@nkottary nkottary requested review from mortenpi and tanmaykm May 23, 2025 15:01
@nkottary nkottary enabled auto-merge (squash) May 23, 2025 15:01
auth_suffix::String
challenge::String
response::String
response::Union{String, Dict{String, Any}}
Copy link
Member

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
Copy link
Member

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.

@nkottary nkottary merged commit acc0663 into JuliaComputing:master May 26, 2025
14 checks passed
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"),
Copy link
Member

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?

Copy link
Member

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.

Copy link
Member

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.

Copy link
Member

@tanmaykm tanmaykm Jun 10, 2025

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants