Secure JupyterLab using Keycloak
In this post, we will see how to secure JupyterLab & manage access for the JupyterLab notebook using Keycloak. I will be setting up the JupyterLab in the local system & require config changes for running it locally which will differ from the production setup. If you are not familiar with the Keycloak basics, you can go through this post Essentials. Let’s get started.
Setup
- Python
- Pip
- JupterLab
- Keycloak
Install JupyterLab & Notebook
pip install jupyterlabpip install notebook
Install oauthenticator
pip install oauthenticator
Proxy (Required for local development)
npm install -g configurable-http-proxy
Keycloak
Keycloak WildFly (deprecated)version
./standalone.sh -Djboss.socket.binding.port-offset=100
Keycloak (Quarkus based)
./kc.sh start-dev --http-port 8180
Create a Realm: keycloak-demo
- Create a Client ID: “jy” (“any preferred name)
- Access Type: Confidential
- Add Valid Redirect Uris: <Jupterhub-host>
Generate Config file
jupyterhub --generate-config
Open the jupyterhub_config.py in any editor
Copy ClientId & Client secret from Keycloak & add the following configuration
- c.GenericOAuthenticator.client_id = ‘jy’
- c.GenericOAuthenticator.client_secret = ‘<client secret>’
Keycloak Widlfy
Check the well-known end-point
http://keycloak-host: port>/realms/keycloak-demo/.well-known/openid-configuration
- c.GenericOAuthenticator.token_url=http://<keycloak-host: port>/auth/realms/<$realm>/protocol/openid-connect/token
- c.GenericOAuthenticator.userdata_url = ‘http://<keycloak-host: port>/auth/realms/keycloak-demo/protocol/openid-connect/userinfo’
Keycloak Quarkus
Check the well-known end-point
http://keycloak-host: port>/realms/keycloak-demo/.well-known/openid-configuration
- c.GenericOAuthenticator.token_url=http://<keycloak-host: port>/realms/<$realm>/protocol/openid-connect/token
- c.GenericOAuthenticator.userdata_url = ‘http://<keycloak-host: port>/realms/keycloak-demo/protocol/openid-connect/userinfo’
- c.GenericOAuthenticator.scope = [‘openid’, ‘profile’]
It will look like this:
from oauthenticator.generic import GenericOAuthenticatorc.JupyterHub.authenticator_class = GenericOAuthenticator
c.GenericOAuthenticator.client_id = 'jy'
c.GenericOAuthenticator.client_secret = '<client secret>'
c.GenericOAuthenticator.token_url = 'http://<keycloak-host: port>/auth/realms/keycloak-demo/protocol/openid-connect/token'
c.GenericOAuthenticator.userdata_url = 'http://<keycloak-host: port>/auth/realms/keycloak-demo/protocol/openid-connect/userinfo'
c.GenericOAuthenticator.userdata_params = {'state': 'state'}
c.GenericOAuthenticator.username_key = 'preferred_username'
c.GenericOAuthenticator.login_service = 'Keycloak'
c.GenericOAuthenticator.scope = ['openid', 'profile']
Update the Spawner
c.JupyterHub.spawner_class = 'jupyterhub.spawner.SimpleLocalProcessSpawner'
Note `Default: ‘jupyterhub.spawner.LocalProcessSpawner’
Requires local UNIX users matching the authenticated users to exist. Does not work on Windows.
Run the Jupterhub
Export Env variables
Keycloak WildFly
export OAUTH2_AUTHORIZE_URL=http://<keycloak-host:port>/auth/realms/keycloak-demo/protocol/openid-connect/authexport OAUTH2_TOKEN_URL=http://<keycloak-host:port/auth/realms/keycloak-demo/protocol/openid-connect/token
Keycloak Quarkus
export OAUTH2_AUTHORIZE_URL=http://<keycloak-host:port>/realms/keycloak-demo/protocol/openid-connect/authexport OAUTH2_TOKEN_URL=http://<keycloak-host:port/realms/keycloak-demo/protocol/openid-connect/token
Run the Jupterhub
jupyterhub -f jupyterhub_config.py
Open the JupterHub url in the browser. You will see the login screen
Click on the button: “Sign in with Keycloak” & You will it will redirect to the Keycloak login page.
You can now create a new notebook.
Conclusion
In this post, we have successfully secured Jupterhub using Keycloak. Setup & configuration is only for local setup. For production configuration will differ like using SSL.
If you like this post, give it a Cheer!!!
Follow the Collection: Keycloak for learning more…
Happy Secure Coding ❤