Zum Hauptinhalt springen

CEL Functions - Wissensdatenbank / Verschiedenes - Bare.ID - Support

CEL Functions

Autorenliste
  • Theresa Henze
  • Tolleiv Nietsch

What is CEL (Common Expression Language)?

CEL is a simple yet powerful language for defining expressions and rules. It is often used in applications to implement custom logic without the need to write complex code. CEL is especially useful in scenarios where flexibility and adaptability are required.

Bare.ID uses CEL in various areas:

  • User Profile Validator (“CEL Program”)
  • Login Provider Mapper (“CEL Attribute Mapper”)
  • Application Mapper
    • for OIDC (“CEL claim”)
    • for SAML (“CEL claim”)

General Helper Functions

There are macros from the CEL language definition as well as the following commonly used CEL extensions available:

Area Functions
Strings charAt(), indexOf(), lastIndexOf(), trim(), replace(), reverse(), split(), substring(), join(), upperAscii(), lowerAscii(), quote()
Lists slice(), flatten(), range(), distinct(), reverse(), sort(), sortBy(), last(), first()
Sets contains(), intersects()
Regex replace(), extract(), extractAll(), matches()
Mathematical Functions greatest(), least(), bitAnd(), bitXor(), bitNot(), bitShiftLeft(), bitShiftRight(), ceil(), floor(), round(), trunc(), abs(), sign(), isInf(), isNaN(), isFinite(), sqrt()
Optional has()
Bind bind()
Comprehensions all(), exists(), existsOne(), transformList(), transformMap(), transformMapEntry()

Additionally, the following functions are available in all CEL expressions. These tables are automatically generated from the source code and are therefore always up to date — even newly added functions appear here automatically, without the need to update this page.

base64.decode

base64.decode(string) -> string

Decodes a standard base64 string back to its original UTF-8 string.

base64.encode

base64.encode(string) -> string

Encodes a UTF-8 string to standard base64.

base64.encode(bytes) -> string

Encodes a byte string to standard base64.

errorCase

errorCase(bool, string) -> cel.v1.ValidatorResponse

Adds a single validation error with the given message key if the boolean condition is true.

Note:: This function is only available for the “User Profile Validator”.

errorCases

errorCases(map<string, bool>) -> cel.v1.ValidatorResponse

Adds one validation error per map entry whose message-key entry key has a true boolean condition value.

UserModel.getFirstAttribute

cel.v1.UserModel.getFirstAttribute(string) -> string

Returns the first value of the given user attribute, or an empty string if the attribute is not set.

groups.getById

groups.getById(string) -> optional_type<cel.v1.GroupModel>

Looks up a single group by its ID. Returns an empty optional if no such group exists.

groups.getFirstByName

groups.getFirstByName(string) -> optional_type<cel.v1.GroupModel>

Returns the first group whose name contains the given substring, or an empty optional if none match.

groups.listByName

groups.listByName(string) -> list<cel.v1.GroupModel>

Searches groups (including subgroups) whose name contains the given substring.

guid.toByteArray

guid.toByteArray(string) -> bytes

Converts a UUID string to its 16-byte binary representation (RFC 4122 mixed-endian byte order used by Microsoft-style GUIDs).

http.call

http.call(cel.v1.HttpServiceCallRequest) -> cel.v1.HttpServiceCallResponse

Performs an outbound HTTP request (GET/POST/PUT/PATCH/DELETE) and returns the response status, headers, and body.

json.decode

json.decode(string) -> google.protobuf.Value

Parses a JSON string into a dynamic value (object, array, string, number, bool, or null).

Example: json.decode('{"key": "value"}')map('key': 'value')

json.encode

json.encode(dyn) -> string

Serializes a value (map, list, string, number, bool, or null) to a compact JSON string.

Example: json.encode(map('key': 'value'))'{"key": "value"}'

query

cel.v1.SqlDatasource.query(string) -> cel.v1.SqlQueryResult

Runs a SQL query against the datasource returned by sql() and returns the result rows.

Example:

