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

Upgrade oauthenticator version and docs #1583

Merged
merged 19 commits into from
Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions config/clusters/2i2c/dask-staging.values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,8 @@ basehub:
shown_idps:
- https://accounts.google.com/o/oauth2/auth
allowed_idps:
# CILogon still uses the old google oidc enpoint instead of the new one listed in `shown_idps`.
# Ref https://github.com/ncsa/OA4MP/issues/45
http://google.com/accounts/o8/id:
username_derivation:
username_claim: "email"
Authenticator:
# We only want 2i2c users to sign up
# Protects against cryptominers - https://github.com/2i2c-org/infrastructure/issues/1216
username_pattern: '^(.+@2i2c\.org|deployment-service-check)$'
# Delete any prior existing users in the db that don't pass username_pattern
delete_invalid_users: true
allowed_domains:
- "2i2c.org"
15 changes: 10 additions & 5 deletions config/clusters/2i2c/demo.values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,15 @@ jupyterhub:
config:
JupyterHub:
authenticator_class: cilogon
Authenticator:
# We do not define allowed_users here since only usernames matching this regex will be allowed to login into the hub.
# Ref: https://jupyterhub.readthedocs.io/en/stable/api/auth.html#jupyterhub.auth.Authenticator.username_pattern
username_pattern: '^(.+@2i2c\.org|.+@rmbl\.org|deployment-service-check)$'
CILogonOAuthenticator:
oauth_callback_url: https://demo.2i2c.cloud/hub/oauth_callback
username_claim: email
# Only show the option to login with Google
shown_idps:
- https://accounts.google.com/o/oauth2/auth
allowed_idps:
http://google.com/accounts/o8/id:
username_derivation:
username_claim: "email"
allowed_domains:
- "2i2c.org"
- "rmbl.org"
143 changes: 105 additions & 38 deletions docs/howto/configure/auth-management.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ There are also some steps that a Community Representative will need to take to s
`2i2c-org`.
- When naming the application, please follow the convention `<cluster_name>-<hub_name>` for consistency, e.g. `2i2c-staging` is the OAuth app for the staging hub running on the 2i2c cluster.
- The Homepage URL should match that in the `domain` field of the appropriate `cluster.yaml` file in the `infrastructure` repo.
- The authorisation callback URL is the homepage url appended with `/hub/oauth_callback`. For example, `staging.pilot.2i2c.cloud/hub/oauth_callback`.
- The authorisation callback URL is the homepage url appended with `/hub/oauth_callback`. For example, `staging.2i2c.cloud/hub/oauth_callback`.
- Once you have created the OAuth app, make a new of the client ID, generate a client secret and then hold on to these values for a future step

