Introduction

Identity configuration management for Kubernetes is intended to allow you to quickly and easily configure OAuth authentication across your fleet of OpenShift clusters. Through the creation of an AuthRealm custom resource, you are able to specify one or more identity providers (such as GitHub or LDAP) and a placement rule to indicate to which clusters the identity providers should apply. As more clusters are brought under management, their OAuth configuration will be automatically configured simply by matching the specified placement rule. The existing OAuth configuration will be replaced by the configurations defined in the different AuthRealms. The existing OAuth configuration is saved in the cluster namespace and will be restored once the cluster is no longer under management.

An identity configuration management operator configuration is composed of:

  • A namespace in which the identity configuration will be defined

  • A managedclusterset custom resource which holds the managed clusters which may be part of the identity configuration.

  • A placement custom resource which defines the matching labels to select the clusters.

  • A managedclustersetbinding custom resource to bind that placement to the managedclusterset.

  • For each identity configuration provider, a secret custom resource containing the client ID and client secret to connect to the identity configuration provider.

  • An authrealm custom resource which defines the identiry configuration providers.

We will first walk through setting up your managed cluster set and placement, then prepare the configuration for your preferred identity provider(s).

Preparing your managed cluster set and placement

In order to add managed clusters to a managed cluster set, the managed clusters must be under management of the hub cluster. Follow these instructions if managed clusters need to be brought under management by the hub cluster:

Once there are managed clusters, create a managed cluster set and managedclustersetbinding. Then select the managed clusters that will be a part of the set:

Now a placement can be created. This will be used to determine which managed clusters in the managedclusterset will have the identity configuration applied. See:

Important

The identity configuration management for Kubernetes Technology Preview does not yet utilize custom role definitions for controlling access to work with AuthRealms. Instead, it relies on the role-based access control implemented by multicluster engine and Advanced Cluster Management around ManagedClusterSets, ManagedClusterSetBindings, and Placements. AuthRealms must exist in a namespace containing a Placement, and the Placement leverages the ManagedClusterSets that are bound to that namespace. Access to namespaces with existing bound ManagedClusterSets and/or existing Placements should be managed accordingly.

Important

If you are using v0.1.0, before detaching a cluster from the hub, you must make sure the managed cluster is no longer managed by identity configuration management. You can remove the cluster from identity configuration management either by removing the cluster from the ManagedClusterSet, or by removing labels from the managed cluster as appropriate to no longer match the Placement. Once your cluster no longer matches the Placement of any AuthRealm, your original OAuth configuration should be restored on the cluster. If the cluster is detached without first being unmanaged from identity provider management, you will lose access to the cluster.

If you are using v0.2.0 or higher, it is recommended that you follow the steps above to take the cluster out of identity configuration management prior to detaching the cluster from the hub. In this case, your original OAuth configuration should be restored for you on the managed cluster, and you can then detach the cluster from the hub. As an alternative, prior to detaching the managed cluster from the hub, you can copy your original OAuth from the ConfigMap named idp-oauth-original in the managed cluster’s namespace on the hub cluster. After the cluster is completely detached from the hub cluster, manually edit the OAuth on the cluster you’ve just detached and refer to the contents of the idp-oauth-original ConfigMap to restore your original OAuth configuration.

Creating your AuthRealm

The AuthRealm custom resoure specifies a combination of one or more identity providers and a placement that determines to which managed clusters the identity provider(s) should be applied.

An AuthRealm resource example is as follows:

apiVersion: identityconfig.identitatem.io/v1alpha1
kind: AuthRealm
metadata:
  name: identity-config-developers
  namespace: identity-config-authrealm
spec:
  identityProviders:
  - github:
      clientID: <Github OAuth client ID>
      clientSecret:
        name: identitatem-github-client-secret
      organizations:
      - identitatem
    mappingMethod: claim
    name: identitatem-developers
    type: GitHub
  placementRef:
    name: dev-clusters-placement
  routeSubDomain: identitatem-devs
  type: dex

The AuthRealm name becomes an identity provider name on each managed cluster to which the AuthRealm applies, and is therefore the label that will appear on the managed cluster OpenShift login button.

