Skip to main content
When you map what an application receives at sign-on - the Subject (NameID) for a SAML app, or the subject and claims for an OIDC app - each value is an IQL expression. IQL lets you pull from a user’s profile and reshape the value before it is sent.
IQL (Iru Query Language) is Iru’s expression language for mapping, used in several places:
  • The attributes and claims an application receives at sign-on.
  • The fields a connected source maps into your directory (see Attribute mapping).
  • Auto Group rules and list filters.
The same syntax works everywhere IQL appears.IQL is built on CEL (Common Expression Language), the open expression-language standard, so any expression that is valid in CEL is valid in IQL.
As you type, the mapping editor suggests the available fields, functions, and operators, and shows a live preview of the result. An expression must type-check in the editor and again when you save, so mistakes surface before they ever reach a sign-on or a sync.

Referencing your data

What you reference depends on where the expression runs:
  • Application mapping starts from the user object, whose fields are your directory’s profile attributes:
    user.email
    user.username
    user.id
    
    The defaults reflect this: an OIDC app’s subject defaults to user.id, and a SAML app’s Subject defaults to user.username.
  • Directory Sync mapping references the source’s field names directly, as they come from the connected system:
    email_work
    first_name
    
Field names are case-sensitive. Reach into nested values with a dot (user.profile.team), and into a list or map with [...] (covered below).

Building blocks

FormExampleWhat it is
Field / variablefirst_name, user.emailA value by name, or a field on a value.
Method calluser.email.upperAscii()A function called on a value.
Indexingparts[0]An element of a list by zero-based position.
Map keyentry["label"]The value stored under a string key.
Grouping(a + b) * cParentheses to control evaluation order.

Literals

"hello"                             // string (double quotes)
'hello'                             // string (single quotes)
42                                  // whole number
3.14                                // decimal number
true   false                        // booleans
null                                // null
["a", "b", "c"]                     // list
{"label": "work", "primary": true}  // map (string keys)
Strings support the usual escapes, such as \n, \t, \\, \", and \uXXXX.

Operators

OperatorExampleWhat it does
+first_name + " " + last_nameAdds numbers, or joins strings.
- * /a * bSubtract, multiply, divide.
%a % bRemainder (modulo).

Precedence

From tightest-binding to loosest. When in doubt, add parentheses.
1) a.b   a()   a[i]   ()      // member access, calls, indexing, grouping
2) !a    -a                   // unary not, negation
3) *  /  %                    // multiply, divide, remainder
4) +  -                       // add, subtract (and string +)
5) <  <=  >  >=  in           // comparison and membership
6) ==  !=                     // equality
7) &&                         // and
8) ||                         // or
9) ? :                        // conditional

String functions

String operations are written as methods on a value, in the form value.method(...):
MethodExampleWhat it does
upperAscii / lowerAsciiuser.email.lowerAscii()Upper- or lower-case the value.
trimfirst_name.trim()Remove surrounding whitespace.
splituser.email.split("@")Split into a list by a separator; index it with [n].
replacephone.replace("-", "")Replace every occurrence of one substring with another.
containsuser.email.contains("+")True if the value contains a substring.
startsWith / endsWithuser.email.endsWith("@acme.com")Test how the value begins or ends.
indexOfusername.indexOf(".")Position of a substring, or -1 if absent.
matchesuser.email.matches("^[a-z]+@acme\\.com$")True if the value matches a regular expression.
sizeuser.email.split("@").size()Length of a string or list. Also available as size(value).

Conditionals and defaults

The conditional operator is the simplest way to supply a fallback when a value might be blank:
// Use the first name, or fall back to the username when it's empty
user.firstName != "" ? user.firstName : user.username
For richer null handling, IQL also has optional (null-safe) helpers, below.

Optional values

Optional helpers let you work with values that might be missing without causing an error. An optional either holds a value or is empty.
optional.of(value)            // wrap a value as an optional
optional.ofNonZeroValue(value) // empty if the value is "zero" (see below)
optional.none()               // an empty optional
ofNonZeroValue treats these as empty: an empty string "", 0, false, an empty list [], an empty map {}, and null.
// A default when a field is empty
optional.ofNonZeroValue(first_name).orValue("anon")

// Split an email and safely take the domain, falling back to ""
optional.ofNonZeroValue(email_work).optMap(e, e.split("@"))[?1].orValue("")

Comments and whitespace

Whitespace is not significant, and // starts a comment that runs to the end of the line:
user.firstName + " " + user.lastName   // build a display name

Examples

// A field, as-is
user.email

// Upper-case the value
user.email.upperAscii()

// Build a display name from two fields
user.firstName + " " + user.lastName

// The local part of an email, before the "@"
user.email.split("@")[0]

// A field from the person's first address
user.addresses[0].city

// Choose a fallback when a field is blank
user.firstName != "" ? user.firstName : user.username

// A structured value, built as a map
{"email": user.email, "primary": true}
Use the preview in the mapping editor to confirm an expression produces what you expect before publishing - it renders the exact value Iru will send or store.

Where to go next

Application mapping

Map IQL values into the assertion or token an application receives.

Attribute mapping

Use the same IQL to map a connected source into your directory.

Auto Groups

Drive group membership from IQL rules over profile attributes.

Profile attributes

The user fields your expressions draw from.