Skip to main content

Background

When configuring workflows to automatically create and update access through Lumos, you may find yourself needing to reference attributes from the target user. For example:
  • When creating a username (setting it to first_name.last_name)
  • When assigning custom attributes in apps like Slack or Okta (team, title, manager)
  • When scheduling an action relative to a user’s start date (e.g. 2 days before)
  • When updating a last name (ensuring names remain aligned with values from the HRIS)
The Lumos Expression Language (LEL) allows you to reference user attributes, perform transformations, and build conditional logic directly within your workflows. Important: LEL uses its own syntax. It is not Python, JavaScript, or any other general-purpose programming language. Standard library functions like timedelta, isoformat(), or datetime are not available. This guide covers every function and operator that LEL supports.

What You Can Do With Expression Language

With Lumos Expression Language, you can:
  • Reference attributes from user identities in your workflows
  • Combine identity attributes with static text
  • Transform data with built-in functions (lowercase, uppercase, split, etc.)
  • Perform date arithmetic (add or subtract days/hours from dates)
  • Create conditional logic to handle different scenarios
  • Generate random values for temporary passwords or unique identifiers
  • Convert non-Latin characters to ASCII equivalents
  • Normalize country names to standard ISO codes
  • Skip setting an attribute entirely when a condition isn’t met

Syntax Basics

Referencing Identity Attributes

To reference an attribute from the user in your workflow, use the user object:
This returns the user’s email address. You can access any of the standard attributes listed in the Available Attributes section below.

The Pipe Operator (|)

LEL supports two ways to apply transformations: the pipe operator and method-call syntax. Both are equivalent — use whichever you find more readable.
For functions that take arguments:

String Concatenation

Use the + or ~ operator to combine values together. Both work the same way.

Static Text

Wrap static text in single or double quotes:

Available Attributes

Standard Attributes

These can be accessed directly on the user object:

Custom Attributes

Custom attributes defined in your Lumos settings are accessed via the custom_attributes field:

Groups

If your workflow context includes group information:

Operators

Comparison Operators

Logical Operators

String Operators


Conditional Logic

Inline If/Else

Use inline if/else to return different values based on a condition:
A more complex example with string concatenation:

Fallbacks with or

For simple “use this value if available, otherwise use that value” logic, the or operator is more concise:

Fallbacks with default

Use the default filter to provide a fallback value when an attribute might be missing or empty:

Skipping an Attribute with DO_NOT_SET

Sometimes you want to conditionally skip setting a value entirely — rather than setting it to an empty string. Use the special DO_NOT_SET sentinel:
When the expression evaluates to DO_NOT_SET, Lumos will skip the attribute update for that user entirely.

Data Transformations

String Transformations

Special Character Removal

strip_punc — Removes all punctuation characters from a string, including ASCII punctuation (!@#$%^&* etc.) and Unicode punctuation (fullwidth commas, curly quotes, Japanese brackets, etc.):
This would transform Jean-Pierre O'Connor into jeanpierre.oconnor@company.com. strip_chars — Removes only the specific characters you define:
This would transform Jean-Pierre into JeanPierre (hyphens removed, all other characters kept).

Transliteration

Convert non-Latin characters (Greek, Chinese, Cyrillic, etc.) to Latin/ASCII equivalents:
  • transliterate('Müller') → "Muller"
  • transliterate('Μαρία') → "Maria"
  • transliterate('张伟') → "zhangwei"
You can also pass a custom transliteration identifier for more control:
The default identifier (Any-Latin; Latin-ASCII;) converts from any script to ASCII.

Base64 Encoding

Encode a value as Base64 for systems that require it:
"john@example.com" → "am9obkBleGFtcGxlLmNvbQ=="

Date Arithmetic

LEL provides built-in filters for performing arithmetic on date values. These are the only way to manipulate dates in LEL — standard programming constructs like timedelta or isoformat() are not available.

add_days(n)

Adds a number of days to a date. Use negative numbers to subtract.

subtract_days(n)

Subtracts a number of days from a date.

add_hours(n)

Adds a number of hours to a date.

Combining Date Filters

You can chain date filters together:
This produces the date 2 days before the start date, at 9:00 AM.

Handling Missing Dates

All date filters gracefully handle missing dates — if the input date is None, the result is also None (no error). Combine with conditional logic if you need different behavior:

Current Timestamp

Get the current date and time with now():

Country Lookup

Normalize a country name or code to standard ISO format using lookup_country:
Useful with custom attributes:

Generating Random Values

Lumos supports generating cryptographically secure random values, useful for temporary passwords, unique IDs, and access codes.

random_string(length, charset?)

Generates a random string of the specified length. Defaults to alphanumeric characters if no charset is specified.
With a custom character set:
Built-in charset constants: Composing formats — use ~ to concatenate multiple random_string calls:
→ e.g. "XY654321" (2 uppercase letters + 6 digits) Maximum length: 50 characters per random_string call.

random_int(min, max)

Generates a random integer within an inclusive range.
Note: random_string and random_int generate a new value every time the expression is evaluated. They are ideal for temporary passwords or one-time codes, but not for values that need to be stable across runs.

Common Recipes

Generate a username from name

→ e.g. "jsmith"

Generate an email with preferred name fallback

Extract handle from email

Set a value 2 days before start date

Schedule for 9 AM, 2 days before start date

Create a clean email from names with special characters

Transliterate non-Latin names for provisioning

Conditionally set an attribute, or skip it

Generate a temporary password

→ e.g. "KXPM4821abcd"

Get the first 4 characters of an Employee ID (safely)


FAQs

What happens if an attribute I reference doesn’t exist? If you reference an attribute that doesn’t exist, the workflow step will fail and generate an Error Task in Lumos with details about the failure. Use the default filter or if/else logic to handle potentially missing attributes gracefully. Can I use expressions in all workflow actions? Yes. Expressions can be used in any input field for any workflow action that expects a “string” value. Why doesn’t timedelta, isoformat(), or datetime work? LEL is not Python. It uses its own set of built-in functions. For date manipulation, use add_days, subtract_days, and add_hours. For converting a date to a string, use | string. Can I reference attributes from connected systems (like Okta or AzureAD)? Yes, but you must first store them as custom attributes on the Identity in Lumos to use them in provisioning workflows. How do I handle names with special characters when creating email addresses? Use strip_punc to remove all punctuation, or strip_chars with specific characters to remove only certain ones. For non-Latin scripts, use transliterate. Are randomly generated values the same each time a workflow runs? No — random_string and random_int generate a new value every time the expression is evaluated. Can I use random_string to generate secure passwords? Yes. Lumos uses Python’s secrets module under the hood, which is cryptographically secure. What does DO_NOT_SET do? When an expression evaluates to DO_NOT_SET, Lumos skips the attribute update for that user entirely. This is different from setting the value to an empty string — DO_NOT_SET means “don’t touch this attribute at all.” How complex can my expressions be? While you can create fairly complex expressions combining multiple conditions and transformations, Lumos recommends keeping expressions reasonably simple for maintainability.

Other Questions?

Contact support@lumos.com or your CSM.