The identityProviders list values directly correspond to OpenShift Container Platform’s identity provider configuration. Only GitHub and LDAP are supported in this Technology Preview. Take special note of the mappingMethod field, which controls how mappings are established between the provider’s identities and User objects.

The placementRef contains the name of the Placement custom resource located in the same namespace as the AuthRealm that will determine to which clusters this AuthRealm will apply.

The routeSubDomain is used to form the Issuer URL of the intermediary OpenID connect server that is installed and configured automatically on the hub cluster by identity configuration management in order to achieve fleet-wide identity configuration. The managed clusters' cluster OAuth configurations connect to this OpenID connect server via the Issuer URL, rather than connecting to the desired identity provider directly.

Important

routeSubDomain must be unique among all AuthRealms on the hub cluster. It must be a max of 54 characters. It must meet the requirements of a DNS subdomain and therefore must also contain only lowercase alphanumeric characters, '-' or '.', and start and end with an alphanumeric character. Once specified, the routeSubDomain must not be modified. If you need to change this value, delete the AuthRealm and start again. These rules will be enforced in a future version of the operator, and failure to comply will result in unexpected results with the technology preview.

The type field must be set to dex for the Technology Preview. The Technology Preview leverages Dex under the covers as described above to achieve fleet-wide identity configuration.

The sections below outline more details and specific steps necessary to create your AuthRealm for GitHub or LDAP.

GitHub authentication

To use GitHub-based authentication, an OAuth application must be defined in GitHub.

GitHub OAuth

  1. The GitHub Oauth app can be created in your personal profile or in a Github organization that you are an administrator for.

  2. Add a New OAuth App. In the new OAuth app, Generate a new client secret. Copy the Client ID and Client Secret values and save them. They will be needed later.

  3. Fill in the Application name with something to help identify the owner and hub it will be used for. NOTE: If you have more than one hub, each one will need its own OAuth app.

  4. Fill in Homepage URL and Authorization callback URL with the OpenShift console URL. (NOTE: A little bit later we will correct the Authorization callback URL value once we have the proper value.)

  5. Click Register Application NOTE: Leave this web page open so you can quickly correct the Authorization callback URL value once you have the proper value.

AuthRealm custom resource for GitHub

With your GitHub OAuth app created and your client id and secret in hand, you are ready to create your AuthRealm custom resource.

An example of an AuthRealm custom resource configured for the Github identity provider is provided below. Make note of the identityProviders field and the configuration of the github identity provider under it:

apiVersion: identityconfig.identitatem.io/v1alpha1
kind: AuthRealm
metadata:
  name: identity-config-developers
  namespace: identity-config-authrealm
spec:
  identityProviders:
  - github:
      clientID: <Github OAuth client ID>
      clientSecret:
        name: identitatem-github-client-secret
      organizations:
      - identitatem
    mappingMethod: claim
    name: identitatem-developers
    type: GitHub
  placementRef:
    name: dev-clusters-placement
  routeSubDomain: identitatem-devs
  type: dex

The identityProviders list contains the configurations for one or more identity providers. The example above contains a single identity provider (GitHub). An entry under identityProviders has the following fields:

  • name contains the unique name that is used to identify the identity provider.

  • type specifies the identity provider type and it is set to GitHub.

  • mappingMethod (add, claim or lookup) controls how mappings are established between this provider’s identities and User objects.

  • github contains the GitHub specific configurations:

    • clientID contains the client ID of a registered GitHub OAuth application.

    • clientSecret contains a reference to a secret object containing the client secret of a registered GitHub OAuth application. Example secret:

      oc create secret generic <github-oauth-clientID-name> --from-literal=clientSecret=<github-oauth-clientID-secret>
    • organizations contains a list of organizations to authenticate the user against (authentication against specific teams within GitHub organizations is currently not supported). This field can be left blank to skip authentication against specific GitHub organizations. If organizations are specified in the config then the user must be a member of at least one of the specified orgs.
      Note: If the GitHub OAuth application is not owned by an organization specified in organizations, an organization owner must grant third-party access to use this option. This can be done in two ways:

      • by the GitHub organization’s administrator from the GitHub organization settings,

      • or, during the first GitHub login when the user will be presented with a UI to explicitly request access to the GitHub organization. The request will flow to the GitHub organization’s administrator for approval and the user will only be able to login after the request for access is approved.

