Configuring CEL expressions for username and groups claim mapping

You can use Common Expression Language (CEL) expressions to construct usernames and groups from JWT token claims. This provides flexible claim mapping, including fallback logic when specific claims are not present.

Prerequisites
  • You have configured an external OIDC identity provider for direct authentication.

  • You have access to the cluster as a user with the cluster-admin role.

  • You have access to a long-lived authentication method, such as a certificate-based kubeconfig file.

  • You are familiar with CEL expression syntax.

Procedure
  1. Create a YAML file named authentication-cel-mapping.yaml with your CEL expression configuration:

    Important

    When using expression, do not set the claim field. You must use either claim or expression, but not both. Setting both will result in a validation error. Additionally, when using expression, do not set prefixPolicy to Prefix. Prefix policies are only compatible with claim-based mappings.

    Note

    When using the email claim in CEL expressions, you must also validate email_verified to ensure the email address has been verified by the identity provider.

    apiVersion: config.openshift.io/v1
    kind: Authentication
    metadata:
      name: cluster
    spec:
      type: OIDC
      oidcProviders:
      - name: my-oidc-provider
        issuer:
          issuerURL: https://idp.example.com
          audiences:
          - my-audience
        claimMappings:
          username:
            expression: 'claims.?upn.orValue(claims.?oid.orValue(claims.sub))'
          groups:
            expression: 'claims.?groups.orValue([])'
    # ...

    where:

    username.expression

    Specifies the fallback logic for username: upn if present, else oid, else sub.

    groups.expression

    Specifies that the groups claim is used if present, else an empty array.

    Note

    Replace the placeholder values (my-oidc-provider, https://idp.example.com, my-audience) with your actual OIDC provider configuration.

  2. Apply the configuration:

    $ oc apply -f authentication-cel-mapping.yaml
Verification
  • Verify that the authentication configuration is applied successfully:

    $ oc get authentication.config.openshift.io/cluster -o yaml
  • Authenticate with a user account and verify the username is constructed correctly:

    $ oc whoami
  • Monitor the cluster authentication Operator status:

    $ oc get clusteroperator authentication

    The Operator should report Available=True and Degraded=False.

Note

CEL expressions have access to standard CEL string functions (lowerAscii(), upperAscii(), contains(), startsWith(), endsWith(), matches(), split()), operators (+, ?, has(), ternary ? :), and the orValue() method for optional chaining. See the CEL specification link in Additional resources for the complete function reference.

You can use the following CEL expression patterns for claim mapping:

Use the optional chaining Operator ? to safely access claims that might not exist
username:
  expression: 'claims.email_verified ? claims.email : claims.sub'

Uses email if verified, otherwise sub. When using the email claim, you must also check email_verified.

Concatenate multiple claims
username:
  expression: 'claims.givenname + "." + claims.surname'

Combines given name and surname claims.

Transform claim values
username:
  expression: 'claims.email.lowerAscii()'

Converts email to lowercase.

Conditional logic for different user types
username:
  expression: 'has(claims.upn) ? claims.upn : claims.oid'

Uses upn for regular users, oid for service principals.

Extract domain from email
groups:
  expression: 'claims.?email.orValue("").split("@").size() > 1 ? [claims.email.split("@")[1]] : []'

Safely extracts domain from email address for group assignment, returning an empty array if email is missing or malformed.

Combine group sources
groups:
  expression: 'claims.?groups.orValue([]) + claims.?roles.orValue([])'

Combines groups and roles claims.