SQR-055: COmanage configuration for Rubin Science Platform

  • Russ Allbery

Latest Revision: 2022-07-15

1 Abstract

COmanage is a user management system designed for academic and research collaborations. Rubin Observatory will use COmanage (as provided by CILogon) as the user identity store and group management system for the Rubin Science Platform. This tech note provides the specific details of the COmanage configuration used by the Science Platform and summarizes remaining COmanage work.

Note

This is part of a tech note series on identity management for the Rubin Science Platform. The primary documents are DMTN-234, which describes the high-level design; DMTN-224, which describes the implementation; and SQR-069, which provides a history and analysis of the decisions underlying the design and implementation. See the references section of DMTN-224 for a complete list of related documents.

2 Configuration

2.1 Configure unique attribute for each person

CILogon generates a unique identifier for every authentication identity. COmanage may map multiple authentication identities to the same person record (so that someone can log in via both GitHub and their local university, for example, which are separate authentication identities). To resolve a login identity to a person in LDAP, those authentication identities must be present in the LDAP record. The recommended attribute in which to store them is uid, which is multivalued.

This means that a different attribute must be used for the unique identifier for each person. That attribute must not be multivalued. We use LSST Registry ID as that attribute.

  1. Go to Configuration → Extended Types

  2. Add an extended type:

    • Name: lsstregistryid

    • Display Name: LSST Registry ID

  3. Go to Configuration → Identifier Assignments

  4. Create an identifier assignment:

    • Description: LSST Registry ID

    • Context: CO Person

    • Type: LSST Registry ID (do not check the Login box)

    • Algorithm: Sequential

    • Format: LSST(#) (via “Select a common pattern”)

    • Permitted Characters: AlphaNumeric Only

    • Minimum: 1000000 (this doesn’t really matter but it will make all the identifiers the same length)

2.2 Configure LDAP provisioning target

Gafaelfawr requires the bare usernames be listed in an attribute in each group record so that they can be searched for. This is supported by the eduMember object class and the hasMember attribute.

We also need to put the user’s canonical username (which COmanage calls the UID) in some attribute in the person record so that we can query on it. We use voPersonApplicationUID for that purpose. Note that this is different than uid (the CILogon federated identity strings) and the unique attribute for each person used in the person data hierarchy (voPersonID).

Note that we use the preferred email and full name, not the official one. This must match the settings used during enrollment flow.

  1. Go to Configuration → Provisioning Targets and configure Primary LDAP

  2. Set “People DN Identifier Type” to LSST Registry ID

  3. Set “People DN Attribute Name” to voPersonId

  4. Go down to the attribute configuration

  5. Enable displayName, disable givenName, and set it to Preferred

  6. Change mail to Preferred

  7. Change uid to OIDC sub and select the box for “Use value from Organizational Identity”

  8. Enable groupOfNames objectclass

  9. Enable isMemberOf in the eduMember objectclass

  10. Enable hasMember in the eduMember objectclass and set it to UID

  11. Enable voPerson objectclass

    1. Enable voPersonApplicationUID and set it to UID

    2. Enable voPersonID and set it to LSST Registry ID

    3. Enable voPersonSoRID and set it to System of Record ID

  12. Save and then Reprovision All to update existing records

2.3 OpenID Connect client

The important configuration setting here is to map voPersonApplicationUID to the username claim. This is used by Gafaelfawr to get the username after authentication or, if that claim is not set, to know that the user is not enrolled in COmanage and to redirect to an enrollment flow.

  1. Go to Configuration → OIDC Clients

  2. Add a new client

  3. Set the name to a reasonable short description of the deployment

  4. Set the home URL to the top-level URL of the deployment

  5. Set the callback to the home URL with /login appended (the Gafaelfawr callback URL)

  6. Enable the org.cilogon.userinfo scope

  7. Add an LDAP to claim mapping

    • LDAP attribute name: voPersonApplicationUID

    • OIDC Claim Name: username

2.4 Add username to enrollment flow

Note that we use the preferred email and full name, not the official one. This must match the settings used during LDAP provisioning.

  1. Edit “Self Signup With Approval” enrollment flow

  2. Edit its enrollment attributes

  3. Edit the Name attribute, change its attribute definition to Preferred rather than Official, and make sure that only Given Name is required

  4. Edit the Email attribute and change its attribute definition to Preferred rather than Official

  5. Add username with a suitable description. Allow the user to change it during enrollment. Set the type of the field to CO Person, Identifier, UID. Mark as required.

This does not work for the “Invite a collaborator” enrollment flow, since the person creating the invite is prompted for the username (this is CO-1002). We probably won’t need that flow. If we do, we’ll need a separate enrollment flow plugin (which does not exist as a turnkey configuration, but there are examples to work from) to collect the username after email validation.

2.5 Username validation

Ensure the Regex Identifier Validator Plugin is enabled. Then:

  1. Go to Configuration → Identifier Validators and add a new validator

  2. Set the name to “Username validation”, the plugin to RegexIdentifierValidator, and the attribute to UID, and click Add

  3. Set the regular expression to:

    /^[a-z0-9](?:[a-z0-9]|-[a-z0-9])*[a-z](?:[a-z0-9]|-[a-z0-9])*$/
    

This implements the restrictions on valid usernames documented in DMTN-225.

2.6 Group name validation

One approach is to use the Group Name Filter Plugin. Ensure it is also enabled. Then:

  1. Go to Configuration → Extended Types and add a new type

  2. Set the name to “groupname” and the display name to “Group name”

  3. Go to Configuration → Data Filters and add a new filter

  4. Set the name to “Force group name validation” and the plugin to GroupNameFilter and click Add

  5. Set the identifier type to “Group name”

  6. Go to Configuration → Identifier Validators and add a new validator

  7. Set the name to “Username validation”, the plugin to RegexIdentifierValidator, and the attribute to UID, and click Add

  8. Set the regular expression to:

    /^g_[a-z0-9._-]{1,30}$/
    

This essentially replaces the group name with an identifier and requires that identifier to start with g_, which will avoid conflicts between usernames and groups. DMTN-225 defines the constraints on group names.

However, this doesn’t change the group creation flow. One has to explicitly go into the group and add the new Group name identifier.

A better approach would be a CakePHP plugin that intercepts the save call and can enforce a group naming convention. This would use the CakePHP Event System. This plugin does not already exist, but the CILogon folks have a previously-written plugin that is very similar and could adapt it to our needs.

3 API

3.1 LDAP

To make LDAP queries, use commands like:

$ ldapsearch -LLL -H ldaps://ldap-test.cilogon.org \
             -D 'uid=readonly_user,ou=system,o=LSST,o=CO,dc=lsst,dc=org' \
             -x -w PASSWORD -b 'ou=people,o=LSST,o=CO,dc=lsst,dc=org'

The password is in 1Password under the hostname of the COmanage registry. Use ou=people,o=LSST,o=CO,dc=lsst,dc=org for people and ou=groups,o=LSST,o=CO,dc=lsst,dc=org for groups.

3.2 COmanage REST API

Only the REST v1 API is currently available. The base URL is the hostname of the COmanage registry service with /registry appended.

We currently don’t expect to use the REST API.

4 Gafaelfawr

Here is an example configuration of the Gafaelfawr Helm chart to use CILogon and COmanage. This is suitable for the values-*.yaml file in Phalanx.

cilogon:
  clientId: "cilogon:/client_id/46f9ae932fd30e9fb1b246972a3c0720"
  enrollmentUrl: "https://registry-test.lsst.codes/registry/co_petitions/start/coef:6"
  usernameClaim: "username"

firestore:
  project: "rsp-firestore-dev-31c4"

ldap:
  url: "ldaps://ldap-test.cilogon.org"
  userDn: "uid=readonly_user,ou=system,o=LSST,o=CO,dc=lsst,dc=org"
  groupBaseDn: "ou=groups,o=LSST,o=CO,dc=lsst,dc=org"
  groupObjectClass: "eduMember"
  groupMemberAttr: "hasMember"
  userBaseDn: "ou=people,o=LSST,o=CO,dc=lsst,dc=org"
  userSearchAttr: "voPersonApplicationUID"

This uses the CILogon test LDAP server (a production configuration will probably use a different LDAP server) and links to an enrollment flow in a test version of COmanage.

5 Open COmanage work

  • Add a button or require authentication before confirming the email address to avoid a bug in the onboarding flow.

  • Write a CakePHP plugin to enforce a group naming convention.

  • COmanage comes with a bunch of default components that we don’t want to use (announcement feeds, forums, etc.). Edit the default dashboard to remove those widges and replace them with widges for group management and personal identity management (if there are any applicable ones).