To create your AuthRealm, copy the sample yaml above and update as appropriate with your client id and secret, GitHub organization(s) (if desired), and preferred names, namespace, route subdomain, and mapping method. Then, run the following command on your hub cluster:

oc create -f <authrealm_file_name>.yaml

With your AuthRealm created, you are ready to update your GitHub OAuth app’s authorization callback URL. Leverage the routeSubDomain you specified in your AuthRealm, and run the script below while logged in to your hub cluster to generate the proper value:

export ROUTE_SUBDOMAIN=<your_route_subdomain>
export APPS=$(oc get infrastructure cluster -ojsonpath='{.status.apiServerURL}' | cut -d':' -f2 | sed 's/\/\/api/apps/g')
echo "Authorization callback URL: https://${ROUTE_SUBDOMAIN}.${APPS}/callback"

At this point, any managed cluster that matches your Placement should be updated with an OAuth configuration that leverages an OpenID identity provider to connect to the proxy server that identity configuration management has stood up under the covers. Allow several minutes for the new login button to appear on your managed cluster.

LDAP authentication

LDAP

The LDAP identity provider configuration allows email/password based authentication backed by a LDAP directory. During authentication, the LDAP directory is searched for an entry that matches the provided user name. If a single unique match is found, a simple bind is attempted using the distinguished name (DN) of the entry plus the provided password.

Setting up LDAP:

There are multiple options available for setting up an LDAP directory. For example:

AuthRealm custom resource for LDAP

An example of an AuthRealm custom resource configured for the LDAP identity provider is provided below. Make note of the identityProviders field and the configuration of the ldap identity provider under it:

apiVersion: identityconfig.identitatem.io/v1alpha1
kind: AuthRealm
metadata:
  name: authrealm-ldap
  namespace: authrealm-ldap-ns
spec:
  type: dex
  routeSubDomain: identitatem-devs
  placementRef:
    name: authrealm-ldap-placement
  ldapExtraConfigs:
    openldap:
      baseDN: "dc=example,dc=com"
      filter: "(objectClass=person)"
  identityProviders:
    - name: openldap
      type: LDAP
      mappingMethod: add
      ldap:
        url: <LDAP server URL>
        insecure: false
        bindDN: cn=Manager,dc=example,dc=com
        ca:
          name: authrealm-ldap-ca
          namespace: authrealm-ldap-ns
        bindPassword:
          name: authrealm-ldap-secret
          namespace: authrealm-ldap-ns
        attributes:
          id:
            - DN
          preferredUsername:
            - mail
          name:
            - cn
          email:
            - mail

The identityProviders list contains the configurations for one or more identity providers. The example above contains a single identity provider (LDAP). An entry under identityProviders has the following fields:

  • name contains the unique name that is used to identify the identity provider.

  • type specifies the identity provider type and it is set to LDAP.

  • mappingMethod (add, claim or lookup) controls how mappings are established between this provider’s identities and User objects.

  • ldapExtraConfigs contains extra server configuration setting for LDAP, the key being the idp.name

    • baseDN contains information to start the LDAP user search from. For example "cn=users,dc=example,dc=com"

    • filter contains optional filter to apply when searching the directory. For example "(objectClass=person)"

  • ldap contains the LDAP specific configurations:

    • url contains the LDAP host and search parameters to use. The url syntax is ldap://host:port/basedn?attribute?scope?filter

    • insecure must be false. ldaps:// URLs will attempt to connect using TLS, and ldap:// URLs will be upgraded to TLS. The identity configuration management operator does not support insecure=true.

    • bindDN contains an optional DN to bind with during the search phase.

    • bindPassword contains an optional reference to a secret by name containing a password to bind with during the search phase. Note: bindDN and bindPassword need to be provided if the LDAP server requires authentication for search.

    • ca contains reference to the secret containing a trusted Root CA file - file name and format: "ca.crt" Note: If the server uses self-signed certificates, include files with names "tls.crt" and "tls.key" (representing client certificate and key) in the same secret

  • attributes maps LDAP attributes to identities

    • id is the attribute whose value should be used as the user ID. Required. Only the first attribute is used; all other values are ignored. If the first attribute does not have a value, authentication fails. LDAP standard identity attribute is "dn".

    • preferredUsername is currently ignored by the identity configuration management operator.

    • name is the attribute whose values should be used as the display name. Required. Only the first attribute is used; all other values are ignored. LDAP standard display name attribute is "cn".

    • email is the attribute whose values should be used as the email address. Required. Only the first attribute is used; all other values are ignored.

