Configure an external authentication provider (preview)

Set up Azure Red Hat OpenShift with hosted control planes to use an external OpenID Connect (OIDC) identity provider for authentication instead of the built-in OpenShift OAuth server. While the built-in OAuth server supports various identity providers, it has limited capabilities. By integrating external OIDC identity providers directly with Azure Red Hat OpenShift with hosted control planes, you can enable machine-to-machine workflows, like CLI access, and gain features unavailable with the built-in OAuth server.

This article describes how to configure Microsoft Entra ID as an external authentication provider to provide access to both the CLI and the OpenShift console.

Prerequisites

Prepare environment variables

Make sure that the following environment variables are defined:

SUBSCRIPTION_ID=$(az account show --query id --output tsv)
CUSTOMER_RG_NAME="<resource-group-name>"
CLUSTER_NAME="<cluster-name>"
EXTERNAL_AUTH_DISPLAY_NAME="${CLUSTER_NAME}-auth"
EXTERNAL_AUTH_NAME="entra"
TENANT_ID=$(az account show --query tenantId --output tsv)
ISSUER_URL="https://login.microsoftonline.com/${TENANT_ID}/v2.0"

Configure Microsoft Entra ID

  1. Retrieve the OpenShift Authentication callback URL.

    CONSOLE_URL=$(az aro hcp cluster show \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --name "${CLUSTER_NAME}" \
      --query properties.console.url --output tsv)
    OAUTH_CALLBACK_URL="${CONSOLE_URL}/auth/callback"
    
  2. Register a new application in Microsoft Entra ID. To access the API server through the oc or kubectl CLIs, add a second redirect URI.

    The following example creates a Microsoft Entra ID application with two redirect URIs: the required OpenShift Authentication callback URL, and a second redirect for CLI access:

    CLIENT_ID=$(az ad app create \
      --display-name "${EXTERNAL_AUTH_DISPLAY_NAME}" \
      --web-redirect-uris ${OAUTH_CALLBACK_URL} http://localhost:8000 \
      --query appId --output tsv)
    
  3. Create a client secret for the application. A console message notifies you that the command output contains credentials. Use the client secret later in this article.

    Note

    After you complete all steps in this article, clear the variable. See Clean up sensitive variables.

    CLIENT_SECRET=$(az ad app credential reset --id ${CLIENT_ID} --query password --output tsv)
    

Configure claims

To provide OpenShift with group membership information, configure Microsoft Entra ID to include a groups optional claim in the tokens it issues. For more information about optional claims, see Configure and manage optional claims in ID tokens, access tokens, and SAML tokens.

  1. Create a manifest.json file to configure the optional claims.

    The following example configures the groups optional claim:

     cat > manifest.json <<EOF
     { 
      "idToken": [
        {
          "name": "groups",
          "source": null,
          "essential": false,
          "additionalProperties": []
        }
      ],
      "accessToken": [
        {
          "name": "groups",
          "source": null,
          "essential": false,
          "additionalProperties": []
        }
      ],
      "saml2Token": [
        {
          "name": "groups",
          "source": null,
          "essential": false,
          "additionalProperties": []
        }
     ]
    }
    EOF
    
  2. Update the Microsoft Entra ID application to use the optional claims that you defined in the manifest.

    az ad app update \
    --id ${CLIENT_ID} \
    --optional-claims @manifest.json
    
  3. Enable Group membership claims for the app registration.

    To ensure that your application receives information about a user’s group memberships, update the groupMembershipClaims property of the application registration manifest.

    az ad app update \
    --id ${CLIENT_ID} \
    --set groupMembershipClaims=SecurityGroup
    

Create an external authentication provider

The following claim mappings show OpenShift how to read the preferred_username and groups claims that you configured Microsoft Entra ID to emit.

  1. Retrieve the API URL.

    API_URL=$(az aro hcp cluster show \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --name "${CLUSTER_NAME}" \
      --query properties.api.url --output tsv)
    
  2. Create the external authentication provider for Azure Red Hat OpenShift with hosted control planes.

    az aro hcp cluster external-auth create \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --cluster-name "${CLUSTER_NAME}" \
      --name "${EXTERNAL_AUTH_NAME}" \
      --issuer-url "${ISSUER_URL}" \
      --issuer-audience "[${CLIENT_ID}]" \
      --claim groups \
      --username-claim preferred_username \
      --username-prefix-policy NoPrefix \
      --clients "[{client-id:${CLIENT_ID},component:{name:console,auth-client-namespace:openshift-console},extra-scopes:[profile],type:Confidential},{client-id:${CLIENT_ID},component:{name:cli,auth-client-namespace:openshift-console},extra-scopes:[profile],type:Public}]"
    
  3. Verify the external authentication provider configuration.

    az aro hcp cluster external-auth show \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --cluster-name "${CLUSTER_NAME}" \
      --name "${EXTERNAL_AUTH_NAME}"
    
  1. Retrieve the API URL.

    API_URL=$(az aro hcp cluster show \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --name "${CLUSTER_NAME}" \
      --query properties.api.url --output tsv)
    
  2. Configure the external authentication provider for Azure Red Hat OpenShift with hosted control planes. To configure an external authentication provider, define an externalAuths resource. The following example shows an externalAuths resource in a Bicep file. For more information about the external authentication provider properties, see External authentication configuration properties.

    Save the following example as externalauth.bicep:

    @description('The name of the external auth provider configuration')
    param externalAuthName string
    
    @description('The issuer url')
    param issuerURL string
    
    @description('The client ID')
    param clientID string
    
    @description('Name of the hypershift cluster')
    param clusterName string
    
    resource hcp 'Microsoft.RedHatOpenShift/hcpOpenShiftClusters@2026-09-01-preview' existing = {
      name: clusterName
    }
    
    resource externalauth 'Microsoft.RedHatOpenShift/hcpOpenShiftClusters/externalAuths@2026-09-01-preview' = {
      parent: hcp
      name: externalAuthName
      properties: {
        claim: {
          mappings: {
            username: {
              claim: 'preferred_username'
              prefixPolicy: 'NoPrefix'
            }
            groups: {
              claim: 'groups'
            }
          }
        }
        clients: [
          {
            clientId: clientID
            component: {
              name: 'console'
              authClientNamespace: 'openshift-console'
            }
            extraScopes: [
              'profile'
            ]
            type: 'Confidential'
          }
          {
            clientId: clientID
            component: {
              name: 'cli'
              authClientNamespace: 'openshift-console'
            }
            extraScopes: [
              'profile'
            ]
            type: 'Public'
          }
        ]
        issuer: {
          url: issuerURL
          audiences: [
            clientID
          ]
        }
      }
    }
    
  3. Apply the Bicep file.

    az deployment group create \
    --name 'aro-hcp-auth' \
    --subscription "${SUBSCRIPTION_ID}" \
    --resource-group "${CUSTOMER_RG_NAME}" \
    --template-file externalauth.bicep \
    --parameters \
       externalAuthName="${EXTERNAL_AUTH_NAME}" \
       issuerURL="${ISSUER_URL}" \
       clientID="${CLIENT_ID}" \
       clusterName="${CLUSTER_NAME}"
    
  4. Verify the external authentication provider configuration.

    az aro hcp cluster external-auth show \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --cluster-name "${CLUSTER_NAME}" \
      --name "${EXTERNAL_AUTH_NAME}"
    

