Skip to content
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

Update to z2jh 2 and JupyterHub 3 #1544

Merged
merged 12 commits into from
Oct 13, 2022

Conversation

consideRatio
Copy link
Member

@consideRatio consideRatio commented Oct 10, 2022

This better be done at some point in time, and one reason to do it is because it makes us compatible with k8s 1.25 and higher among other things.


Since this may be relevant knowing about I pinged a lot of you who I guessed could be influenced.

Draft status of PR because of ...

[D 2022-10-10 14:15:14.238 JupyterHub app:2035] Loading roles into database
[I 2022-10-10 14:15:14.249 JupyterHub roles:173] Role jupyterhub-idle-culler added to database
[I 2022-10-10 14:15:14.251 JupyterHub app:1934] Not using allowed_users. Any authenticated user will be allowed.
[W 2022-10-10 14:15:14.264 JupyterHub app:2312] Service binder sets `admin: True`, which is deprecated in JupyterHub 2.0. You can assign now assign roles via `JupyterHub.load_roles` configuration. If you specify services in the admin role configuration, the Service admin flag will be ignored.
[I 2022-10-10 14:15:14.265 JupyterHub roles:238] Adding role admin for Service: binder
[E 2022-10-10 14:15:14.268 JupyterHub app:3297]
    Traceback (most recent call last):
      File "/usr/local/lib/python3.9/site-packages/jupyterhub/app.py", line 3294, in launch_instance_async
        await self.initialize(argv)
      File "/usr/local/lib/python3.9/site-packages/jupyterhub/app.py", line 2824, in initialize
        self.init_services()
      File "/usr/local/lib/python3.9/site-packages/jupyterhub/app.py", line 2338, in init_services
        setattr(service, key, value)
      File "/usr/local/lib/python3.9/site-packages/traitlets/traitlets.py", line 715, in __set__
        self.set(obj, value)
      File "/usr/local/lib/python3.9/site-packages/traitlets/traitlets.py", line 689, in set
        new_value = self._validate(obj, value)
      File "/usr/local/lib/python3.9/site-packages/traitlets/traitlets.py", line 723, in _validate
        value = self._cross_validate(obj, value)
      File "/usr/local/lib/python3.9/site-packages/traitlets/traitlets.py", line 729, in _cross_validate
        value = obj._trait_validators[self.name](obj, proposal)
      File "/usr/local/lib/python3.9/site-packages/traitlets/traitlets.py", line 1132, in __call__
        return self.func(*args, **kwargs)
      File "/usr/local/lib/python3.9/site-packages/jupyterhub/services/service.py", line 322, in _validate_client_id
        raise ValueError(
    ValueError: service  has oauth_client_id='binder-oauth-client-test'. Service oauth client ids must start with 'service-'
    
[D 2022-10-10 14:15:14.270 JupyterHub application:961] Exiting application: jupyterhub

And failures following trialing prefixing with service-. Feel free to push commits to resolve this!

@consideRatio
Copy link
Member Author

consideRatio commented Oct 12, 2022

JupyterHub logs of high relevance

[E 2022-10-10 14:34:49.702 JupyterHub auth:271] User <User(dummy 0/1 running)> not allowed to access JupyterHub service binder
[W 2022-10-10 14:34:49.703 JupyterHub web:[179](https://github.com/jupyterhub/binderhub/actions/runs/2987255039/jobs/4789548250#step:28:182)6] 403 GET /hub/api/oauth2/authorize?client_id=service-binder&redirect_uri=http%3A%2F%2F127.0.0.1%3A8585%2Foauth_callback&response_type=code&state=eyJ1dWlkIjogIjE2MmM1NzNjMDJmMDRlYmE4OGQ4ZjNiODM1NTZlZTM5IiwgIm5leHRfdXJsIjogIi8ifQ (::ffff:10.1.1.85): You do not have permission to access JupyterHub service binder

Additional log lines for more context

[W 2022-10-10 14:34:45.684 JupyterHub app:2312] Service binder sets `admin: True`, which is deprecated in JupyterHub 2.0. You can assign now assign roles via `JupyterHub.load_roles` configuration. If you specify services in the admin role configuration, the Service admin flag will be ignored.
[I 2022-10-10 14:34:45.685 JupyterHub roles:238] Adding role admin for Service: binder
[I 2022-10-10 14:34:45.691 JupyterHub provider:651] Creating oauth client service-binder
[I 2022-10-10 14:34:45.706 JupyterHub app:2244] Adding API token for service: binder
[D 2022-10-10 14:34:45.712 JupyterHub app:2274] Purging expired APITokens
[D 2022-10-10 14:34:45.713 JupyterHub app:2274] Purging expired OAuthCodes
[D 2022-10-10 14:34:45.716 JupyterHub app:2110] Loading role assignments from config
[W 2022-10-10 14:34:45.729 JupyterHub app:2657] Allowing service binder to complete OAuth without confirmation on an authorization web page
...
[I 2022-10-10 14:34:49.605 JupyterHub log:186] 302 GET /hub/api/oauth2/authorize?client_id=service-binder&redirect_uri=http%3A%2F%2F127.0.0.1%3A8585%2Foauth_callback&response_type=code&state=[secret] -> /hub/login?next=%2Fhub%2Fapi%2Foauth2%2Fauthorize%3Fclient_id%3Dservice-binder%26redirect_uri%3Dhttp%253A%252F%252F127.0.0.1%253A8585%252Foauth_callback%26response_type%3Dcode%26state%3DeyJ1dWlkIjogIjE2MmM1NzNjMDJmMDRlYmE4OGQ4ZjNiODM1NTZlZTM5IiwgIm5leHRfdXJsIjogIi8ifQ (@::ffff:10.1.1.85) 1.39ms
[I 2022-10-10 14:34:49.650 JupyterHub log:186] 200 GET /hub/login?next=%2Fhub%2Fapi%2Foauth2%2Fauthorize%3Fclient_id%3Dservice-binder%26redirect_uri%3Dhttp%253A%252F%252F127.0.0.1%253A8585%252Foauth_callback%26response_type%3Dcode%26state%3DeyJ1dWlkIjogIjE2MmM1NzNjMDJmMDRlYmE4OGQ4ZjNiODM1NTZlZTM5IiwgIm5leHRfdXJsIjogIi8ifQ (@::ffff:10.1.1.85) 33.09ms
[D 2022-10-10 14:34:49.662 JupyterHub roles:281] Assigning default role to User dummy
[I 2022-10-10 14:34:49.667 JupyterHub roles:238] Adding role user for User: dummy
[D 2022-10-10 14:34:49.672 JupyterHub roles:281] Assigning default role to User dummy
[D 2022-10-10 14:34:49.676 JupyterHub base:559] Setting cookie jupyterhub-session-id: {'httponly': True, 'path': '/'}
[D 2022-10-10 14:34:49.676 JupyterHub base:563] Setting cookie for dummy: jupyterhub-hub-login
[D 2022-10-10 14:34:49.676 JupyterHub base:559] Setting cookie jupyterhub-hub-login: {'httponly': True, 'path': '/hub/'}
[I 2022-10-10 14:34:49.677 JupyterHub base:810] User logged in: dummy
[I 2022-10-10 14:34:49.677 JupyterHub log:186] 302 POST /hub/login?next=%2Fhub%2Fapi%2Foauth2%2Fauthorize%3Fclient_id%3Dservice-binder%26redirect_uri%3Dhttp%253A%252F%252F127.0.0.1%253A8585%252Foauth_callback%26response_type%3Dcode%26state%3DeyJ1dWlkIjogIjE2MmM1NzNjMDJmMDRlYmE4OGQ4ZjNiODM1NTZlZTM5IiwgIm5leHRfdXJsIjogIi8ifQ -> /hub/api/oauth2/authorize?client_id=service-binder&redirect_uri=http%3A%2F%2F127.0.0.1%3A8585%2Foauth_callback&response_type=code&state=[secret] (dummy@::ffff:10.1.1.85) 18.70ms
[D 2022-10-10 14:34:49.690 JupyterHub base:275] Recording first activity for <User(dummy 0/1 running)>
[D 2022-10-10 14:34:49.694 JupyterHub provider:415] Validating client id service-binder
[D 2022-10-10 14:34:49.695 oauthlib.oauth2.rfc6749.grant_types.authorization_code authorization_code:363] Validating redirection uri http://127.0.0.1:8585/oauth_callback for client service-binder.
[D 2022-10-10 14:34:49.695 oauthlib.oauth2.rfc6749.grant_types.base base:230] Using provided redirect_uri http://127.0.0.1:8585/oauth_callback
[D 2022-10-10 14:34:49.700 JupyterHub provider:490] validate_redirect_uri: client_id=service-binder, redirect_uri=http://127.0.0.1:8585/oauth_callback
[D 2022-10-10 14:34:49.701 oauthlib.oauth2.rfc6749.grant_types.base base:171] Validating access to scopes ['access:services!service=binder', 'read:users:name!user', 'read:users:groups!user'] for client 'service-binder' (<OAuthClient(identifier='service-binder')>).
[D 2022-10-10 14:34:49.702 JupyterHub provider:614] Allowing request for scope(s) for service-binder:  read:users:groups!user,access:services!service=binder,read:users:name!user
[E 2022-10-10 14:34:49.702 JupyterHub auth:271] User <User(dummy 0/1 running)> not allowed to access JupyterHub service binder
[W 2022-10-10 14:34:49.703 JupyterHub web:[179](https://github.com/jupyterhub/binderhub/actions/runs/2987255039/jobs/4789548250#step:28:182)6] 403 GET /hub/api/oauth2/authorize?client_id=service-binder&redirect_uri=http%3A%2F%2F127.0.0.1%3A8585%2Foauth_callback&response_type=code&state=eyJ1dWlkIjogIjE2MmM1NzNjMDJmMDRlYmE4OGQ4ZjNiODM1NTZlZTM5IiwgIm5leHRfdXJsIjogIi8ifQ (::ffff:10.1.1.85): You do not have permission to access JupyterHub service binder

Origin of error message

https://github.com/jupyterhub/jupyterhub/blob/5997614f452a3cfebfa541800012a914d37f3ec8/jupyterhub/apihandlers/auth.py#L265-L283

@consideRatio
Copy link
Member Author

I think I've pinpointed the differences of relevance here.

The different outcome is determined in the GET webrequest handler for JupyterHub's /api/oauth2/authorize path, specifically this code segment from jupyterhub 3.0.0 and this code segment from jupyterhub 1.5.0.

In 3.0.0 we get User <User(dummy 0/1 running)> not allowed to access JupyterHub service binder, while in 1.5.0 we get Skipping oauth confirmation for <User(dummy 0/1 running)> accessing JupyterHub service binder. The JupyterHub registered service binder is configured with oauth_no_confirm: true, and that is why we observe the "Skipping oauth confirmation" message. Should we do that also for 3.0.0? If so, that logic maybe needs to be given higher priority in JupyterHub.

With z2jh 2.0.0 and JupyterHub 3.0.0

[I 2022-10-10 14:34:49.677 JupyterHub base:810] User logged in: dummy
[I 2022-10-10 14:34:49.677 JupyterHub log:186] 302 POST /hub/login?next=%2Fhub%2Fapi%2Foauth2%2Fauthorize%3Fclient_id%3Dservice-binder%26redirect_uri%3Dhttp%253A%252F%252F127.0.0.1%253A8585%252Foauth_callback%26response_type%3Dcode%26state%3DeyJ1dWlkIjogIjE2MmM1NzNjMDJmMDRlYmE4OGQ4ZjNiODM1NTZlZTM5IiwgIm5leHRfdXJsIjogIi8ifQ -> /hub/api/oauth2/authorize?client_id=service-binder&redirect_uri=http%3A%2F%2F127.0.0.1%3A8585%2Foauth_callback&response_type=code&state=[secret] (dummy@::ffff:10.1.1.85) 18.70ms
[D 2022-10-10 14:34:49.690 JupyterHub base:275] Recording first activity for <User(dummy 0/1 running)>
[D 2022-10-10 14:34:49.694 JupyterHub provider:415] Validating client id service-binder
[D 2022-10-10 14:34:49.695 oauthlib.oauth2.rfc6749.grant_types.authorization_code authorization_code:363] Validating redirection uri http://127.0.0.1:8585/oauth_callback for client service-binder.
[D 2022-10-10 14:34:49.695 oauthlib.oauth2.rfc6749.grant_types.base base:230] Using provided redirect_uri http://127.0.0.1:8585/oauth_callback
[D 2022-10-10 14:34:49.700 JupyterHub provider:490] validate_redirect_uri: client_id=service-binder, redirect_uri=http://127.0.0.1:8585/oauth_callback
[D 2022-10-10 14:34:49.701 oauthlib.oauth2.rfc6749.grant_types.base base:171] Validating access to scopes ['access:services!service=binder', 'read:users:name!user', 'read:users:groups!user'] for client 'service-binder' (<OAuthClient(identifier='service-binder')>).
[D 2022-10-10 14:34:49.702 JupyterHub provider:614] Allowing request for scope(s) for service-binder:  read:users:groups!user,access:services!service=binder,read:users:name!user
[E 2022-10-10 14:34:49.702 JupyterHub auth:271] User <User(dummy 0/1 running)> not allowed to access JupyterHub service binder
[W 2022-10-10 14:34:49.703 JupyterHub web:[179](https://github.com/jupyterhub/binderhub/actions/runs/2987255039/jobs/4789548250#step:28:182)6] 403 GET /hub/api/oauth2/authorize?client_id=service-binder&redirect_uri=http%3A%2F%2F127.0.0.1%3A8585%2Foauth_callback&response_type=code&state=eyJ1dWlkIjogIjE2MmM1NzNjMDJmMDRlYmE4OGQ4ZjNiODM1NTZlZTM5IiwgIm5leHRfdXJsIjogIi8ifQ (::ffff:10.1.1.85): You do not have permission to access JupyterHub service binder

With z2jh 1.2.0 and JupyterHub 1.5.0

[I 2022-10-12 10:31:27.419 JupyterHub base:762] User logged in: dummy
[I 2022-10-12 10:31:27.419 JupyterHub log:189] 302 POST /hub/login?next=%2Fhub%2Fapi%2Foauth2%2Fauthorize%3Fclient_id%3Dbinder-oauth-client-test%26redirect_uri%3Dhttp%253A%252F%252F127.0.0.1%253A8585%252Foauth_callback%26response_type%3Dcode%26state%3DeyJ1dWlkIjogIjZlYmM2YzgyZDk1ODQ2MjNhMmU4ZGNhOWFjYjJhNTg2IiwgIm5leHRfdXJsIjogIi8ifQ -> /hub/api/oauth2/authorize?client_id=binder-oauth-client-test&redirect_uri=http%3A%2F%2F127.0.0.1%3A8585%2Foauth_callback&response_type=code&state=[secret] (dummy@::ffff:10.1.0.155) 16.90ms
[D 2022-10-12 10:31:27.429 JupyterHub base:283] Recording first activity for <User(dummy 0/1 running)>
[D 2022-10-12 10:31:27.431 JupyterHub provider:409] Validating client id binder-oauth-client-test
[D 2022-10-12 10:31:27.437 JupyterHub provider:484] validate_redirect_uri: client_id=binder-oauth-client-test, redirect_uri=http://127.0.0.1:8585/oauth_callback
[D 2022-10-12 10:31:27.439 JupyterHub auth:252] Skipping oauth confirmation for <User(dummy 0/1 running)> accessing JupyterHub service binder
[D 2022-10-12 10:31:27.439 JupyterHub provider:409] Validating client id binder-oauth-client-test
[D 2022-10-12 10:31:27.440 JupyterHub provider:484] validate_redirect_uri: client_id=binder-oauth-client-test, redirect_uri=http://127.0.0.1:8585/oauth_callback
[D 2022-10-12 10:31:27.440 JupyterHub provider:231] Saving authorization code binder-oauth-client-test, uPo..., (), {}
[I 2022-10-12 10:31:27.444 JupyterHub log:189] 302 GET /hub/api/oauth2/authorize?client_id=binder-oauth-client-test&redirect_uri=http%3A%2F%2F127.0.0.1%3A8585%2Foauth_callback&response_type=code&state=[secret] -> http://127.0.0.1:8585/oauth_callback?code=[secret]&state=[secret] (dummy@::ffff:10.1.0.155) 15.75ms

@consideRatio
Copy link
Member Author

🎉 wiee nice @minrk I see the tests passing with your changes!

Sorry for missing to bump the jupyterhub version, we even had a note about it... DOH!

@consideRatio consideRatio changed the title Update to z2jh 2.0.0 Update to z2jh 2 and JupyterHub 3 Oct 13, 2022
@minrk
Copy link
Member

minrk commented Oct 13, 2022

I believe the missing bit is that users must be granted access to services explicitly via load_roles.

That's the

User <User(dummy 0/1 running)> not allowed to access JupyterHub service binder

message, which translates to "user dummy does not have scope access:services!binder." Granting users access to services via loadRoles should get past this step, at least. I added access:services to the user role.

JupyterHub in the binderhub image also needs to be updated to match, which I added as well.

The binder service also should not need to be admin, we should define Binder's own permissions in a role. It needs:

  1. servers to read, start, and stop user servers
  2. admin:users (if not using auth)

It may make sense to define the role(s) dynamically in Python, because of the if auth_enabled logic involved.
Or we could define two roles statically in config, and then assign the role dynamically, depending on if auth is enabled or not.

Alternately, it could get no permissions at all in the auth case, and we could perform the launch requests with the user's own token. That might be better! It would mean specifying the permission servers!user in the services.binder.oauth_client_allowed_scopes config. It would still mean defining the (default) binder role (or not) and then assigning it (or not) based on auth_enabled.

@consideRatio
Copy link
Member Author

consideRatio commented Oct 13, 2022

@minrk I opened #1553 to represent your comments suggestions on how to tighten the requested permissions needed.

Thanks for completing this PR, this LGTM!

@consideRatio consideRatio merged commit d8f0e3b into jupyterhub:master Oct 13, 2022
consideRatio pushed a commit to jupyterhub/helm-chart that referenced this pull request Oct 13, 2022
@manics
Copy link
Member

manics commented Oct 14, 2022

@consideRatio
Copy link
Member Author

Yepp, we need a new jupyterhub version for compatibility i think :/

@manics
Copy link
Member

manics commented Oct 14, 2022

I think we should make one last release before bumping it: jupyterhub/repo2docker#1194

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking maintenance Under the hood improvements and fixes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CI system broken with k8s 1.25 (at least k3s 1.25)
3 participants