To configure group search for LDAP provider, please refer https://identitatem.github.io/idp-mgmt-docs/groups

To create your AuthRealm, copy the sample yaml above and update as appropriate with your ldap configuration, preferred names, namespace, route subdomain, and mapping method. Then, run the following command on your hub cluster:
oc create -f <authrealm_file_name>.yaml

At this point, any managed cluster that matches your Placement should be updated with an OAuth configuration that leverages an OpenID identity provider to connect to the proxy server that identity configuration management has stood up under the covers. Allow several minutes for the new login button to appear on your managed cluster. You will be able to login with the ldap user.

OpenID authentication

Version 0.3.1 of the technology preview introduces limited support for integrating with OpenID Connect identity providers. We have only tested the integration with dex, Keycloak, and Red Hat Single Sign-On.

NOTE: When integrating with Keycloak, ensure the Keycloak client has default or optional client scopes enabled for email and profile.

AuthRealm custom resource for OpenID

An example of an AuthRealm custom resource configured with an OpenID identity provider is provided below. Make note of the identityProviders field and the configuration of the opeinid identity provider under it:

apiVersion: identityconfig.identitatem.io/v1alpha1
kind: AuthRealm
metadata:
  name: authrealm-openid
  namespace: authrealm-openid-ns
spec:
  placementRef:
    name: dev-clusters-placement
  routeSubDomain: identitatem-devs
  type: dex
  identityProviders:
    - name: identitatem-developers
      mappingMethod: add
      type: OpenID
      openID:
        clientID: <OpenID client ID>
        clientSecret:
          name: identitatem-openid-client-secret
        claims:
          preferredUsername:
            - username
          name:
            - name
          email:
            - mail
        issuer: <openid auth URL>

The identityProviders list contains the configurations for one or more identity providers. The example above contains a single identity provider (OpenID). An entry under identityProviders has the following fields:

  • name contains the unique name that is used to identify the identity provider.

  • type specifies the identity provider type and it is set to OpenID.

  • mappingMethod (add, claim or lookup) controls how mappings are established between this provider’s identities and User objects.

  • openID contains the OpenID specific configurations:

    • clientID contains the client ID of a client registered with the OpenID provider.

    • clientSecret contains a reference to a secret object containing the OpenID client secret. Example secret:

      oc create secret generic <openid-oauth-clientID-name> --from-literal=clientSecret=<openid-oauth-clientID-secret>
  • claims maps attributes on the user entry.

    • preferredUsername is the list of attributes whose values should be used as the preferred username. Optional. If unspecified, the preferred username is determined from the value of the sub claim. OpenShift supports an array of preferredUsername, but identity configuration management for Kubernetes is only supporting the first value from the array.

    • name is the list of attributes whose values should be used as the display name. Optional. If unspecified, no display name is set for the identity. OpenShift supports an array of name, but identity configuration management for Kubernetes is only supporting the first value from the array.

    • email is the list of attributes whose values should be used as the email address. Optional. If unspecified, no email is set for the identity. OpenShift supports an array of email, but identity configuration management for Kubernetes is only supporting the first value from the array.

  • issuer the URL of the OpenID authentication provider.

To create your AuthRealm, copy the sample yaml above and update as appropriate with your OpenID configuration, preferred names, namespace, route subdomain, and mapping method. Then, run the following command on your hub cluster:

oc create -f <authrealm_file_name>.yaml

