Install Che on OpenShift with Keycloak as external identity provider

Install Che on an OpenShift cluster that uses Keycloak as an external OIDC identity provider for centralized user authentication.

Prerequisites
Procedure
  1. Define the environment variables:

    # The Keycloak namespace:
    KEYCLOAK_NAMESPACE=<KEYCLOAK_NAMESPACE>
    
    # The Keycloak realm used for OpenShift authentication:
    OPENSHIFT_REALM=<REALM>
    
    # The Keycloak URL
    KEYCLOAK_URL=https://$(kubectl get route keycloak -n $KEYCLOAK_NAMESPACE --template='{{ .spec.host }}')
  2. Create a eclipse-che client in the Keycloak Admin Console:

    1. Within the realm used for OpenShift authentication, select Clients on the left side of the navigation bar.

    2. Select the Create client button.

    3. On the General Settings page:

      1. Enter eclipse-che in the Client ID field.

      2. Optional: Enter a Name and Description for the OAuth client.

      3. Click Next.

    4. On the Capability config page:

      1. Toggle Client authentication to On.

      2. Click Next.

      3. Click Save.

    5. Navigate to the Credentials tab of the newly created client and copy the Client secret value for use when applying the OAuth client secret.

  3. Add the eclipse-che client to the audiences list in the OpenShift authentication configuration:

    kubectl patch authentication.config/cluster \
      --type='json' \
      -p='[
        {
          "op": "add",
          "path": "/spec/oidcProviders/0/issuer/audiences/-",
          "value": "eclipse-che"
        }
      ]'

    If you have multiple OIDC providers configured, adjust the array index in the path (currently 0) to match your Keycloak provider’s position in the configuration.

  4. Wait for the kube-apiserver cluster operator to roll out the configuration changes:

    watch kubectl get co kube-apiserver
  5. Create a namespace for Che:

    kubectl create namespace eclipse-che
  6. Create a secret for the OAuth client in the Che namespace:

    kubectl apply -f - <<EOF
    apiVersion: v1
    kind: Secret
    metadata:
      name: oauth-secret
      namespace: eclipse-che
      labels:
        app.kubernetes.io/part-of: che.eclipse.org
    stringData:
      oAuthSecret: <CLIENT_SECRET> (1)
    EOF
    1 The client secret value from the eclipse-che client in Keycloak.
  7. Optional: Create the ConfigMap with a Keycloak certificate in the eclipse-che namespace. If Keycloak uses a certificate that is already trusted by OpenShift, skip this step.

    openssl s_client \
      -connect "$(echo "$KEYCLOAK_URL" | sed 's|https://||'):443" \
      -showcerts < /dev/null \
    | sed -n '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/p' \
    > keycloak-ca.crt
    
    kubectl create configmap keycloak-certs \
        --from-file=keycloak-ca.crt=keycloak-ca.crt \
        -n eclipse-che && \
    kubectl label configmap keycloak-certs \
        app.kubernetes.io/part-of=che.eclipse.org \
        app.kubernetes.io/component=ca-bundle \
        -n eclipse-che
  8. Prepare the CheCluster patch:

    cat > che-patch.yaml << EOF
    kind: CheCluster
    apiVersion: org.eclipse.che/v2
    spec:
      networking:
        auth:
          oAuthClientName: eclipse-che
          oAuthSecret: oauth-secret
          identityProviderURL: "$KEYCLOAK_URL/realms/$OPENSHIFT_REALM"
          gateway:
            oAuthProxy:
              cookieExpireSeconds: 300
            deployment:
              containers:
                - name: oauth-proxy
                  env:
                    - name: OAUTH2_PROXY_CODE_CHALLENGE_METHOD
                      value: S256
                    - name: OAUTH2_PROXY_BACKEND_LOGOUT_URL
                      value: "$KEYCLOAK_URL/realms/$OPENSHIFT_REALM/protocol/openid-connect/logout?id_token_hint={id_token}"
      components:
        cheServer:
          extraProperties:
            CHE_OIDC_GROUPS__CLAIM: '<GROUPS_CLAIM>' (1)
            CHE_OIDC_GROUPS__PREFIX: '<GROUPS_PREFIX>' (2)
            CHE_OIDC_USERNAME__CLAIM: '<USERNAME_CLAIM>' (3)
            CHE_OIDC_USERNAME__PREFIX: '<USERNAME_PREFIX>' (4)
    EOF
    1 The claim to use for extracting user groups.
    2 The prefix to add to group names. Empty string means no prefix.
    3 The claim to use for extracting the username.
    4 The prefix to add to usernames from the external authentication system.

    These values must match the corresponding claim and prefix settings configured in the authentication.config/cluster resource. To view the current cluster configuration, run:

    kubectl get authentication.config/cluster -o yaml
  9. Create the Che instance with chectl:

    chectl server:deploy \
      --platform openshift \
      --che-operator-cr-patch-yaml che-patch.yaml
  10. Update a eclipse-che client to set Che callback URL:

    1. Open the Keycloak Admin Console.

    2. Within the realm used for OpenShift authentication, click the eclipse-che client.

      1. In the Valid redirect URIs field, enter the redirect URI for your Che installation. To obtain the redirect URI, run the following command:

        echo "$(kubectl get checluster eclipse-che -n eclipse-che -o jsonpath='{.status.cheURL}')/oauth/callback"
      2. Click Save.

  11. Create a ClusterRoleBinding to grant users access to Che:

    kubectl apply -f - <<EOF
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: openshift-developers
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: self-provisioner (1)
    subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: Group
      name: <GROUP_NAME> (2)
    EOF
    1 Users must have at least the self-provisioner role to access Che.
    2 The name of the user group from Keycloak that should be granted access to Che.
Verification
  1. Verify the Che instance status:

    chectl server:status
  2. Navigate to the Che cluster instance:

    chectl dashboard:open
  3. Log in to the Che instance.