Manage groups

Who: JIMM controller admin

See also: Group

Preview an example workflow
# Create a group:
juju add-group A

# Verify that the group has been created successfully:
juju list-groups

# Give the members of the group write access to test-model-1:
juju add-permission group-B#member writer model-test-ctl-1/test-model-1

# Rename the role to something more suitable:
juju rename-group model-writers

# Add users to the group:
juju add-permission user-alice@canonical.com member group-A
juju add-permission user-bob@canonical.com member group-B

# Verify that user Alice has indeed inherited the group's write access to test-model-1:
juju check-permission user-alice@canonical.com writer model-test-ctl-1/test-model-1

# Create another group B and make members of group A also members of group B:
juju add-permission group-A#member member group-B
...

The sections below describe the JAAS groups workflow, which is still supported on the v3 track. For the IdP groups workflow and the migration from JAAS groups to IdP groups, see About IdP groups and Migrate from JAAS groups to IdP groups.

Add a group

To add a new group to your JIMM controller, use the add-group command followed by the name you want to assign to the group. For example:

juju add-group A

See more: juju add-group

View all the current groups

To view all the current groups, run the list-groups command. For example:

juju list-groups [options]

See more: juju list-groups

Add a user to a group

To add a user to a group, add a member permission between the user and the group. For example:

juju add-permission user-alice@canonical.com member group-mygroup
juju add-permission group-groupA#member member group-groupB
juju add-permission user-everyone@external member group-mygroup

Rename a group

To rename a group, run the rename-group command followed by the old name and the new name. For example:

juju rename-group TeamA TeamB

Remove a group

To remove a group from a JIMM controller, run the remove-group command followed by the name of the group. For example:

juju remove-group TeamB

About IdP groups

See also: Group

An IdP group is a group that is managed by your Identity Provider (IdP), not by JAAS. When a user logs in to JAAS, the IdP includes an extra claim in the access token that lists the groups the user belongs to. JAAS reads these claims and treats each value as an IdP group the user is a member of.

Compared to JAAS groups, the key difference is that JAAS no longer creates groups or assigns users to them. In JAAS you only assign permissions (e.g. administrator on a model) to an IdP group, then every user who logs in with that group claim inherits the permission automatically.

IdP groups are referenced using the idpgroup tag and require the #member userset, just like JAAS groups. For example:

# Grant administrator access on a model to every member of the "canonical" IdP group:
juju add-permission idpgroup-canonical#member administrator model-mycontroller/mymodel

Hook-service group lookup

The hook-service is a separate service in the Identity Platform’s infrastructure cluster. It exposes a gRPC API that JIMM can call to retrieve a user’s current IdP group memberships. JIMM obtains an access token from the IdP using the client ID and secret for JIMM’s OAuth client and the client-credentials grant, then sends that token as a bearer token to the hook-service. The client ID and secret are used with the IdP; they are not sent to the hook-service. JIMM’s current hook-service client uses gRPC without TLS, so configure a direct route to the hook-service over a protected internal network.

Where JIMM uses the hook-service

The hook-service provides JIMM with a user’s current IdP groups when JIMM needs to evaluate that user outside their own login session. JIMM calls the hook-service in these cases:

  • When JIMM checks a different user’s permissions from those of the logged-in user. This includes permission or relationship checks, such as juju check-permission, and looking up that user’s JIMM controller access.

  • When JIMM authorizes an SSH user, so that access granted through the user’s IdP groups can be considered.

  • When JIMM checks whether a user may consume a cross-model application offer during offer discharge.

For each lookup, JIMM asks the hook-service for groups associated with the user’s identifier and uses them for authorization checks. JIMM does not create or persist the groups.

If a lookup fails during a permission or relationship check, controller access lookup, or SSH authorization, that operation fails before it can complete the authorization check. A hook-service outage can therefore interrupt these operations even if the user might otherwise have direct access. Offer discharge is an exception: if a lookup fails, JIMM logs the failure and continues without the user’s group memberships, so group-based access cannot be established for that check.

The remaining known limitation is juju show-model, which does not list users whose access comes through IdP group membership.

Configure JIMM’s charm to accept group claims

There are two ways to configure JIMM’s charm for IdP group claims, and it depends on the way the Identity Platform was configured. If the identity platform was configured to emit the group claim by default you will need to change the oauth-group-claim-key charm config with the key where JIMM will find the group claim (e.g. groups). If the identity platform is configured to optionally offer the group claim then additionally configure both oauth-client-credential-scopes and oauth-optional-scopes (e.g. groups) to request group claims when authenticating client-credentials and users, respectively.

Configure the hook-service connection

Configure these JIMM charm options to enable the hook-service fetcher and tell JIMM where to connect:

idp-group-fetcher-type: hook-service
idp-hook-service-address: hook-service.internal:9090

idp-group-fetcher-type selects the group lookup implementation; set it to hook-service. Leave it empty to disable hook-service group fetching. idp-hook-service-address is the hook-service gRPC address in host:port form and is required when the fetcher type is hook-service. Replace the example address with the address of the hook-service that is reachable from JIMM.

The client_credentials grant must be enabled on the IdP side for JIMM’s OAuth client. It is not a JIMM charm option.

Migrate from JAAS groups to IdP groups

To migrate from JAAS groups to IdP groups, move group membership management to your IdP and replace JAAS group permission assignments with IdP-group permission assignments.

The high-level migration steps are:

  1. Configure your IdP to emit a group claim (e.g. groups) that contains the group names you want to use in JAAS. The exact configuration depends on your IdP (e.g. Canonical Identity Platform / Keycloak, Auth0, etc.).

  2. Map the existing JAAS groups in JAAS to the group names the IdP will emit. For each local group, make sure the IdP emits a group with a matching name, and assign the same users to that group in the IdP.

  3. Re-assign permissions from the local group to the IdP group. For every permission previously granted to group-<name>#member, grant the same permission to idpgroup-<name>#member.

  4. Remove the JAAS group permission assignments and the local group itself once the IdP group is in use and users have confirmed they inherit the expected access.

Terraform migration example

The following example shows how to migrate a typical local-group setup to IdP groups using the Terraform Provider for Juju.

Before — JAAS groups:

# Create a group in JAAS:
resource "juju_jaas_group" "test_group" {
  name = "test-group"
}

# Assign users to the JAAS group:
resource "juju_jaas_access_group" "development" {
  group_id = juju_jaas_group.test_group.uuid
  access   = "member"
  users    = ["jimm-group-user@canonical.com"]
}

# Grant the JAAS group administrator access on a model:
resource "juju_jaas_access_model" "development" {
  model_uuid = juju_model.test_model.uuid
  access     = "administrator"
  groups     = [juju_jaas_group.test_group.uuid]
}

After — IdP groups (v3 and v4):

# No juju_jaas_group or juju_jaas_access_group resources are needed.
# Group membership is managed by the IdP and sent as a claim at login.

# Grant the IdP group "canonical" administrator access on a model:
resource "juju_jaas_access_model" "development" {
  model_uuid = juju_model.test_model.uuid
  access     = "administrator"
  idp_groups = ["canonical"]
}

With the IdP groups setup:

  • There is no juju_jaas_group resource, the group is not created in JAAS.

  • There is no juju_jaas_access_group resource, user-to-group membership is managed by the IdP.

  • The juju_jaas_access_model resource uses idp_groups instead of groups to reference the IdP group by name.

Note

When you apply the migration, remove the juju_jaas_group and juju_jaas_access_group resources from your Terraform configuration and run terraform apply. Existing JAAS groups and their permission assignments can also be removed with the juju remove-group command once the IdP group permissions are in place.