sql("myDatasource").query("SELECT id, name FROM my_table WHERE status = 'active'")

cel.v1.SqlDatasource.query(string, list<dyn>) -> cel.v1.SqlQueryResult

Runs a parameterized SQL query (positional ? placeholders bound from the given list) against the datasource returned by sql() and returns the result rows.

Example:

sql("myDatasource").query("SELECT id, name FROM my_table WHERE status = ?", ["active"])

roles.getById

roles.getById(string) -> optional_type<cel.v1.RoleModel>

Looks up a single realm or client role by its ID. Returns an empty optional if no such role exists.

roles.getFirstByName

roles.getFirstByName(string) -> optional_type<cel.v1.RoleModel>

Returns the first realm or client role whose name contains the given substring, or an empty optional if none match.

roles.listByName

roles.listByName(string) -> list<cel.v1.RoleModel>

Searches realm and client roles whose name contains the given substring.

secret

secret(string) -> string

Returns the value of the named CEL secret (configured per-realm via the Bare.ID app-frontend), or fails if no secret with that name is configured.

secretOrDefault

secretOrDefault(string, string) -> string

Returns the value of the named CEL secret, or the given fallback if no secret with that name is configured.

sql

sql(string) -> cel.v1.SqlDatasource

Resolves a named SQL datasource (configured on the Keycloak server) so it can be queried with query(). Fails if no active datasource with that name exists.

Example:

sql("myDatasource").query("SELECT id, name FROM my_table WHERE status = ?", ["active"])

url.decode

url.decode(string) -> string

Decodes percent-encoded (%XX) sequences. A + is left as-is; use url.decodeQuery to decode form-encoded query parameters.

url.decodeQuery

url.decodeQuery(string) -> string

Decodes a query parameter name or value: both %XX sequences and + as a space.

url.encode

url.encode(string) -> string

Percent-encodes a value so it can be used as a single component of a URL (RFC 3986), e.g. a path segment. A space becomes %20.

url.encodeQuery

url.encodeQuery(string) -> string

Percent-encodes a value for use as a query parameter name or value (application/x-www-form-urlencoded, i.e. a space becomes +).

Example: url.encodeQuery('a b')'a+b'

users.getById

users.getById(string) -> optional_type<cel.v1.UserModel>

Looks up a single user by its ID. Returns an empty optional if no such user exists.

users.getByLoginName

users.getByLoginName(string) -> optional_type<cel.v1.UserModel>

Looks up a single user by their login name (email if the realm uses email as username, otherwise username). Returns an empty optional if no such user exists.

validatedAttributeEntry

validatedAttributeEntry(string, list<string>) -> cel.v1.AttributeEntry

Shortcut helper function to use in CEL Validators.

Runs the configured user-profile validators for the given attribute key against the provided values, throwing on failure, and returns a validated AttributeEntry.

Warning: Do not encode API keys or other secrets directly in CEL expressions. If your mapper needs to call a protected remote service, contact support so that the secret can be managed through a managed configuration.

User Profile Validator

Validation functions use CEL expressions to check input values and report errors.

Available Variables and Return Value:

ValidatorRequest — User Profile Field Validator

Field Type Description
value string
field string

ValidatorResponse

Field Type Description
errors ValidationError[]

ValidationError

Field Type Description
message_key string

The helper errorCase/errorCases are listed in the section “General Helper Functions”.

Note: Validation functions throw errors with a translation key. This key must be defined in the translations so that the error message is displayed correctly for the available languages. See the manual, chapter Translations.

Examples:

Full notation: throws error input.not.test if the input value is not test.

ValidatorResponse{
  errors: [
    value == 'test' ? ValidationError{} : ValidationError{message_key: 'input.not.test'}
  ]
}

Shorthand notation: throws error error.expected.not.test if the input value is test.

errorCase(value == 'test', 'error.expected.not.test')

Multiple errors: throws if the input value is less than or equal to 5, or greater than or equal to 10.

errorCases(
  {
    'error.lesser.than.expected': int(value) <= int(5),
    'error.greater.than.expected': int(value) >= int(10)
  }
)