2. **Create or update the appropriate secret config file under `config/clusters/<cluster_name>/<hub_name>.secret.values.yaml`.**
Expand Down Expand Up @@ -323,7 +323,7 @@ The steps to enable the JupyterHub CILogonOAuthenticator for a hub are simmilar
This can be achieved by using the [cilogon_app.py](https://github.com/2i2c-org/infrastructure/blob/HEAD/deployer/cilogon_app.py) script.

- The script needs to be passed the cluster and hub name for which a client id and secret will be generated, but also the hub type, and the authorisation callback URL.
- The authorisation callback URL is the homepage url appended with `/hub/oauth_callback`. For example, `staging.pilot.2i2c.cloud/hub/oauth_callback`.
- The authorisation callback URL is the homepage url appended with `/hub/oauth_callback`. For example, `staging.2i2c.cloud/hub/oauth_callback`.
- Example script invocation that creates a CILogon OAuth client for the 2i2c dask-staging hub:
```bash
python3 ./deployer/cilogon_app.py create 2i2c dask-staging daskhub https://dask-staging.2i2c.cloud/hub/oauth_callback
Expand Down Expand Up @@ -364,48 +364,115 @@ The steps to enable the JupyterHub CILogonOAuthenticator for a hub are simmilar
...
```

5. **Edit the non-secret config under `config/clusters/<cluster_name>/<hub_name>.values.yaml`.**
You should make sure the matching hub config takes one of the following forms.
4. **Edit the non-secret config under `config/clusters/<cluster_name>/<hub_name>.values.yaml`.**

```{warning}
When using this method of authentication, make sure to remove the `allowed_users` key from the config.
This is because this key will block any user not listed under it **even if** they are valid members of the the organisation or team you are authenticating against.
4.1. **A few rules of thumb when using this method of authentication:**

Also, the `admin_users` list need to match `allowed_idps` currently.
Reference https://github.com/jupyterhub/oauthenticator/issues/494.
```
- The `admin_users` list need to match `allowed_idps` rules too.

To authenticate using CILogon, allowing only a certain identity provider:
- It is recommended to define in the `allowed_idps` dict, all the identity providers we plan to allow to be used for a hub. This way, only these will be allowed to be used.

```yaml
jupyterhub:
hub:
config:
JupyterHub:
authenticator_class: cilogon
CILogonOAuthenticator:
oauth_callback_url: https://{{ HUB_DOMAIN }}/hub/oauth_callback
username_claim: USERNAME_KEY
allowed_idps:
- 2i2c.org
- IDP
```
```{note}
The keys allowed in the `allowed_idps` dict **must be valid CILogon `EntityIDs`**.
Go to https://cilogon.org/idplist for the list of EntityIDs of each IdP.
```

Check the [CILogon scopes
section](https://www.cilogon.org/oidc#h.p_PEQXL8QUjsQm) to checkout available
values for `USERNAME_KEY` claim. This *cannot* be changed afterwards without manual
migration of user names, so choose this carefully.

```{warning}
`USERNAME_KEY` should be something the user *cannot change* in any of the identity providers
we support. If they can, it can be easily used to impersonate others! For example, if we allow
both GitHub and `utoronto.ca` as allowed authentication providers, and only use `email` as
`USERNAME_KEY`, any GitHub user can set their email field in their GitHub profile to a `utoronto.ca`
email and thus gain access to any `utoronto.ca` user's server! So a very careful choice needs to
be made here.
```
- All the identity providers must define a `username_derivation` scheme, with their own `username_claim`, that the user *cannot change*. If they can, it can be easily used to impersonate others! For example, if we allow both GitHub and `utoronto.ca` as allowed authentication providers, and only use `email` as `username_claim`, for both providers, any GitHub user can set their email field in their GitHub profile to a `utoronto.ca` email and thus gain access to any `utoronto.ca` user's server! So a very careful choice needs to
be made here.

6. Run the deployer as normal to apply the config.
```{note}
You can check the [CILogon scopes section](https://www.cilogon.org/oidc#h.p_PEQXL8QUjsQm) to checkout available values for `username_claim`. This *cannot* be changed afterwards without manual migration of user names, so choose this carefully.
```

4.2. **Most common configurations for 2i2c clusters:**

1. **Only display specific identity provider as a login options**

*This example uses GitHub as the only identity provider to show to the user.*

```yaml
jupyterhub:
hub:
config:
JupyterHub:
authenticator_class: cilogon
CILogonOAuthenticator:
# This config option will only display GitHub as the only identity provider option
shown_idps:
- https://github.com/login/oauth/authorize
```

2. **Authenticate using Google with CILogon, allowing only a certain domain**:

*This example sets `2i2c.org` as the only domain that can login into the hub using Google*

```yaml
jupyterhub:
hub:
config:
JupyterHub:
authenticator_class: cilogon
CILogonOAuthenticator:
oauth_callback_url: https://{{ HUB_DOMAIN }}/hub/oauth_callback
allowed_idps:
http://google.com/accounts/o8/id:
username_derivation:
username_claim: "email"
allowed_domains:
- "2i2c.org"
```

3. **Authenticate using an instutional identity provider for the hub community users and Google for 2i2c staff.**

This example:
- only shows the ANU identity provider and Google as the possible login option though CILogon
- sets `2i2c.org` as the only domain that can login into the hub using Google
- sets `anu.edu.au` as the only domain that can login into the hub using the ANU institutional id provider
- adds a `2i2c:` prefix to the usernames logging in through Google. The hub usernames are the `email` addresses of these accounts, as specified through `username_claim`.
- strips the `@anu.edu.au` domain from the usernames logging in through ANU IDP. The hub usernames are the `email` addresses of these accounts, as specified through `username_claim`.

```{note}
To get the value of the key that must go in the `allowed_idp` dict for a specific IdP, go to https://cilogon.org/idplist and get the value of the `EntityID` key of the desired institutional IdP.
```

Example config:

```yaml
jupyterhub:
hub:
config:
JupyterHub:
authenticator_class: cilogon
CILogonOAuthenticator:
oauth_callback_url: https://{{ HUB_DOMAIN }}/hub/oauth_callback
admin_users:
- [email protected]
# Only show the option to login with Google and ANU
shown_idps:
- https://idp2.anu.edu.au/idp/shibboleth
- https://accounts.google.com/o/oauth2/auth
allowed_idps:
http://google.com/accounts/o8/id:
username_derivation:
username_claim: "email"
action: "prefix"
prefix: "2i2c"
allowed_domains:
- "2i2c.org"
https://idp2.anu.edu.au/idp/shibboleth:
username_derivation:
username_claim: "email"
action: "strip_idp_domain",
domain: "anu.edu.au"
allowed_domains:
- "anu.edu.au"
```

```{note}
To learn about all the possible config options of the `CILogonOAuthenticator` dict, checkout [the docs](https://oauthenticator.readthedocs.io/en/latest/api/gen/oauthenticator.cilogon.html#oauthenticator.cilogon.CILogonOAuthenticator.allowed_idps).
```

5. Run the deployer as normal to apply the config.


### CILogon through Auth0
Expand Down
10 changes: 10 additions & 0 deletions docs/topic/hub-image.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ When this hub image needs to be updated, the steps to take are:
chartpress --push
```

````{note}
If you are on macOs wit M1, you need to run chartpress with [docker buildx](https://docs.docker.com/build/buildx/) under the hood and specify which platform to use, i.e. `amd64`.

```
chartpress --push --builder docker-buildx --platform linux/amd64
```

Ref: https://cloudolife.com/2022/03/05/Infrastructure-as-Code-IaC/Container/Docker/Docker-buildx-support-multiple-architectures-images/
````

- Commit the changes made by `chartpress` to `helm-charts/basehub/values.yaml`, but discard the changes made to `helm-charts/basehub/Chart.yaml` as the last may cause problems with the `daskhub` dependency mechanism.

```bash
Expand Down
2 changes: 1 addition & 1 deletion helm-charts/basehub/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ jupyterhub:
admin: true
image:
name: quay.io/2i2c/pilot-hub
tag: "0.0.1-n3636.h5f27d655"
tag: "0.0.1-n3784.hc740a271"
nodeSelector:
hub.jupyter.org/node-purpose: core
networkPolicy:
Expand Down
7 changes: 6 additions & 1 deletion helm-charts/images/hub/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
# quay.io container registry credentials configured to have access to
# https://quay.io/repository/2i2c/pilot-hub.
#
# Note: if on macOs wit M1, you need to run chartpress with docker buildx under the hood and specify
# the architecture to use.
# `chartpress --push --builder docker-buildx --platform linux/amd64`
# Ref: https://cloudolife.com/2022/03/05/Infrastructure-as-Code-IaC/Container/Docker/Docker-buildx-support-multiple-architectures-images/
#
FROM jupyterhub/k8s-hub:1.1.3-n644.h35436cda

ENV CONFIGURATOR_VERSION ed7e3a0df1e3d625d10903ef7d7fd9c2fbb548db
Expand All @@ -20,7 +25,7 @@ USER $NB_USER
RUN pip install --upgrade git+https://github.com/meeseeksmachine/jupyterhub@72e4119e1a9f5fead690cb399dba36143d6d2ecc

# Latest version comes with some breaking changes https://oauthenticator.readthedocs.io/en/latest/migrations.html#migrating-cilogonoauthenticator-to-version-15-0
RUN pip install --no-cache --upgrade oauthenticator==15.0.1
RUN pip install --no-cache --upgrade git+https://github.com/jupyterhub/oauthenticator@6cf6599d99b47f99db3826ceaaedf467af14a05d

USER root
RUN mkdir -p /usr/local/etc/jupyterhub-configurator
Expand Down