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

Adding security.shared_users_group option for default users group #1056

Merged
merged 2 commits into from
Feb 12, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
23 changes: 0 additions & 23 deletions docs/source/dev_guide/minikube.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,29 +199,6 @@ Then, initialize the configuration file `qhub-config.yaml` with:
```shell
python -m qhub init local --project=thisisatest --domain github-actions.qhub.dev --auth-provider=password --terraform-state=local
```
## Generate user password
For each user on the `qhub-config.yaml` file needs a password.
A random password is auto generated for the user `example-user` when
the auth provider `password` is run, the value is then printed to the standard output (stdout).

In case you would like to change the generated password (optional), You can use [bcrypt](https://pypi.org/project/bcrypt/) to generate your own salted password by using the following _Python command_ script:

```bash
python -c "import bcrypt; print(bcrypt.hashpw(b'admin', bcrypt.gensalt()).decode('utf-8'))"
```

`<password>` can be changed to any desired value. This requires the Python package `bcrypt` to be installed in your virtual environment. The password is added to the `qhub-config.yaml` in the users section.

```yaml
users:
example-user:
uid: 1000
...
password: '$2b$12$lAk2Bhw8mu0QJkSecPiABOX2m87RF8N7vv7rBw9JksOgewI2thUuO'
...
primary_group: users

```

## Deploy and render the infrastructure

Expand Down
59 changes: 9 additions & 50 deletions docs/source/installation/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,43 +242,20 @@ security:

### User and group management

It's still possible to specify `users` and `groups` in the YAML file - in older versions of QHub, all users had to be specified in this way.
Groups and users of QHub are all defined in Keycloak. As above, access Keycloak as the `root` user, noting that the `root` user is not actually a QHub user - you cannot access the main features of QHub such as JupyterLab with at user. It is only for Keycloak management.

If specifying users/groups in this way, you can also manually add more users/groups in Keycloak. However, be aware that if users/groups were initially created based on entries in the YAML file, those users/groups will be destroyed if `qhub deploy` is ever run without those users/groups in the file. They may also be recreated after you delete them manually in Keycloak.

Any user is assigned a `primary_group` and optionally
any number of `secondary_groups`.

```yaml
security:
users:
example-user:
primary_group: users
secondary_groups:
- billing
password: plaintextpasswd
dharhas:
primary_group: admin
groups:
users:
admin:
billing:
```

* The `primary_group` is the group name assigned to files that are
written for the user.
* `groups` are a mapping of group name to an empty map (no entries are required within that map any longer).
* `security.shared_users_group` is an optional key (default False) which
optionally adds all users to a default group named `users`. Only new
users created after this option is enabled will be added to the
`users` group. You will have to manually add existing users to the
`users` group if you chose to enable this option later.

#### Admin and Users Group

The admin group has special significance. If a user's `primary_group`
is admin they will be able to access the jupyterhub admin page. The
admin page allows a user to stop user's servers and launch a given
The admin group has special significance in QHub, and will always be automatically created in Keycloak in every deployment. If a user is a member of the Keycloak `admin` group they will be able to access the jupyterhub admin page. The admin page allows a user to stop user's servers and launch a given
user's server and impersonate them.

All users must be a member of the `users` group.

Both `admin` and `users` groups will be created even if not specified in the YAML file.
If `security.shared_users_group` is `true` then all users will become members of the `users` group.

## Provider Infrastructure

Expand Down Expand Up @@ -815,25 +792,7 @@ security:
client_id: CLIENT_ID
client_secret: CLIENT_SECRET

users:
example-user:
primary_group: users
secondary_groups:
- billing
dharhas:
primary_group: admin
tonyfast:
primary_group: admin
prasunanand:
primary_group: admin
aktech:
primary_group: users
secondary_groups:
- admin
groups:
users:
admin:
billing:
shared_users_group: true

digital_ocean:
region: nyc3
Expand Down
11 changes: 0 additions & 11 deletions docs/source/installation/existing.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,6 @@ security:
client_id:
client_secret:
oauth_callback_url: https://<domain_name>/hub/oauth_callback
users:
example_user:
uid: 1000
primary_group: admin
secondary_groups:
- users
groups:
users:
gid: 100
admin:
gid: 101
default_images:
jupyterhub: quansight/qhub-jupyterhub:v0.3.13
jupyterlab: quansight/qhub-jupyterlab:v0.3.13
Expand Down
16 changes: 2 additions & 14 deletions docs/source/installation/management.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,9 @@

## Add users to QHub

One of the first things you might want to do is to **add new users** to your QHub. Any type of supported authorization from Auth0 can be used as a username. Below is an example configuration of two users:
One of the first things you might want to do is to **add new users** to your QHub.

```yaml
joeuser@example.com:
uid: 1000000
primary_group: users
secondary_groups:
- billing
- admin
janeuser@example.com:
uid: 1000001
primary_group: users
```

As seen above, each username has a unique `uid` and a `primary_group`. Optional `secondary_groups` may also be set for each user. This can be done through the Keycloak web console. See [Adding a QHub user](./login.md#adding-a-qhub-user) for details.
This can be done through the Keycloak web console. See [Adding a QHub user](./login.md#adding-a-qhub-user) for details.

## Upgrades and dependencies management

Expand Down
3 changes: 3 additions & 0 deletions qhub/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,9 @@ def provision_06_kubernetes_keycloak_configuration(stage_outputs, config, check=
"realm_display_name", realm_id
),
"authentication": config["security"]["authentication"],
"default_project_groups": ["users"]
if config["security"].get("shared_users_group")
else [],
},
)

Expand Down
1 change: 1 addition & 0 deletions qhub/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ class Keycloak(Base):

class Security(Base):
authentication: Authentication
shared_users_group: typing.Optional[bool]
keycloak: typing.Optional[Keycloak]


Expand Down
17 changes: 17 additions & 0 deletions qhub/template/stages/06-kubernetes-keycloak-configuration/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,20 @@ resource "keycloak_group" "groups" {
realm_id = keycloak_realm.main.id
name = each.value
}

resource "keycloak_group" "project_groups" {
for_each = var.default_project_groups
realm_id = keycloak_realm.main.id

name = each.value
parent_id = keycloak_group.groups["projects"].id
}


resource "keycloak_default_groups" "default" {
realm_id = keycloak_realm.main.id
group_ids = [
for g in var.default_project_groups:
keycloak_group.project_groups[g].id
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,9 @@ variable "authentication" {
description = "Authentication configuration for keycloak"
type = any
}

variable "default_project_groups" {
description = "Set of groups that should exist by default"
type = set(string)
default = []
}
3 changes: 3 additions & 0 deletions qhub/upgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ def _version_specific_upgrade(
if "users" in security:
del security["users"]
if "groups" in security:
if "users" in security["groups"]:
# Ensure the users default group is added to Keycloak
security["shared_users_group"] = True
del security["groups"]

# Create root password
Expand Down