Login Provider Mapper

Pre-Processing

This defines how the username and email address for login are selected from the data provided by the external provider. This ensures that the correct information is used for login.

This happens before the “First Broker Login” flow is called.

Available Variables and Return Value:

IdentityProviderPreprocessorRequest

Field Type Description
brokered_identity_context BrokeredIdentityContext
claims google.protobuf.Struct The upstream claims merged from the access token, the ID token and the

UserInfo claim set - the same three sources Keycloak’s own oidc-user-attribute-idp-mapper reads. On a conflicting top level claim the access token wins over the ID token, which wins over UserInfo. (Keycloak resolves each claim path individually, so for a nested path it may fall back to a lower precedence source where this merge lets the higher one win.) |

IdentityProviderPreprocessorResponse

Field Type Description
username string evaluated in preprocessFederatedIdentity before first broker login flow
email string evaluated in preprocessFederatedIdentity before first broker login flow

BrokeredIdentityContext

Field Type Description
id string
username string
model_username string
email string
first_name string
last_name string
broker_session_id string
broker_user_id string
token string
context_data google.protobuf.Struct IdentityProviderModel idp_config = 10;

IdentityProvider idp = 11; The raw context data Keycloak keeps on the brokered identity, e.g. VALIDATED_ACCESS_TOKEN, VALIDATED_ID_TOKEN, UserInfo, FEDERATED_ACCESS_TOKEN_RESPONSE or user.attributes.<name>. Entries whose value cannot be represented as JSON (such as a SAML assertion) are omitted. |

Beispiele:

Maps the username and email address.

IdentityProviderPreprocessorResponse{
    username: 'username',
    email: 'test@example.com'
}

Mapping attributes and assigning roles and groups

Available Variables and Return Value:

IdentityProviderMapperRequest — Identity Provider Mapper

Field Type Description
brokered_identity_context BrokeredIdentityContext roles and groups are provided as functions
claims google.protobuf.Struct The upstream claims merged from the access token, the ID token and the

UserInfo claim set - the same three sources Keycloak’s own oidc-user-attribute-idp-mapper reads. On a conflicting top level claim the access token wins over the ID token, which wins over UserInfo. (Keycloak resolves each claim path individually, so for a nested path it may fall back to a lower precedence source where this merge lets the higher one win.) |

IdentityProviderMapperResponse

Field Type Description
attributes AttributeEntry[]
role_uuids string[]
group_uuids string[]

BrokeredIdentityContext

Field Type Description
id string
username string
model_username string
email string
first_name string
last_name string
broker_session_id string
broker_user_id string
token string
context_data google.protobuf.Struct IdentityProviderModel idp_config = 10;

IdentityProvider idp = 11; The raw context data Keycloak keeps on the brokered identity, e.g. VALIDATED_ACCESS_TOKEN, VALIDATED_ID_TOKEN, UserInfo, FEDERATED_ACCESS_TOKEN_RESPONSE or user.attributes.<name>. Entries whose value cannot be represented as JSON (such as a SAML assertion) are omitted. |

AttributeEntry

Field Type Description
key string
values string[]

Helper functions for looking up groups (groups.*), roles (roles.*), and users (users.*) are listed above in the section “General Helper Functions”.

Examples:

Maps multiple attributes and assigns roles and groups.

IdentityProviderMapperResponse{
    attributes: [
        AttributeEntry{
          key: 'my-attribute',
          values: ['val1', 'val2']
        },
        AttributeEntry{
          key: 'broker-attribute',
          values: [brokered_identity_context.id]
        }
    ],
    role_uuids: ['role-uuid-1'],
    group_uuids: ['group-uuid-1']
}

Using a helper function to look up groups by name.

IdentityProviderMapperResponse{
    group_uuids: groups.listByName('editor').map(g, g.id)
}

LDAP Attribute Mapper

Mapper for LDAP-connected directories: This defines how a single attribute is synchronized between the LDAP directory and the local Bare.ID user. There are two directions, each configurable with its own CEL expression.