Configure authentication and authorization in OpenShift

After creating the external authentication provider, sign in to your Azure Red Hat OpenShift with hosted control planes cluster to configure access for your confidential client (the OpenShift console) and set up role-based access control (RBAC).

  1. If you don't have a temporary administrative credential for your Azure Red Hat OpenShift with hosted control planes cluster, generate one. For more information, see Access the cluster.

    Your cluster doesn't use the built-in OpenShift OAuth server to act as a separate identity provider. This configuration means there's no standalone cluster-admin account for accessing the cluster. Instead, you must request a temporary administrative credential, which provides a kubeconfig with cluster-admin privileges.

    oc create secret generic ${EXTERNAL_AUTH_NAME}-console-openshift-console \
    --namespace openshift-config \
    --from-literal=clientSecret=${CLIENT_SECRET}
    
  2. (Optional) If necessary, assign users and groups to your Azure Red Hat OpenShift with hosted control planes cluster.

    By default, all users in the Microsoft Entra tenant can access registered applications after authenticating successfully. Microsoft Entra ID allows tenant administrators and developers to restrict an app to a specific set of users or security groups in the tenant.

    To restrict a Microsoft Entra app to a specific set of users, see Restrict a Microsoft Entra app to a set of users.

  3. Configure RBAC for your cluster.

    By default, OpenShift doesn't grant permissions to take any action inside of your cluster when a user first signs in. Azure Red Hat OpenShift with hosted control planes includes a significant number of preconfigured roles, including the cluster-admin role that grants full access and control over the cluster. The cluster doesn't automatically create RoleBinding and ClusterRoleBinding objects for authenticated users; you are responsible for creating those bindings yourself.

    This example shows how to create a ClusterRoleBinding object that grants a specific Microsoft Entra ID user the cluster-admin role. You can also create a role binding for a security group by following the instructions in Using RBAC.

  4. Retrieve the user principal name of the user to whom you want to grant access.

    USER_NAME=$(az ad user show --id "<user-email>" --query userPrincipalName -o tsv)
    
  5. Create the ClusterRoleBinding object to grant the user access to the cluster-admin role.

    oc apply -f - <<EOF
    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: aro-admin
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
    subjects:
    - apiGroup: rbac.authorization.k8s.io
      kind: User
      name: $USER_NAME
    EOF
    

Validate the external authentication configuration

After setting up external authentication for your cluster, you can validate the configuration for the OpenShift CLI and web console.

Validate access to the OpenShift web console

  1. Retrieve the URL for the OpenShift web console.

    az aro hcp cluster show \
      --resource-group "${CUSTOMER_RG_NAME}" \
      --name "${CLUSTER_NAME}" \
      --query properties.console.url --output tsv
    
  2. Open the URL in your web browser and sign in.

Validate access to the OpenShift CLI

You can use Microsoft Entra ID to sign in to the OpenShift command-line tool. This authentication method works because the kubelogin client-go credential plugin is now built directly into the tool.

  1. Sign in to the cluster by running the following command:

    oc login $API_URL \
      --exec-plugin=oc-oidc \
      --client-id=$CLIENT_ID \
      --client-secret=$CLIENT_SECRET \
      --issuer-url=$ISSUER_URL \ 
      --extra-scopes=profile \
      --callback-port=8000
    

    The command displays a URL. Use the URL to complete the authentication process in your browser. When you finish, the OpenShift CLI is authenticated.

  2. Verify that your credentials are set properly:

    oc auth whoami 
    

    Example output:

    ATTRIBUTE    VALUE
    Username     user@email.com
    Groups       [<group-id> system:authenticated]
    

Clean up sensitive variables

After you verify that external authentication is working, clear the sensitive variables from your shell session.

CLIENT_SECRET=""