Is Jupyterhub RBAC groups the same as OAuth groups?

In case it’s useful, here’s a more complete copy of the code I ended up with. I wanted to keep my JH groups in sync with my AWS SSO groups, but you could use this pattern for any OAuth source.

class CustomOAuthenticator(GenericOAuthenticator):
    # Automatically send the user to the OIDC login page instead of prompting them to click a button.
    auto_login = True

    # Allow all AUTHENTICATED users to log in.
    allow_all = True

    # Authenticator class (this) is now responsible for managing groups.
    manage_groups = True

    login_service = ...
    username_claim = ...
    authorize_url = ...
    client_id = ...
    client_secret = ...
    oauth_callback_url ...
    token_url = ...
    userdata_url = ...

    async def update_auth_model(self, auth_model):
        """
        Because manage_groups is set to True, we need to include the user's groups in the returned auth model.
        Ref: https://jupyterhub.readthedocs.io/en/stable/reference/authenticators.html#authenticator-managed-group-membership
        """
        auth_model = await super().update_auth_model(auth_model)

        # Build the user's list of groups in the normal fashion. The parent class will do this automatically,
        # but only when checking for admin permissions. We want to do it for all users to return their groups!
        user_info = auth_model["auth_state"][self.user_auth_state_key]
        user_groups = self.get_user_groups(user_info)

        # Include the new "groups" key in the auth_model.
        auth_model["groups"] = user_groups

        return auth_model

    def claim_groups_key(self, user_info):
        """
        Return the JupyterHub groups a user should be associated with:
        - any AWS SSO group membership
        - global collab group
        """
        user_aws_sso_groups = aws_sso.user_groups.get(user_info['email'], [])
        return [shared_group] + list(user_aws_sso_groups)


c.JupyterHub.authenticator_class = CustomOAuthenticator

Once I started down the custom class path, a lot of cool functionality became possible :slight_smile: One problem I did quickly encounter was limitations with the base JupyterHub docker image I was using (via Z2JH), specifically it not having boto3 installed. So, had to customize that as well.

But in the end it works beautifully!

2 Likes