At this point, any managed cluster that matches your Placement should be updated with an OAuth configuration that leverages an OpenID identity provider to connect to the proxy server that identity configuration management has stood up under the covers. Allow several minutes for the new login button to appear on your managed cluster. You will be able to login with the OpenID authentication.

Using a custom certificate

By default, identity configuration management stands up an OpenID Connect proxy service that leverages the hub cluster’s default ingress certificate. You can instead utilize a custom certificate by adding the following two fields to the AuthRealm spec:

spec:
  certificatesSecretRef:
    name: acme-cert
  host: https://identitatem-devs.acme.com

Create a tls secret containing your custom certificate in the same namespace as your AuthRealm and provide the secret name in certificatesSecretRef.name. For host, specify the full URL of the domain you want created for the OpenID Connect proxy service, including the https:// protocol.

When creating the tls secret, be sure to specify the tls type. For example:

kubectl create secret tls <acme-cert> --cert=<path/to/cert/file>  --key=<path/to/key/file>

Note: When you specify a host URL, the routeSubDomain is used only for creating an OpenShift project on your hub cluster to hold resources pertaining to the AuthRealm. It is not reflected in the OpenID Connect proxy service issuer URL.

Command line interface

AuthRealm configuration can be created through the cm-cli.

cm create authrealm --values <values.yaml>
  1. Fill the template form

    The template can be retreived by running:

    cm create authrealm -h

    Fill the template and save it as for example my-authrealm.yaml

    authRealm:
      # The name of the authrealm, can be override using the --name parameter
      name:
      # The namespace where the authrealm must be created, can be override using the --namespace
      namespace:
      #The strategy type, only dex is supported, can be override using --type
      type: dex
      # The routeSubDomain to use, can be override using --route-sub-domain
      routeSubDomain:
      # The placement rule to use, if not present then a new one will be created
      # in the authrealm namespace and having for labelSelector the matchLabels below.
      # It can be overridden using --placement
      placement:
      # The matchLabels to use to build the placement if not provided
      # For example:
      # matchLabels:
      #  authdeployment: east
      matchLabels:
      # The managedClusterSet to link the placement to, can be override using --cluster-set
      managedClusterSet:
      # The managedClusterSetBinding, if not present then it will be created to bind
      # the provided placement with the managedClusterSet
      # It can be overridden using --cluster-set-binding
      managedClusterSetBinding:
      # The list of identity providers
      identityProviders:
      # Example for github, this section will be copied into the authrealm CR.
      # Reference: https://github.com/openshift/api/blob/master/config/v1/0000_10_config-operator_01_oauth.crd.yaml#L80
      # The identity provider name
      - name: my-github-idp
        # The mappingMethod could be add, claim or lookup
        mappingMethod: claim
        # The identity provider type, here GitHub
        type: GitHub
        # The github specifics
        github:
          # The client ID of the github app
          clientID:
          # The github app secret, the cm-cli will create a local secret with it
          clientSecret:
          # Lists of GitHub Organizations (optionals)
          organizations:
          - myorg
        #,,,,
      # Example for LDAP, this section will be copied into the authrealm CR.
      # Reference: https://github.com/openshift/api/blob/master/config/v1/0000_10_config-operator_01_oauth.crd.yaml#L215
      # The identity provider name
      - name: my-ldap-idp
        # The mappingMethod could be add, claim or lookup
        mappingMethod: claim
        # The identity provider type, here LDAP
        type: LDAP
        # The ldap specifics
        ldap:
          # The LDAP server url
          url:
          # The bind Domain name
          bindDN:
          # The bind password, the cm-cli will create a local secret with it
          bindPassword:
        #....
      # Extra supported ldap configuration for the dex server
      #
      ldapExtraConfigs:
        # The name of the ldap identity provider
        my-ldap-idp:
          # The base Domain name
          baseDN:
          filter:
  2. Create the authrealm

    1. Create directly

      cm create authrealm --values my-authrealm.yaml
    2. Create a file and then apply

      Options --dry-run with --output-file can be used to get the rendered file

      cm create authrealm --values my-authrealm.yaml --dry-run --output-file my-authrealm-yamls.yaml

      Then the my-authrealm-yamls.yaml can be applied using

      oc apply -f my-authrealm-yamls.yaml