LDAP → Local

Evaluated when importing or reconciling a user from the LDAP directory to determine the value for the local user attribute.

Available Variables and Return Value:

LdapUserAttributeToLocalMapperRequest

Field Type Description
attribute_value string
realm RealmModel
is_create bool

LdapUserAttributeToLocalMapperResponse

Field Type Description
value string

RealmModel

Field Type Description
id string
name string

Example:

Copies the LDAP value unchanged.

LdapUserAttributeToLocalMapperResponse{value: attribute_value}

Local → LDAP

Evaluated when writing a local user attribute back to the LDAP directory.

Available Variables and Return Value:

LdapUserAttributeFromLocalMapperRequest

Field Type Description
attribute_value string
local_user UserModel
realm RealmModel

LdapUserAttributeFromLocalMapperResponse

Field Type Description
value string

UserModel

Field Type Description
id string
username string
attributes AttributeEntry[]
groups GroupModel[]

AttributeEntry

Field Type Description
key string
values string[]

GroupModel — OIDC and SAML Protocol Mappers

Field Type Description
id string
name string
full_path string

RealmModel

Field Type Description
id string
name string

Example:

Copies the local value unchanged.

LdapUserAttributeFromLocalMapperResponse{value: attribute_value}

Application Mapper

OIDC

Mapper for OpenID Connect (OIDC) claims: This defines how user attributes are embedded in the OIDC token issued to applications. This ensures that applications receive the necessary information about the user.

Available Variables and Return Value:

OIDCProtocolMapperRequest

Field Type Description
user_session UserSessionModel ProtocolMapperModel mappingModel = 1;

ClientSessionContext clientSessionCtx = 4; |

OIDCProtocolMapperResponse

Field Type Description
claim_value google.protobuf.Value Number value means long value, no floating point values possible

UserSessionModel

Field Type Description
user UserModel

UserModel

Field Type Description
id string
username string
attributes AttributeEntry[]
groups GroupModel[]

GroupModel — OIDC and SAML Protocol Mappers

Field Type Description
id string
name string
full_path string

AttributeEntry

Field Type Description
key string
values string[]

Examples:

Maps a boolean value.

OIDCProtocolMapperResponse{
  claim_value: has(user_session.user.username)
}

Maps a numeric value.

OIDCProtocolMapperResponse{
  claim_value: size(user_session.user.username)
}

Maps a text value.

OIDCProtocolMapperResponse{
  claim_value: user_session.user.id
}

Maps a list of values.

OIDCProtocolMapperResponse{
  claim_value: [
    user_session.user.id,
    user_session.user.username
  ]
}

Maps a map/JSON object.

OIDCProtocolMapperResponse{
  claim_value: {
    'id': user_session.user.id,
    'username': user_session.user.username
  }
}

SAML

Mapper for SAML attributes and NameID: This defines how user attributes are embedded in the SAML attribute statement issued to applications. This ensures that applications receive the necessary information about the user.

SAMLProtocolMapperResponse contains either the value of the attribute (attribute_value) or the value for the NameID (mapper_name_id).

Available Variables and Return Value:

SAMLProtocolMapperRequest

Field Type Description
user_session UserSessionModel string nameIdFormat = 1;

ProtocolMapperModel mappingModel = 2; KeycloakSession session = 3;

AuthenticatedClientSessionModel clientSession = 5; |

SAMLProtocolMapperResponse

Field Type Description
attribute_value string
mapper_name_id string

UserSessionModel

Field Type Description
user UserModel

UserModel

Field Type Description
id string
username string
attributes AttributeEntry[]
groups GroupModel[]

GroupModel — OIDC and SAML Protocol Mappers

Field Type Description
id string
name string
full_path string

AttributeEntry

Field Type Description
key string
values string[]

Examples:

Maps an attribute value.

SAMLProtocolMapperResponse{attribute_value: 'test'}

Maps the NameID.

SAMLProtocolMapperResponse{mapper_name_id: 'test'}