All pages
Powered by GitBook
1 of 6

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Fallback Formatters

Configure fallback formatters for uniquely identifying attributes during identity synchronization

Overview

Fallback formatters can help resolve conflicts when provisioning identities with unique attributes. This is particularly useful when automated provisioning requires unique identifiers, but the standard generated values are already in use.

Understanding Fallback Formatters

When provisioning new identities through Lifecycle Management, unique attributes like usernames, login IDs, or email addresses must not conflict with existing values. Fallback formatters provide an automated way to generate alternative values when conflicts arise, ensuring provisioning can proceed without manual intervention.

You can configure fallback formatters when configuring a to ensure new users can be onboarded efficiently, regardless of naming conflicts.

Use Case: Username Conflicts

The most common use case for fallback formatters is handling username conflicts. For example:

Your organization uses a standard username format of first initial + last name (e.g., jsmith for John Smith).

When multiple employees have similar names, this can lead to conflicts:

  • John Smith already has jsmith

  • Jane Smith already has jsmith1

  • James Smith already has jsmith2

When Jennifer Smith joins, the fallback formatter automatically assigns jsmith3, maintaining your naming convention while ensuring uniqueness.

Configuring Fallback Formatters

Fallback formatters can be configured as part of the "Sync Identities" action within a Lifecycle Management workflow:

  1. Edit or create a Lifecycle Management policy

  2. Edit the workflow containing the Sync Identities action

  3. In the Sync Identities action configuration, click Add Fallback

  4. Configure the to use as a fallback pattern for the unique attribute that might experience conflicts

Transformer Options for Fallback Formatters

Several transformers can be used for implementing fallback formatters depending on your specific use case.

Using the NEXT_NUMBER Transformer

A typical approach is to use the NEXT_NUMBER transformer, which is specifically designed to generate sequential numerical alternatives when naming conflicts occur.

The NEXT_NUMBER transformer:

  • Generates a set of sequential integers as strings

  • Takes two parameters: BeginInteger (starting number) and Length (how many numbers to generate)

  • Is unique among transformers in that it returns multiple values, making it ideal for fallback scenarios

Other Useful Transformers for Fallbacks

In addition to NEXT_NUMBER, other transformers can be valuable for creating fallback formatters:

Using Random Alphanumeric for Unique Usernames:

This could generate usernames like jsmith8f3d instead of sequential jsmith1, jsmith2, etc.

Using UUID for Guaranteed Uniqueness:

This would append the first 8 characters of a UUID, creating identifiers like jsmith-a7f3e9c2.

Implementation Example

When configuring a fallback formatter with the NEXT_NUMBER transformer:

  1. Select the attribute that requires uniqueness (e.g., username, email)

  2. Configure the primary pattern (e.g., {first_initial}{last_name})

  3. Add a fallback using the NEXT_NUMBER transformer to generate sequential alternatives:

This will generate up to 10 alternatives: jsmith1, jsmith2, ... jsmith10

Common Fallback Patterns

Here are some commonly used fallback patterns:

Primary Format
Fallback Pattern
Examples

How Fallback Resolution Works

When Lifecycle Management attempts to provision a new identity with a unique attribute value that already exists:

  1. The system first tries the primary format (e.g., jsmith)

  2. If a conflict is detected, it automatically tries the first alternative using the NEXT_NUMBER transformer (e.g., jsmith1)

  3. If that value also exists, it tries the next alternative (e.g., jsmith2)

This automated conflict resolution ensures provisioning can proceed without manual intervention, even when your standard naming conventions result in conflicts.

Close the action sidebar and save your changes to the policy.

This process continues until either:

  • A unique value is found

  • All alternatives from the NEXT_NUMBER range are exhausted (in which case an error would be reported)

{first_initial}{last_name}

{first_initial}{last_name}{NEXT_NUMBER(1, 10)}

jsmith, jsmith1, jsmith2, etc.

{first_name}.{last_name}

{first_name}.{last_name}{NEXT_NUMBER(1, 10)}

john.smith, john.smith1, john.smith2

{username}@domain.com

{username}{NEXT_NUMBER(1, 10)}@domain.com

[email protected], [email protected]

{first_name}{last_initial}

{first_name}{last_initial}{NEXT_NUMBER(1, 10)}

Sync Identities Action
Transformer

johns, johns1, johns2

{first_initial}{last_name}{RANDOM_ALPHANUMERIC_GENERATOR(4)}
{first_initial}{last_name}-{UUID_GENERATOR() | SUB_STRING,0,8}
{first_initial}{last_name}{NEXT_NUMBER(1, 10)}

Transformer Reference

Reference guide for supported transformation functions and parameters for attribute transformers

This page includes a comprehensive list of all supported transformer functions and parameters. Some commonly used transformation functions include:

  • Replacing a character with a different one

  • Removing domains from email addresses

  • Transforming to upper, lower, camel, or snake case

  • Using a substring from the original value

See for more information about using attribute transformers to update or create attributes in downstream systems based on changes in your source of identity.

Understanding the Attribute Transformer Interface

When configuring attribute transformers in Lifecycle Management policies, you work with three key fields:

Destination Attribute

A Destination Attribute is a target-system attribute that Lifecycle Management creates or updates (e.g., email, username, first_name).

Lifecycle Management uses the Destination Attribute when you build a transformer or Sync/Deprovision action. You select a Destination Attribute (from the target entity type), then supply a Formatter (a fixed value, a {source_attribute}, or a transformation pipeline). Destination Attributes can be configured for continuous sync, used by action-level or common transformers, and referenced with $target inside the same action.

Formatter

A Formatter defines the exact value or expression used to populate a target attribute (Destination Attribute) when provisioning or syncing identities.

Formatters can be a fixed literal, a reference to a source-of-identity attribute (e.g., {first_name}), or an expression that applies transformation functions and pipelines (e.g., {email | REMOVE_DOMAIN | LOWER}).

They're configured on transformers used by Sync/Deprovision actions and control continuous sync behavior, fallbacks, and uniqueness.

The base transformation expression that defines how to construct the attribute value. This field can contain:

  • Source attribute references: {first_name}, {email}

  • Static text and source attributes combined: {first_name}.{last_name}@company.com

  • Static values only: "Veza" or true

Pipeline Functions

A Pipeline Function is a chained sequence of attribute formatters that run in order using the pipe (|) operator.

Pipeline Functions take the output of one formatter as the input to the next, letting you build multi-step transformations (for triggers, transformers, and formatter fields). They are used in workflow trigger conditions and transformer attributes to normalize, format, or compute values (for example: {department | TRIM | UPPER} or {hire_date | DATE_FORMAT, "2006-01-02"}).

Optional transformation functions applied after the Formatter. Multiple functions are chained using the pipe (|) character, with each function's output becoming the next function's input. Examples:

  • | LOWER

  • | ASCII | REMOVE_WHITESPACE

  • | TRIM_CHARS, "." | UPPER

At runtime, Veza combines the {Formatter}{Pipeline Functions} fields to create the complete transformation.

Reading the Examples

Each transformer below includes three types of examples:

  1. Basic Usage: Shows the transformer used alone with a simple source attribute

  2. In a Pipeline: Demonstrates chaining multiple transformers together

  3. Example: Provides practical context from Lifecycle Management scenarios

Copy-paste these examples directly into your attribute transformer configuration, adjusting attribute names to match your source of identity.

APPEND

APPEND

This transformer enables string concatenation by appending text to the end of attribute values during identity provisioning workflows.

Parameter Format

Characters (STRING, required)

Basic Usage

ASCII

ASCII

Removes non-printable characters and replaces non-ASCII characters with their closest ASCII equivalents. Particularly useful for Active Directory sAMAccountName and other legacy systems with strict character requirements.

Note: The ASCII transformer performs operations on the base level, not the extended set.

Parameter Format

ASSUME_TIME_ZONE

ASSUME_TIME_ZONE

Interprets the incoming time string as if it were in the specified time zone, then converts it to a UTC time. (example: if the input is "1/2/2025 11pm" and the defined time zone is "America/Los_Angeles" the function will treat "1/2/2025 11pm" as local time in Los Angeles and output the corresponding UTC time "1/3/2025 7am")

Parameter Format

String - Time Zone String (Optional) - Format

COUNTRY_CODE_ISO3166

COUNTRY_CODE_ISO3166

Transforms country code to ISO 3166 format.

defines codes for the representation of country names, dependent territories, and their subdivisions

Parameter Format

DATE_ADJUST

DATE_ADJUST

Adjusts date value based on date and day.

Parameter Format

Integer - date

Integer - day

DATE_ADJUST_DAY

DATE_ADJUST_DAY

Adjusts date value based on hour, day, month, year inputs provided (example: 2021-01-01 00:00:00 with a DATE_ADJUST of "+1,2,3,-1" becomes "2020-04-03 01:00:00").

Parameter Format

Integer - date

Integer - hour

DATE_FORMAT

DATE_FORMAT

Transforms dates to a different format using Go time layout syntax. Essential for LDAP integration and standardizing dates across systems.

Parameter Format

Output Layout (STRING, required): Go time layout for output format Input Layout (STRING, optional): Go time layout for input format

FIRST_N

FIRST_N

Picks the first N characters of a string. Useful for creating shortened identifiers or initials.

Parameter Format

Length (NUMBER, required): Number of characters to return

Basic Usage

FROM_ENTITY_ATTRIBUTE

FROM_ENTITY_ATTRIBUTE

Transforms a string from an attribute of another entity in the graph.

Parameter Format

EntityType (STRING, required)

SourceAttribute (STRING, required),

LANGUAGE_RFC5646

LANGUAGE_RFC5646

Transforms language to RFC 5646 format.

defines "Tags for Identifying Languages." It does not contain a fixed, exhaustive list of language codes within the RFC itself. Instead, it specifies the structure and rules for constructing language tags, which are then built using codes from various external standards and registries.

Parameter Format

LAST_N

LAST_N

Picks the last N characters of a string, where N is the number of characters to return.

Parameter Format

Length (NUMBER, required)

Usage Example

LEFT_PAD

LEFT_PAD

Adds padding characters to the left side of a string until it reaches the specified length. Useful for creating fixed-width identifiers.

Parameter Format

Length (NUMBER, required): Target string length Pad (CHARACTER, optional): Character to use for padding (default is space)

LOOKUP

LOOKUP

Transforms a value using a lookup table defined in your Lifecycle Management policy. Essential for mapping codes to descriptive values or standardizing data across systems.

Parameter Format

Table Name (STRING, required): Name of the lookup table Column Name (STRING, required): Column to search in Return Column Name (STRING, required): Column value to return

LOWER

LOWER

Transforms all uppercase characters in a string to lowercase. One of the most commonly used transformers for normalizing usernames and email addresses.

Parameter Format

None (no parameters required)

Basic Usage

LOWER_SNAKE_CASE

LOWER_SNAKE_CASE

Transforms string to lowercase with underscores.

Parameter Format

None (no parameters required)

Usage Example

NEXT_NUMBER

NEXT_NUMBER

Generates a set of alternative values by appending sequential numbers. Essential for handling unique constraint conflicts during user provisioning. Returns an empty string first, then "2", "3", "4", etc.

Parameter Format

Start Integer (NUMBER, required): First number in sequence Length (NUMBER, required): How many alternatives to generate

NEXT_NUMBER Max Length

NEXT_NUMBER Max Length

This transformer supports an optional maximum length parameter to simplify complex username generation workflows. It automatically evaluates combined strings (such as {first_name}_{last_name}) and truncates to specified character limits before appending numerical suffixes.

Generates a set of integers as strings.

Parameter Format

NOW

NOW

Returns the current time in UTC. An optional argument indicates the outgoing time format; by default, the RFC3339 format.

Parameter Format

String (Optional) - Format

Usage Example

PHONE_NUMBER_E164

PHONE_NUMBER_E164

Transforms a phone number into the E.164 format.

E. 164 numbers are formatted [+] [country code] [subscriber number including area code] and can have a maximum of fifteen digits. Parameter Format

Region (STRING, optional): ISO 3166-1 alpha-2 format

PREPEND

PREPEND

Adds text to the beginning of attribute values. Useful for adding prefixes like organization codes or type indicators.

Parameter Format

Characters (STRING, required): Text to add at the beginning

Basic Usage

RANDOM_ALPHANUMERIC_GENERATOR

RANDOM_ALPHANUMERIC_GENERATOR

Generates a random alphanumeric string.

Parameter Format

Length (NUMBER, required)

Usage Example

RANDOM_INTEGER

RANDOM_INTEGER

Generates a random integer value between specified minimum and maximum values (inclusive). Useful for creating unique test IDs or temporary identifiers. Does not require an input value.

Parameter Format

Min (NUMBER, required): The minimum value (inclusive) Max (NUMBER, required): The maximum value (inclusive)

RANDOM_NUMBER_GENERATOR

RANDOM_NUMBER_GENERATOR

Generates a random number string.

Parameter Format

Length (NUMBER, required)

Usage Example

RANDOM_STRING_GENERATOR

RANDOM_STRING_GENERATOR

Generates a random string.

Parameter Format

Length (NUMBER, required)

Usage Example

REMOVE_CHARS

REMOVE_CHARS

Removes all instances of specified characters from a string. Useful for cleaning up data and removing unwanted punctuation or special characters.

Parameter Format

Characters (STRING, required): String containing all characters to be removed

REMOVE_DIACRITICS

REMOVE_DIACRITICS

Removes diacritics (accents, etc.) from input string.

Parameter Format

None (no parameters required)

Usage Example

REMOVE_DOMAIN

REMOVE_DOMAIN

Removes the domain portion from an email address, leaving only the username. One of the most frequently used transformers for generating usernames from email addresses.

Parameter Format

None (no parameters required)

REMOVE_WHITESPACE

REMOVE_WHITESPACE

Removes all whitespace characters (spaces, tabs, newlines) from a string. Useful for creating compact identifiers and ensuring data consistency.

Parameter Format

None (no parameters required)

REPLACE_ALL

REPLACE_ALL

Replaces all instances of one string with another. Essential for character substitution and format standardization.

Parameter Format

Original (STRING, required): String to find New (STRING, required): String to replace with

RIGHT_PAD

RIGHT_PAD

Right pads a string with a character.

Parameter Format

Length (NUMBER, required),

Pad (CHARACTER, optional): Default is space

SPLIT

SPLIT

Splits a string and returns the string at the given index.

Parameter Format

Split String (STRING, required), Index (NUMBER, required)

Usage Example

SUB_STRING

SUB_STRING

Extracts a substring from the original value starting at a specific position. Commonly used for creating initials or extracting portions of identifiers.

Parameter Format

Offset (NUMBER, required): Starting position (0-based index) Length (NUMBER, required): Number of characters to extract

TRIM

TRIM

Removes leading and trailing whitespace from a string. Essential for cleaning up data from external systems.

Parameter Format

None (no parameters required)

Basic Usage

TRIM_CHARS

TRIM_CHARS

Removes all specified characters from both the beginning and end of a string. Useful for removing padding characters or cleaning up formatted data.

Parameter Format

Characters (STRING, required): String containing all characters to remove from both ends

TRIM_CHARS_LEFT

TRIM_CHARS_LEFT

Removes all specified characters from the beginning of a string only. Useful for removing leading zeros or prefixes.

Parameter Format

Characters (STRING, required): String containing all characters to remove from the beginning

TRIM_CHARS_RIGHT

TRIM_CHARS_RIGHT

Removes all specified characters from the end of a string only. Useful for removing trailing characters or suffixes.

Parameter Format

Characters (STRING, required): String containing all characters to remove from the end

UPPER

UPPER

Transforms all lowercase characters in a string to uppercase. Commonly used for standardizing identifiers and codes.

Parameter Format

None (no parameters required)

Basic Usage

UPPER_CAMEL_CASE

UPPER_CAMEL_CASE

Transforms a string to upper camel case.

Parameter Format

None (no parameters required)

Usage Example

UPPER_SNAKE_CASE

UPPER_SNAKE_CASE

Transforms string to uppercase with underscores.

Parameter Format

None (no parameters required)

Usage Example

UTC_TO_TIME_ZONE

UTC_TO_TIME_ZONE

Interprets the incoming time string as if it were in UTC and then converts it to the specified time zone. (example: if the input is "1/2/2025 11pm" and the specified time zone is "America/Los_Angeles" the function will treat "1/2/2025 11pm" as the UTC time zone and output the corresponding "America/Los_Angeles" time "1/2/2025 3pm") Note: When using the time zone parameter, a named time zone ("America/Los_Angeles") accounts for daylight saving time, whereas a time zone offset ("-07:00") is always calculated from UTC, ignoring daylight saving time.

Parameter Format

UUID_GENERATOR

UUID_GENERATOR

Generates a UUID.

A UUID (Universally Unique Identifier) is a 128-bit identifier used to uniquely identify information in computer systems.

Parameter Format

None (no parameters required)

Conditional logic: IF statements with comparison operators

  • Destination Attribute: email

  • Formatter: {username}

  • Pipeline Functions: | APPEND, "@company.com"

  • Result: If username = john.smith, output is [email protected]

  • In a Pipeline

    • Destination Attribute: display_name

    • Formatter: {first_name}

    • Pipeline Functions: | APPEND, " " | APPEND, "{last_name}"

    • Result: If first_name = John and last_name = Smith, output is John Smith

    Example

    • Destination Attribute: user_principal_name

    • Formatter: {first_name}.{last_name}

    • Pipeline Functions: | LOWER | APPEND, "@contoso.com"

    • Use case: Generate standardized email addresses for Azure AD user provisioning

    None (no parameters required)

    Basic Usage

    • Destination Attribute: username

    • Formatter: {first_name}

    • Pipeline Functions: | ASCII

    • Result: If first_name = Łukasz, output is Lukasz

    In a Pipeline

    • Destination Attribute: login_name

    • Formatter: {first_name}.{last_name}

    • Pipeline Functions: | ASCII | LOWER | REMOVE_WHITESPACE

    • Result: If first_name = José María, last_name = García, output is josemaria.garcia

    Example

    • Destination Attribute: sAMAccountName

    • Formatter: {first_name}

    • Pipeline Functions: | ASCII | SUB_STRING, 0, 1 | LOWER

    • Use case: Generate Active Directory account names that comply with character restrictions while handling international names (converts "Łukasz" to "l")

    Usage Example

    Input:

    {activation_date | ASSUME_TIME_ZONE, "America/Los_Angeles"}

    {activation_date | ASSUME_TIME_ZONE, "America/Los_Angeles", "RFC3339"}

    {activation_date | ASSUME_TIME_ZONE, "-07:00"}

    {activation_date | ASSUME_TIME_ZONE, "-07:00", "RFC3339"}

    Format (STRING, optional): [alpha2, alpha3, numeric], defaults to alpha2

    Usage Example

    Input:

    {"US" | COUNTRY_CODE_ISO3166, "alpha3"}

    Output:

    USA

    Usage Example

    Input:

    {activation_date | DATE_ADJUST_DAY, +1}

    {activation_date | DATE_ADJUST_DAY, +1, "RFC3339"}

    {activation_date | DATE_ADJUST_DAY, +1, "2006-01-02T15:04:05Z07:00"}

    Integer - day

    Integer - month

    Integer-year

    String (Optional) - Format

    Usage Example

    Input:

    {activation_date | DATE_ADJUST, +1, 2, 3, -1}

    {activation_date | DATE_ADJUST, +1, 2, 3, -1, "RFC3339"}

    {activation_date | DATE_ADJUST, +1, 2, 3, -1, "2006-01-02T15:04:05Z07:00"}

    Basic Usage
    • Destination Attribute: hire_date

    • Formatter: {start_date}

    • Pipeline Functions: | DATE_FORMAT, "01/02/2006"

    • Result: If start_date = 2023-03-15, output is 03/15/2023

    In a Pipeline

    • Destination Attribute: formatted_date

    • Formatter: {hire_date}

    • Pipeline Functions: | DATE_FORMAT, "Jan 2, 2006" | REPLACE_ALL, " ", "_"

    • Result: If hire_date = 2023-03-15, output is Mar_15,_2023

    Example

    • Destination Attribute: accountExpires

    • Formatter: {termination_date}

    • Pipeline Functions: | DATE_FORMAT, "20060102150405Z"

    • Use case: Convert dates to LDAP Z time format for Active Directory account expiration (outputs UTC format like 20230315143025Z)

  • Destination Attribute: initial

  • Formatter: {first_name}

  • Pipeline Functions: | FIRST_N, 1

  • Result: If first_name = John, output is J

  • In a Pipeline

    • Destination Attribute: username

    • Formatter: {first_name}.{last_name}

    • Pipeline Functions: | FIRST_N, 1 | LOWER

    • Result: If first_name = John, output is j

    Example

    • Destination Attribute: username

    • Formatter: {first_name}

    • Pipeline Functions: | FIRST_N, 1 | LOWER

    • Use case: Create abbreviated usernames in the format "j.smith" by combining first initial with last name

    TargetAttribute (STRING, required)

    Usage Example

    Input:

    {Employee:ID | FROM_ENTITY_ATTRIBUTE, "ManagerID"}

    Output:

    Manager ID (for the employee)

    None (no parameters required)

    Usage Example

    Input:

    {"Spanish" | LANGUAGE_RFC5646}

    Output:

    es

    Input:

    {"helloworld" | LAST_N, 5}

    Output:

    world

    Basic Usage
    • Destination Attribute: employee_id

    • Formatter: {id}

    • Pipeline Functions: | LEFT_PAD, 5, "0"

    • Result: If id = 123, output is 00123

    In a Pipeline

    • Destination Attribute: formatted_code

    • Formatter: {cost_center}

    • Pipeline Functions: | TRIM_CHARS, "0" | LEFT_PAD, 6, "0"

    • Result: If cost_center = 001234, output is 001234 (first removes then re-applies padding)

    Example

    • Destination Attribute: employee_id

    • Formatter: {employee_id}

    • Pipeline Functions: | REMOVE_CHARS, "#" | TRIM_CHARS, "0" | LEFT_PAD, 6, "0"

    • Use case: Standardize employee IDs to 6-digit format (converts "##001234##" to "001234")

    Basic Usage
    • Destination Attribute: city

    • Formatter: {location_code}

    • Pipeline Functions: | LOOKUP, "locationTable", "location_code", "city"

    • Result: If location_code = IL001 and locationTable contains that code, output is Chicago

    In a Pipeline

    • Destination Attribute: office_email_domain

    • Formatter: {office_code}

    • Pipeline Functions: | LOOKUP, "officeTable", "code", "domain" | LOWER

    • Result: Looks up domain from table, then converts to lowercase

    Example

    • Destination Attribute: office_location

    • Formatter: {location}

    • Pipeline Functions: | LOOKUP, "locationTable", "location_code", "city"

    • Use case: Convert abbreviated location codes (like "IL001", "CA002") to full city names for user profiles, maintaining consistency across different source systems

  • Destination Attribute: username

  • Formatter: {first_name}

  • Pipeline Functions: | LOWER

  • Result: If first_name = JOHN, output is john

  • In a Pipeline

    • Destination Attribute: email

    • Formatter: {first_name}.{last_name}@company.com

    • Pipeline Functions: | LOWER

    • Result: If first_name = John, last_name = Smith, output is [email protected]

    Example

    • Destination Attribute: login

    • Formatter: {first_name}

    • Pipeline Functions: | SUB_STRING, 0, 1 | LOWER

    • Use case: Create standardized Okta login names in format "j.smith" by extracting first initial and converting to lowercase

    Input:

    {"Hello World" | LOWER_SNAKE_CASE}

    Output:

    hello_world

    Basic Usage
    • Destination Attribute: username

    • Formatter: {first_name}.{last_name}

    • Pipeline Functions: | LOWER | NEXT_NUMBER, 2, 3

    • Result: Generates john.smith, john.smith2, john.smith3, john.smith4 as fallback options

    In a Pipeline

    • Destination Attribute: email

    • Formatter: {first_name}{last_name}

    • Pipeline Functions: | LOWER | NEXT_NUMBER, 2, 5 | APPEND, "@company.com"

    • Result: Creates email alternatives: [email protected], [email protected], etc.

    Example

    • Destination Attribute: user_principal_name

    • Formatter: (see conditional example below)

    • Pipeline Functions: N/A (used within IF statement)

    • Use case: Intelligent username generation with length-based fallbacks:

    This handles both name length constraints and uniqueness conflicts automatically.

    Integer (NUMBER, required), Length (NUMBER, required)

    Usage Example

    Input:

    {"foobar" | NEXT_NUMBER, 1, 12, 4}

    Output:

    foob foo1 foo2 foo3 foo4 foo5 foo6 foo7 foo8 foo9 fo10 fo11 fo12

    Input:

    {NOW}

    {| NOW, "RFC3339"}

    {NOW, "RFC3339"}

    {NOW, "2006-01-02T15:04:05Z07:00"}

    Usage Example

    Input:

    {"+1-800-555-1212" | PHONE_NUMBER_E164}

    Output:

    +18005551212

    • Destination Attribute: location_code

    • Formatter: {city_code}

    • Pipeline Functions: | PREPEND, "CORP_"

    • Result: If city_code = NYC, output is CORP_NYC

    In a Pipeline

    • Destination Attribute: contractor_username

    • Formatter: {username}

    • Pipeline Functions: | PREPEND, "c-" | LOWER

    • Result: If username = JSmith, output is c-jsmith

    Example

    • Destination Attribute: account_name

    • Formatter: {username}

    • Pipeline Functions: | PREPEND, "c-"

    • Use case: Identify contractor accounts by prefixing their usernames (converts "jsmith" to "c-jsmith" to distinguish from employee accounts)

    Input:

    {| RANDOM_ALPHANUMERIC_GENERATOR, 8}

    Output:

    a1B2c3D4

    Note: This transformer generated an alphanumeric string with eight characters.

    Basic Usage
    • Destination Attribute: test_id

    • Formatter: TEST

    • Pipeline Functions: | RANDOM_INTEGER, 1000, 9999

    • Result: Output is TEST followed by random number like TEST4827

    In a Pipeline

    • Destination Attribute: temp_username

    • Formatter: user

    • Pipeline Functions: | RANDOM_INTEGER, 1, 100 | APPEND, "@temp.local"

    • Result: Output like [email protected]

    Example

    • Destination Attribute: temporary_id

    • Formatter: TEST

    • Pipeline Functions: | RANDOM_INTEGER, 1000, 9999

    • Use case: Generate unique test identifiers for sandbox environments (produces values like "TEST4827", "TEST8391")

    Input:

    {| RANDOM_NUMBER_GENERATOR, 4}

    Output:

    4829

    Note: This transformer generated a random numeric string with four characters.

    Input:

    {| RANDOM_STRING_GENERATOR, 6}

    Output:

    uFkLxw

    Note: This transformer generated a random alpha string with six characters.

    Basic Usage
    • Destination Attribute: username

    • Formatter: {email}

    • Pipeline Functions: | REMOVE_CHARS, "@."

    • Result: If email = [email protected], output is johndoeexamplecom

    In a Pipeline

    • Destination Attribute: phone

    • Formatter: {phone_number}

    • Pipeline Functions: | REMOVE_CHARS, "()- "

    • Result: If phone_number = (123) 456-7890, output is 1234567890

    Example

    • Destination Attribute: user_id

    • Formatter: {email}

    • Pipeline Functions: | REMOVE_CHARS, "-"

    • Use case: Create clean user IDs from email addresses by removing hyphens (converts "" to "")

    Input:

    {"José" | REMOVE_DIACRITICS}

    Output:

    Jose

    Basic Usage
    • Destination Attribute: username

    • Formatter: {email}

    • Pipeline Functions: | REMOVE_DOMAIN

    • Result: If email = [email protected], output is john.smith

    In a Pipeline

    • Destination Attribute: login_name

    • Formatter: {email}

    • Pipeline Functions: | REMOVE_DOMAIN | REPLACE_ALL, ".", "_"

    • Result: If email = [email protected], output is john_smith

    Example

    • Destination Attribute: username

    • Formatter: {email}

    • Pipeline Functions: | REMOVE_DOMAIN

    • Use case: Extract usernames for target systems that don't use email-style logins (converts "[email protected]" to "jsmith")

    Basic Usage
    • Destination Attribute: username

    • Formatter: {display_name}

    • Pipeline Functions: | REMOVE_WHITESPACE

    • Result: If display_name = John A. Doe, output is JohnA.Doe

    In a Pipeline

    • Destination Attribute: tag

    • Formatter: {department}

    • Pipeline Functions: | REMOVE_WHITESPACE | LOWER

    • Result: If department = Human Resources, output is humanresources

    Example

    • Destination Attribute: cost_center_code

    • Formatter: {cost_center}

    • Pipeline Functions: | REMOVE_WHITESPACE

    • Use case: Ensure cost center codes have no embedded spaces for system integration (converts "CC 12345" to "CC12345")

    Basic Usage
    • Destination Attribute: username

    • Formatter: {display_name}

    • Pipeline Functions: | REPLACE_ALL, " ", "_"

    • Result: If display_name = John Smith, output is John_Smith

    In a Pipeline

    • Destination Attribute: identifier

    • Formatter: {employee_id}

    • Pipeline Functions: | REPLACE_ALL, "-", "" | TRIM

    • Result: If employee_id = EMP-12345, output is EMP12345

    Example

    • Destination Attribute: email

    • Formatter: {email}

    • Pipeline Functions: | REPLACE_ALL, " ", "."

    • Use case: Fix malformed email addresses with spaces (converts "john " to "")

    Usage Example

    Input:

    {"123" | RIGHT_PAD, 5, "0"}

    Output:

    12300

    Input:

    {"[email protected]" | SPLIT, "@", 0}

    Output:

    first.last

    Note: This transformer generated the results where the index starts at zero (0).

    Basic Usage
    • Destination Attribute: initial

    • Formatter: {first_name}

    • Pipeline Functions: | SUB_STRING, 0, 1

    • Result: If first_name = John, output is J

    In a Pipeline

    • Destination Attribute: short_id

    • Formatter: {employee_id}

    • Pipeline Functions: | SUB_STRING, 3, 4 | UPPER

    • Result: If employee_id = EMP12345, output is 1234

    Example

    • Destination Attribute: username

    • Formatter: {first_name}

    • Pipeline Functions: | SUB_STRING, 0, 1 | LOWER

    • Use case: Generate usernames like "j.smith" by extracting first initial and combining with last name

  • Destination Attribute: username

  • Formatter: {display_name}

  • Pipeline Functions: | TRIM

  • Result: If display_name = " John Doe ", output is John Doe

  • In a Pipeline

    • Destination Attribute: email

    • Formatter: {email_address}

    • Pipeline Functions: | TRIM | LOWER

    • Result: If email_address = " [email protected] ", output is [email protected]

    Example

    • Destination Attribute: display_name

    • Formatter: {display_name}

    • Pipeline Functions: | TRIM

    • Use case: Clean up imported user data that may have padding whitespace from CSV files or database fields

    Basic Usage
    • Destination Attribute: employee_id

    • Formatter: {id_number}

    • Pipeline Functions: | TRIM_CHARS, "0."

    • Result: If id_number = 000.123.000, output is 123

    In a Pipeline

    • Destination Attribute: clean_code

    • Formatter: {code}

    • Pipeline Functions: | TRIM_CHARS, "-_" | UPPER

    • Result: If code = ---ABC123___, output is ABC123

    Example

    • Destination Attribute: office_code

    • Formatter: {office_code}

    • Pipeline Functions: | TRIM_CHARS, ".0" | TRIM_CHARS_RIGHT, ".USCA"

    • Use case: Clean up office codes with variable padding (converts "000.8675309.USCA" to "8675309")

    Basic Usage
    • Destination Attribute: cost_center

    • Formatter: {cost_center_code}

    • Pipeline Functions: | TRIM_CHARS_LEFT, "0"

    • Result: If cost_center_code = 00012345, output is 12345

    In a Pipeline

    • Destination Attribute: identifier

    • Formatter: {raw_id}

    • Pipeline Functions: | TRIM_CHARS_LEFT, "x" | UPPER

    • Result: If raw_id = xxxABC123, output is ABC123

    Example

    • Destination Attribute: cost_center

    • Formatter: {cost_center}

    • Pipeline Functions: | TRIM_CHARS_LEFT, "0"

    • Use case: Remove leading zeros from cost center codes while preserving trailing zeros (converts "00012345" to "12345")

    Basic Usage
    • Destination Attribute: office_code

    • Formatter: {raw_office_code}

    • Pipeline Functions: | TRIM_CHARS_RIGHT, "0"

    • Result: If raw_office_code = ABC12300, output is ABC123

    In a Pipeline

    • Destination Attribute: clean_code

    • Formatter: {code}

    • Pipeline Functions: | TRIM_CHARS_RIGHT, "temp" | UPPER

    • Result: If code = ABC123temp, output is ABC123

    Example

    • Destination Attribute: office_code

    • Formatter: {office_code}

    • Pipeline Functions: | TRIM_CHARS_RIGHT, "0"

    • Use case: Remove trailing zeros from office codes while preserving leading zeros (converts "ABC12300" to "ABC123")

  • Destination Attribute: department_code

  • Formatter: {department}

  • Pipeline Functions: | UPPER

  • Result: If department = sales, output is SALES

  • In a Pipeline

    • Destination Attribute: user_id

    • Formatter: {username}

    • Pipeline Functions: | REMOVE_WHITESPACE | UPPER

    • Result: If username = john smith, output is JOHNSMITH

    Example

    • Destination Attribute: last_name_normalized

    • Formatter: {name}

    • Pipeline Functions: | UPPER

    • Use case: Standardize employee last names for matching across systems (converts "Smith" to "SMITH")

    Input:

    {"hello world" | UPPER_CAMEL_CASE}

    Output:

    HelloWorld

    Input:

    {"hello world" | UPPER_SNAKE_CASE}

    Output:

    HELLO_WORLD

    String - Time Zone String (Optional) - Format

    Usage Example

    Input:

    {activation_date | UTC_TO_TIME_ZONE, "America/Los_Angeles"}

    {activation_date | UTC_TO_TIME_ZONE, "America/Los_Angeles", "RFC3339"}

    {activation_date | UTC_TO_TIME_ZONE, "-07:00"}

    {activation_date | UTC_TO_TIME_ZONE, "-07:00", "RFC3339"}

    Usage Example

    Input:

    {| UUID_GENERATOR}

    Output:

    123e4567-e89b-12d3-a456-426614174000

    Attribute Transformers
    ISO 3166
    RFC 5646
    IF sys_attr__would_be_value_len le 20
      {first_name | LOWER}.{last_name | LOWER | NEXT_NUMBER, 2, 3}
    ELSE IF sys_attr__would_be_value_len le 30
      {first_name | LOWER}.{last_name | LOWER | FIRST_N, 1 | NEXT_NUMBER, 2, 3}
    ELSE
      {first_name | LOWER | FIRST_N, 1}.{last_name | LOWER | FIRST_N, 1 | NEXT_NUMBER, 2, 3}
    [email protected]
    [email protected]
    [email protected]
    [email protected]

    Lookup Tables

    Use lookup tables to transform identity attributes for target systems

    Overview

    You can use Lookup transformers to convert identity attributes from a source system into appropriate values for target systems based on CSV reference tables. This is particularly useful when mapping values between systems that use different naming conventions, codes, or formats for the same conceptual data.

    For example, you might need to transform a "Location" attribute from Workday (which might be stored as location codes like "MN001") into corresponding values for country, country code, or city names in a target system.

    Use Table Lookup Transformers when:

    • You need to map source attribute values to different values in target systems

    • You have standardized reference data that must be consistent across applications

    • You need to extract different pieces of information from a single attribute value

    • You have complex mapping requirements that built-in transformers cannot support

    Examples

    1. Geographic Information:

      • Transform location codes to country, region, city, or timezone information

      • Map office codes to physical addresses or facility types

    2. Organizational Mapping:

    How It Works

    The Table Lookup Transformer references CSV-based mappings between source and destination values. When synchronizing user attributes, Veza:

    1. Takes the source attribute value

    2. Looks up this value in the specified lookup table

    3. Returns the corresponding value from the designated return column

    4. Applies this value to the target attribute

    Lookup Table Structure

    Lookup tables are CSV files with columns that map values from a source of identity to destination values. Each row represents a mapping entry. The first row must contain the column headers.

    For example, a location mapping table might look like:

    Creating and Managing Lookup Tables

    Creating a Lookup Table

    To create a new lookup table:

    1. Navigate to the Lookup Tables tab within your policy configuration

    2. Click Edit mode to enable policy changes

    3. Click Add New to create a new lookup table

    4. Provide a Name and optional Description for the lookup table

    Managing Lookup Tables

    From the Lookup Tables tab, you can:

    • Edit table descriptions or upload a new CSV

    • Delete tables that are no longer needed

    Using Table Lookup Transformers

    Basic Syntax

    To use a Table Lookup Transformer in a common or action-synced attribute:

    1. In Destination Attribute, choose the attribute on the target entity that will be updated

    2. In Formatter, choose the source attribute to transform

    3. In Pipeline Functions, specify the lookup table name, the column to match against, and the column containing values to return.

    The full syntax for using lookup table transformers is:

    Where:

    • <value> is the source attribute to transform (e.g., {location})

    • <table_name> is the name of the lookup table to use

    • <column_name> is the column in the table to match against

    Examples

    Assuming a user has "location": "IL001" and a lookup table named locationTable structured as shown earlier:

    Formatter
    Result

    Advanced Features

    Pipeline Transformations

    You can combine lookup transformations with other transformation functions in a pipeline:

    This would look up the state_code corresponding to the location value and convert it to lowercase.

    Handling Missing Values

    When a lookup value is not found in the table, the transformation will fail for that specific attribute.

    For full coverage, ensure your lookup table includes entries for all possible source values that may be encountered during provisioning.

    To ensure robust provisioning workflows, it's important to include all expected values in your lookup table, validate source data before implementing lookup transformations, and test transformations with representative data sets.

    Technical Details

    Implementation Notes

    • Lookup tables are immutable and automatically deleted when no longer referenced by any policy version

    • Multiple policy versions can reference the same lookup table (e.g., an active version and a draft version)

    • Lookup tables are defined at the policy level and can be referenced by any transformer within the policy

    • Lookup tables can have multiple columns to support different transformations from the same reference data

    Best Practices

    1. Standardize Naming: To use a lookup-based transformer, you will reference the table by file name. Apply consistent conventions for both the table and columns.

    2. Document Mappings: Add descriptions for each lookup table to explain its purpose

    3. Validate Data: Ensure lookup tables are complete and accurate before using them in transformers. Consider how lookup tables will be maintained over time, especially for values expected to change.

    Troubleshooting

    Common Issues

    Issue
    Resolution

    Related Topics

  • Convert department codes to department names or business units

  • Map cost centers to budget codes or accounting categories

  • System-Specific Configurations:

    • Transform job titles to role designations in target systems

    • Convert skill codes to certification requirements or training needs

  • Drag a CSV file or click Browse to upload your reference data

  • Review the automatically detected column names

  • Click Save to store the lookup table

  • <return_column_name> is the column containing the value to return

    {location} | LOOKUP locationTable, location_code, city

    "Chicago"

    {location} | LOOKUP locationTable, location_code, state

    "Illinois"

    {location} | LOOKUP locationTable, location_code, state_code

    "IL"

    Value not found in lookup table

    Add the missing mapping to the lookup table with the correct source value

    Incorrect column name referenced

    Check the column names in your lookup table (they are case-sensitive)

    Unexpected transformation results

    Verify the lookup table content and ensure the correct columns are specified

    Attribute Transformers
    Common Transformers
    Pipeline Functions
    Lifecycle Management Workflows
    Configuring an action-level attribute transformer using lookup tables.
    location_code,state_code,state,city
    MN001,MN,Minnesota,Minneapolis
    CA001,CA,California,Los Angeles
    TX001,TX,Texas,Houston
    TX002,TX,Texas,Austin
    {<value> | LOOKUP <table_name>, <column_name>, <return_column_name>}
    {location | LOOKUP locationTable, location_code, state_code | LOWER}

    System Attributes

    Computed properties for advanced workflow triggering and conditional transformations in Lifecycle Management

    Overview

    System attributes are computed properties that Lifecycle Management automatically generates during identity processing. These attributes enable advanced automation scenarios by providing runtime information about identity changes and transformation results.

    All system attributes follow the sys_attr__ prefix convention and cannot be manually set or modified.

    Available System Attributes

    sys_attr__is_mover

    A persistent boolean attribute that indicates whether an identity has undergone changes to monitored properties.

    Type: Boolean Persistence: Stored with identity record Available in: Workflow triggers, conditions, and transformers

    Configuration: Define monitored properties in the policy configuration:

    Workflow Trigger Example:

    Combined Condition Example:

    The attribute is automatically set to true when any property in mover_properties changes during identity update. It is cleared when the identity is unchanged in an extraction cycle, and excluded from change detection to prevent recursive updates.

    System attribute names are case-sensitive and must be lowercase in all expressions.

    sys_attr__would_be_value

    A transient attribute that provides a preview of the transformation result during conditional evaluation.

    Type: String Persistence: Transient (exists only during IF statement evaluation) Available in: Conditional transformers only

    Usage Example - Conditional Domain Addition:

    The above transformer will check if the transformed email already contains "@", preserve existing email addresses, and add domain only when needed.

    sys_attr__would_be_value_len

    A transient attribute that provides the character length of the transformation result during conditional evaluation.

    Type: Number Persistence: Transient (exists only during IF statement evaluation) Available in: Conditional transformers only

    Usage Example - Progressive Username Truncation:

    For "Leonevenkataramanathan Foster":

    • First check (≤30 chars): leonevenkataramanathan.foster (30 chars - passes first condition)

    • If >30 chars, second check (≤20 chars): leonevenkataramana.foster (25 chars - fails second condition)

    • If >20 chars, fallback: l.f (3 chars - always succeeds)

    Integration with NEXT_NUMBER

    Preview attributes work with the NEXT_NUMBER transformer for generating unique alternatives:

    This evaluates the base value length before applying numbering, ensuring the final result (including numbers) meets constraints.

    Only one NEXT_NUMBER transformer is allowed per conditional branch.

    Workflow Trigger Properties

    The sys_attr__is_mover attribute supports additional trigger properties for fine-grained control:

    This workflow triggers only when:

    • The identity is marked as a mover (department or location changed)

    • The identity is active

    • At least one of the trigger_properties has changed since last extraction

    Performance Notes

    • Mover Detection: Comparison occurs for all properties in mover_properties during each extraction

    • Preview Evaluation: Each IF branch with preview attributes requires transformation execution

    • Optimization: Place most common conditions first to minimize preview evaluations

    See Also

    • - Complete list of transformation functions

    • - Attribute transformation concepts and examples

    • - Configuring mover properties and workflows

    Alternatives with NEXT_NUMBER: l.f2, l.f3, l.f4

    Caching: Preview values are calculated once per condition branch and reused

    Transformer Functions Reference
    Transformers
    Policies
    {
      "mover_properties": ["department", "manager_id", "title", "location"]
    }
    sys_attr__is_mover eq true
    sys_attr__is_mover eq true and department eq "Engineering" and active eq true
    IF sys_attr__would_be_value co "@"
      {email | LOWER}
    ELSE
      {email | LOWER}@company.com
    IF sys_attr__would_be_value_len le 30
      {first_name | LOWER}.{last_name | LOWER | NEXT_NUMBER, 2, 3}
    ELSE IF sys_attr__would_be_value_len le 20
      {first_name | LOWER | FIRST_N, 10}.{last_name | LOWER | NEXT_NUMBER, 2, 3}
    ELSE
      {first_name | LOWER | FIRST_N, 1}.{last_name | LOWER | FIRST_N, 1 | NEXT_NUMBER, 2, 3}
    IF sys_attr__would_be_value_len le 15
      {username | NEXT_NUMBER, 2, 5}
    ELSE IF sys_attr__would_be_value_len le 15
      {username | FIRST_N, 13 | NEXT_NUMBER, 2, 5}
    {
      "trigger_properties": ["department", "location"],
      "trigger_string": "sys_attr__is_mover eq true and active eq true"
    }

    Attribute Mapping

    How source system properties become Veza attributes

    Overview

    When connecting to integrated systems (see Veza Integrations), Veza ingests properties from the source systems (e.g., Workday, Okta, Active Directory) and normalizes them into standardized attributes that appear when configuring Workflow trigger conditions, configuring Actions, and in Identities views.

    While these standardized attributes are intended to ensure consistent naming across different systems, it is important to understand that some attributes may appear differently than their original names in the source system.

    You can retrieve the original attribute names for enabled Lifecycle Management integrations using the ListLifecycleManagerDatasources API.

    Attribute Naming Conventions

    Veza normalizes all property names for consistency:

    Original Format
    Veza Format
    Rule Applied

    The following normalization rules typically apply:

    • Source properties are converted to lowercase

    • Any spaces and hyphens become underscores

    • Special characters removed

    • CamelCase converted to snake_case

    Attribute Types and Mappings

    The following sections include some examples of how Veza handles attributes from common integrations.

    Standard Attributes

    Veza recognizes and standardizes many common attributes across source systems:

    Attribute
    Type
    Description
    Example Value

    Source-Specific Mappings

    Veza will make conversions to some attribute names from the source integration. For example, sAMAccountName in Microsoft Active Directory is shown as account_name for Active Directory Users in Veza Access Graph.

    Workday → Veza

    Workday Property
    Veza Attribute
    Notes

    Okta → Veza

    Okta Property
    Veza Attribute
    Notes

    Active Directory → Veza

    AD Property
    Veza Attribute
    Notes

    Custom Properties

    Some integrations support custom property extraction for organization-specific fields from custom reports or extended schemas:

    • Always prefixed with customprop_

    • Automatically discovered during extraction once enabled

    • Follow standard normalization rules (lowercase, underscores)

    Examples:

    • customprop_department_code - Custom department identifier

    • customprop_employeeou - Organizational unit

    • customprop_region - Geographic region

    System Attributes

    Some entity attributes are computed by Veza, and not derived from source data:

    • sys_attr__is_mover - Identity has changed monitored properties

    • sys_attr__would_be_value - Preview value in conditional transformers

    • sys_attr__would_be_value_len - Preview value length in conditional transformers

    See for details.

    Using Attributes in Workflows

    When configuring a Workflow trigger condition or an action that syncs attributes, you can choose from available attributes using a dropdown menu.

    Primary vs Secondary Sources

    Primary Source - Attributes from the main identity source appear without prefixes:

    Secondary Sources - Attributes from additional sources are prefixed with the entity type:

    Example Usage

    In Workflow Conditions:

    In Transformers:

    With Secondary Sources:

    See Also

    • - Computed attributes for advanced scenarios

    • - Modifying and combining attribute values

    • - Using attributes in workflow conditions

    Custom fields are identified with a customprop_ prefix
  • System-computed fields are identified with the sys_attr__ prefix

  • title

    string

    Job title

    Senior Engineer

    business_title

    string

    Business position

    Senior Engineer

    manager

    string

    Manager reference

    managers

    list

    List of managers

    [John Smith]

    is_active

    boolean

    Active status

    true

    hire_date

    date

    Employment start date

    2024-01-15

    cost_center

    string

    Financial allocation

    CC-1000

    Employee Type

    employee_types

    List (e.g., Full Time)

    Manager

    managers

    List of manager names

    manager

    manager

    Manager's email/ID

    department

    department

    Department name

    title

    title

    Job title

    customprop_project_code - Project allocation

    Employee ID

    employee_id

    Spaces → underscores

    BusinessTitle

    business_title

    CamelCase → snake_case

    Cost-Center

    cost_center

    Special chars removed

    Department Code

    customprop_department_code

    employee_id

    string

    Employee identifier

    E-98765

    email

    string

    Primary email

    [email protected]

    department

    string

    Department name

    Worker ID

    workday_id

    Unique worker identifier

    Employee ID

    employee_id

    Employee number

    Business Title

    business_title

    Job position

    Cost Center

    cost_center

    login

    login

    Username

    email

    email

    Primary email

    status

    status

    ACTIVE, SUSPENDED, etc.

    department

    department

    sAMAccountName

    account_name

    Pre-Windows 2000 login

    distinguishedName

    distinguished_name

    Full LDAP path

    userPrincipalName

    user_principal_name

    user@domain format

    memberOf

    member_of

    System Attributes
    System Attributes
    Transformers
    Policies
    Selecting attributes in a workflow trigger condition.

    Custom fields prefixed

    Engineering

    Financial allocation

    Department name

    List of group DNs

    workday_id
    employee_id
    business_title
    hire_date
    email
    customprop_department_code
    OktaUser.login
    OktaUser.department
    AzureADUser.job_title
    ActiveDirectoryUser.distinguished_name
    employee_types co "Full Time" and department eq "Engineering"
    {first_name}.{last_name}@{customprop_domain}.com
    OktaUser.status eq "ACTIVE" and WorkdayWorker.is_active eq true
    [email protected]

    Attribute Transformers

    Configure how user attributes from a source of identity are transformed for target user accounts

    When creating workflows in Lifecycle Management policies to create, sync, or deprovision identities, you will use attribute transformers to specify how user attributes for target accounts should be structured. The target attributes to create or update are typically mapped and, optionally, transformed from user metadata in the source of identity, such as an identity provider, HR system, or CSV upload. Attributes can be synchronized once or kept continuously in sync as changes occur throughout the user’s employment lifecycle.

    For example, attribute mapping and transformation can be used across Joiner, Mover, and Leaver scenarios:

    • Joiner: Set new Azure AD User Principal Name to {source username}@your-email-domain.com. This is an example of mapping multiple attributes and performing a transformation. More specifically, you use the attribute transformer to generate an email address for new joiners. Use the source username (user_principal_name) from the source of identity (Azure AD UPN) for the first part (user attribute), while your-email-domain.com is used for the last part (target attribute).

    • Mover: Always update a user’s “Manager” and “Department” attributes in Okta to match the user’s manager and department in Workday, a source of identity, whenever a department change or other employee mobility event occurs. This is an example of attribute mapping with continuous synchronization.

    • Leaver: Move a user’s Active Directory account to an Organizational Unit (OU) reserved for terminated accounts.

    When synchronizing a user’s attributes, Veza may apply many transformations to convert the source attribute values into a more suitable format intended for the target application as a user account attribute.

    For example, a transformer might remove the domain from an email address, replace special characters, or convert a string with uppercase letters to lowercase letters.

    See for detailed information.

    Adding transformers

    Common transformers define one or more rules to apply when synchronizing the attributes of a target identity. Use them at the Policy level where you want to create or update attributes using the same conventions across multiple sync or deprovision actions. When you need to configure a one-time individual action in a workflow, such as a specific attribute, then you use the transformer at the Action level.

    At the Policy level, you configure a transformer with basic details, including how to source the value of each attribute:

    1. Assign a name and description to the transformer, and specify the data source to which it applies.

    2. Entity Type: Choose the target entity type in the destination system.

    3. Click Add Attribute. The Destination Attribute dropdown will list available attributes for the chosen entity type.

    After creating a common transformer, you can select it when editing a workflow action. You can edit or delete common transformers on the Edit Policy > Common Transformers tab. Remember that “Sync Identity” and “De-Provision Identity” actions can have action-level transformers override common transformers. If the same destination attribute is defined in both, the action-level transformer will take precedence.

    Formatters

    Formatters specify the actual value of the attribute to synchronize. The target attribute can be set to a specific value, synchronized with a source attribute, transformed using a function, or a combination of these.

    Some formatters should enable continuous synchronization for the attribute, while others should not. For example, the value of "Created By" should be immutable once a user account is provisioned. Other attributes that represent a state or status should be synchronized throughout the user's or account's lifecycle.

    Simple Value Setting

    To create a destination attribute with a fixed value, enter the desired value when configuring the formatter. For setting the creator attribute:

    Destination Attribute
    Formatter
    Continuous Sync

    For activating a re-hired employee:

    Destination Attribute
    Formatter
    Continuous Sync

    Empty Values

    To set empty values (common for de-provisioning flows):

    Destination Attribute
    Formatter
    Continuous Sync

    Source of Identity Formatters

    Target attributes can be updated based on attributes belonging to the source of identity. To reference the value of a source entity attribute, use the format {\<source\_attribute\_name>}. Examples:

    Destination Attribute
    Formatter Example
    Continuous Sync

    Transformation functions

    Based on the user metadata available from your source of identity (SOI), you may need to convert a full email address to a valid username, standardize a date, or generate a unique identifier for users provisioned by Veza. Suppose an attribute value needs to be altered to be compatible with the target system. In that case, you can transform the value of a source attribute or apply a range of other functions to generate the target value.

    Formatter expressions use the following syntax: {\<source\_attribute\_name> | \<FUNCTION\_NAME>,\<param1>,\<param2>} For example:

    Destination Attribute
    Formatter
    Description
    Example

    Table of transformation functions

    Refer to the page for a comprehensive list of all supported functions and parameters. Contact Veza if you require additional transformations for your use case. Some commonly used transformation functions include:

    • Replacing a character with a different one

    • Removing domains from email addresses

    • Transforming to upper, lower, camel, or snake case

    • Using a substring from the original value

    Using the ASCII Transformer

    The ASCII transformer is particularly useful when working with localized user data and legacy systems with strict character-set limitations (such as Active Directory sAMAccountName restrictions). This transformer performs two primary operations:

    1. Removes all non-printable ASCII characters (including control codes, zero-width spaces, tabs, and newlines)

    2. Converts non-ASCII characters to their closest ASCII equivalents

    Whereas the REMOVE_DIACRITICS transformer only removes accent marks while preserving the basic character, the ASCII transformer performs a more comprehensive conversion, replacing characters like “Ł” with “L” and handling a wider range of non-ASCII characters, including the following:

    Accented Letters: Letters with diacritics like é, à, ö, ñ, ç, etc., commonly used in languages like French, Spanish, German, and Portuguese. Non-Latin Alphabets: Characters from various alphabets such as Cyrillic (e.g., ж, б), Greek (e.g., α, β), Arabic (e.g., ح, ص), Hebrew, and Chinese (e.g., 汉, 字). Mathematical and Technical Symbols: Symbols like infinity (∞), integral (∫), summation (∑), Ohm (Ω), degree (°). Currency Symbols: Symbols like €, £, ¥. Emoji: Various emoticons like 😊, 😞, etc. Other Symbols: Symbols like ©, ®, ™, etc.

    DATE_FORMAT Transformer using Date Strings

    The DATE_FORMAT transformer formats date strings using Go time package layout syntax. This transformer helps convert between different date formats, such as for LDAP integration or to standardize date formats across systems.

    Go Time Layout Syntax

    Go time layouts use a specific reference time: Monday, January 2, 15:04:05 MST 2006, which is Unix time 1136239445. All layout strings must use the exact digits and format from this reference time. For more information about Go time layouts, refer to the . Date Components:

    • 2006 = 4-digit year

    • 06 = 2-digit year

    • 01 = 2-digit month (01-12)

    • 1 = 1-digit month (1-12)

    Time Components:

    • 15 = 24-hour format hour (00-23)

    • 03 = 12-hour format hour (01-12)

    • 3 = 12-hour format hour without leading zero (1-12)

    • 04 = minute (00-59)

    Weekday Components:

    • Mon = 3-letter weekday abbreviation

    • Monday = full weekday name

    Time Zone Components:

    • MST = time zone abbreviation

    • Z0700 = RFC3339 time zone format

    • Z07:00 = RFC3339 time zone format with colon

    RFC Components:

    • RFC822 = “02 Jan 06 15:04 MST”

    • RFC822Z = “02 Jan 06 15:04 -0700” // RFC822 with numeric zone

    • RFC850 = “Monday, 02-Jan-06 15:04:05 MST”

    • RFC1123 = “Mon, 02 Jan 2006 15:04:05 MST”

    Other Constant Components:

    • Layout = “01/02 03:04:05PM '06 -0700” // The reference time, in numerical order.

    • ANSIC = “Mon Jan _2 15:04:05 2006”

    • UnixDate = “Mon Jan _2 15:04:05 MST 2006”

    • RubyDate = “Mon Jan 02 15:04:05 -0700 2006”

    Common Layout Examples

    Layout String
    Format
    Example Output

    Usage Examples

    Basic Date Formatting:

    Formats any recognized date input into MM/DD/YYYY format.

    Converting Between Specific Formats:

    Parses input in MM/DD/YYYY format and outputs in YYYY-MM-DD format.

    LDAP Integration Example: The DATE_FORMAT transformer was specifically enhanced to support LDAP Z and Win32 time format requirements.

    The Z time format (20060102150405Z) is commonly used in LDAP directories and represents timestamps in UTC with a ‘Z’ suffix indicating zero UTC offset.

    Converts a date to LDAP Z time format for directory integration. Example for LDAP account expiration:

    Human-Readable Format:

    Outputs a full, human-readable date format. Time Zone Handling:

    Includes time zone information in the output.

    Additionally, the DATE_FORMAT transformer supports LDAP time format requirements using the format Win32 in LDAP directories:

    Converts a date to LDAP time format for directory integration.

    Notes on DATE_FORMAT Transformers

    • Input Format: When the second parameter (input layout) is omitted, the transformer attempts to parse the input using common date formats automatically

    • Case Sensitivity: Layout components are case-sensitive (e.g., PM vs pm)

    • Leading Zeros: Use 01, 02, etc. for zero-padded values, and 1, 2, etc. for non-padded values

    • Reference Time: All layouts must use the exact reference time digits: Mon Jan 2 15:04:05 MST 2006

    DATE_FORMAT Transformer using Time String (Generalized-Time)

    The DATE_FORMAT transformer formats time using a time string to store time values in Generalized-Time format, which is required for Active Directory and other Microsoft-based target applications.

    The Generalized-Time syntax is “YYYYMMDDHHMMSS.0Z”. Time String Format Example:

    The “Z” indicates no time differential. Active Directory stores date/time as Greenwich Mean Time (GMT). If no time differential is specified, GMT is the default.

    If the time is specified in a time zone other than GMT, the differential between the time zone and GMT is appended to the string instead of “Z” in the form “YYYYMMDDHHMMSS.0[+/-]HHMM”. Time Zone Format Example:

    The differential is based on the formula: GMT = Local + Differential.

    String Manipulation Transformers

    These transformers enable the cleaning, formatting, and standardization of string data from your source systems.

    REMOVE_CHARS

    The REMOVE_CHARS transformer removes all instances of specified characters from a string. This is useful for cleaning up data by removing unwanted punctuation, special characters, or formatting elements. Use Cases:

    • User ID creation: {email | REMOVE_CHARS, “-”}

      • If email is ", the result is “johndoe@examplecom”

    • Phone number formatting: {phone_number | REMOVE_CHARS, "()- "}

    REMOVE_WHITESPACE

    The REMOVE_WHITESPACE transformer removes all whitespace characters (spaces, tabs, newlines) from a string. It can help create compact identifiers or ensure data consistency. Use Cases:

    • Username generation: {display_name | REMOVE_WHITESPACE}

      • If display_name is “John A. Doe”, the result is “JohnA.Doe”

    • Tag creation: {department | REMOVE_WHITESPACE | LOWER}

    TRIM, TRIM_CHARS, TRIM_CHARS_LEFT, and TRIM_CHARS_RIGHT

    These transformers help clean up strings by removing unwanted characters from the beginning and/or end of strings. This is essential for data hygiene and ensuring consistent formatting. TRIM: Removes leading and trailing whitespace

    • Basic cleanup: {display_name | TRIM}

      • If display_name is " John Doe ", the result is “John Doe”

    TRIM_CHARS: Removes specified characters from both ends

    • Cleaning employee IDs: {employee_id | TRIM_CHARS, “0.”}

      • If employee_id is “000.123.000”, the result is “123”

    • Removing padding characters: {code | TRIM_CHARS, “-_”}

    TRIM_CHARS_LEFT: Removes specified characters from the beginning only

    • Removing leading zeros: {cost_center | TRIM_CHARS_LEFT, “0”}

      • If cost_center is “00012345”, the result is “12345”

    • Cleaning prefixes: {identifier | TRIM_CHARS_LEFT, “x”}

    TRIM_CHARS_RIGHT: Removes specified characters from the end only

    • Removing trailing characters: {office_code | TRIM_CHARS_RIGHT, “0”}

      • If office_code is “ABC12300”, the result is “ABC123”

    • Cleaning suffixes: {code | TRIM_CHARS_RIGHT, “temp”}

    Advanced Conditional Logic with NEXT_NUMBER

    The NEXT_NUMBER transformer can be combined with IF/ELSE conditional logic to create intelligent username generation with automatic fallback strategies. This is particularly useful for handling length constraints and ensuring unique usernames in Lifecycle Management attribute transformers.

    • Only one NEXT_NUMBER transformer can be used per transformation expression

    • The first alternative uses an empty string (""), followed by numbered alternatives (“2”, “3”, etc.)

    • Alternative values are automatically generated to ensure username uniqueness

    Username Generation with Length-Based Fallbacks

    This example creates usernames that adapt based on length constraints, using the sys_attr__would_be_value_len system attribute to evaluate the length of the generated value:

    Example outputs: For a user named “John Whitaker” (short enough for the first condition):

    • Base value: john.whitaker

    • Alternatives: john.whitaker2, john.whitaker3, john.whitaker4

    For a user named “Leonevenkataramanathan Foster” (requires truncation to meet length limits):

    • Base value: l.f

    • Alternatives: l.f2, l.f3, l.f4

    This approach ensures that username generation adapts to different name lengths while maintaining consistency and uniqueness across your identity management system.

    Pipeline Functions {#pipeline-functions}

    You can pipeline multiple transformation functions together, separated by a vertical bar (|). Each will apply in sequence, allowing for complex attribute formatters that use the output of one function as the input of another.

    Example Pipeline Functions

    • {name | UPPER}

      • If name = Smith, the result is SMITH.

    • {first\_name | SUB\_STRING,0,1 | LOWER}.{last\_name | LOWER}

    Common Transformers

    As part of implementing Lifecycle Management (LCM) processes with Veza, you should create sets of common transformers to define how values such as username, login, or ID are sourced for each LCM Policy. These transformers can then be reused across all identity sync and deprovision policy workflows.

    Create common transformers to consistently form attributes for specific entity types, and reuse them to avoid errors and save time when creating actions for that entity type. The order of common transformers matters when multiple transformers set the same destination attribute. Drag-and-drop to reorder common transformers and control precedence.

    For example, defining a common synced attribute to describe how to format Azure AD account names {username}@evergreentrucks.com enables reuse across multiple workflow actions. You can also define synced attributes at the action level when they are used only once within a policy, such as setting the primary group DN and OU of de-provisioned identities to a group reserved for terminated accounts.

    Common Transformer Examples:

    Transformer & Entity Type
    Attribute
    Value Format
    Continuous Sync
    Description

    $target Attribute Transformer Function

    The $target attribute transformer function is used when a value consists of one or more attributes that require an operation(s), making it too complex to transform, but it needs to be reused.

    Important: The $target function can only be used within the same Action.

    For example, an email address consists of [email protected]. However, you must use the format . By using the $target function, you reuse only one attribute, username, while not changing the other two attributes (firstname_lastname).

    Example:

    Destination Attribute

    Formatter

    Formatter

    Custom Attribute Transformer Function

    The Custom Attribute Transformer function allows you to define a custom transformer that acts as an alias for applying one or more transformer functions.

    For example, you can define a custom function named $CLEAN, which is used as {first_name | $CLEAN}. This function can consist of a series of transformer functions such as | ASCII | LOWER | REMOVE_CHAR |.

    To define a custom attribute transformer, use the following guidelines:

    Policy Version Definitions

    • Custom functions must be defined as part of the policy version.

    • These definitions are structured similarly to hard-coded definitions and are returned in the same format, allowing the Veza UI to handle them without modification.

    • The API for updating and retrieving a policy version must also support these custom function definitions.

    Naming Convention: Custom functions must be in ALL CAPS and prefixed with a $ to avoid conflicts with built-in functions.

    Custom Attribute Transformer Limitations

    The following custom definitions are not supported:

    • Transformer functions with included transformer parameters

    • Nested transformer functions

    • Transformer functions with parameters

    Appending Multi-Value Attribute (Active Directory only)

    As part of the Identity Sync action, you can append values to multi-value Active Directory attributes without replacing existing values. This ensures that existing attribute values are preserved when adding new ones.

    This feature is specific to Active Directory and is not available for other integrations.

    Supported Multi-Value Attributes:

    Active Directory supports appending for the following multi-value attributes:

    • organizationalStatus, departmentNumber, employeeType

    • servicePrincipalName, proxyAddresses

    • member

    Syntax:

    Use the >> prefix before the array to append values:

    Appending syntax supports two array formats:

    • With quotes (JSON format): >>[``"Active", "Permanent"]

    • Without quotes (simple format): >>[Active, Permanent]

    When you use this syntax:

    1. New values are added to the end of the existing attribute values

    2. Duplicate values are automatically removed

    3. The order of existing values is preserved

    4. New values appear after existing values in the order specified

    For example, ff an Active Directory user has:

    And you apply the transformer:

    The resulting value is:

    Note that "Employee" was already present and not duplicated.

    Setting vs. Appending:

    • To Replace existing values: Use [value1, value2] (without >>)

    • To Append to existing values: Use >>[value1, value2] (with >>)

    Additional Notes:

    • The append prefix (>>) only works for multi-value attributes. It is ignored for single-value attributes

    • If the attribute has no existing values, the values are simply set (no difference from non-append behavior)

    • Both the appending syntax and the standard array syntax support arrays with or without quotes around values

    Destination Attribute: Choose the attribute that Veza will create or update for the target entity.
  • Formatter: Choose how the destination attribute should be formatted. Specify the value, a {source\_attribute}, or apply Transformation Functions.

  • Pipeline Functions: Combines a series of attribute formatters with the pipe ( | ) character that runs the value of an attribute in sequential order, where the output of one formatter becomes the input of the following formatter, thus the name, pipeline.

  • See Pipeline Functions for more examples.

    • Continuous Sync: Enabling this option ensures that the attribute is always synced, while applying any defined transformations. By default, attributes will not be synced if the target identity already exists.

    Generating random values (e.g., RANDOM_INTEGER for numeric ranges)

    Jan = 3-letter month abbreviation
  • January = full month name

  • 02 = 2-digit day (01-31)

  • 2 = 1-digit day (1-31)

  • _2 = space-padded day

  • DateTime = “2006-01-02 15:04:05”

  • DateOnly = “2006-01-02”

  • 4 = minute without leading zero (0-59)
  • 05 = second (00-59)

  • 5 = second without leading zero (0-59)

  • PM = AM/PM indicator

  • pm = am/pm indicator (lowercase)

  • TimeOnly = “15:04:05”

  • RFC1123Z = “Mon, 02 Jan 2006 15:04:05 -0700” // RFC1123 with numeric zone

  • RFC3339 = “2006-01-02T15:04:05Z07:00”

  • RFC3339Nano = “2006-01-02T15:04:05.999999999Z07:00”

  • Kitchen = “3:04PM” // Handy time stamps.

  • Stamp = “Jan _2 15:04:05”

  • StampMilli = “Jan _2 15:04:05.000”

  • StampMicro = “Jan _2 15:04:05.000000”

  • StampNano = “Jan _2 15:04:05.000000000”

  • Monday, January 2, 2006

    Full date

    Wednesday, March 15, 2023

    2006-01-02 15:04:05

    Full timestamp

    2023-03-15 14:30:25

    03:04:05 PM

    12-hour time

    02:30:25 PM

    15:04

    24-hour time

    14:30

    20060102150405Z

    LDAP Z time format

    20230315143025Z

    If phone_number is “(123) 456-7890”, the result is “1234567890”
  • Cleaning account names: {account_name | REMOVE_CHARS, “!@#$%”}

    • Removes special characters that might cause issues in target systems

  • If the department is “Human Resources”, the result is “humanresources”
  • Creating system identifiers: {cost_center | REMOVE_WHITESPACE}

    • Ensures cost center codes have no embedded spaces

  • If code is “—ABC123___”, the result is “ABC123”
    If identifier is “xxxABC123”, the result is “ABC123”
    If code is “ABC123temp”, the result is “ABC123”
    If first_name = John and last_name = Smith, the result is j.smith.
  • {email | REMOVE\_DOMAIN}

    • If email = [email protected], the result is john.smith.

  • {email | REPLACE\_ALL, " ", "."}

    • If email = john [email protected], the result is [email protected].

  • {location | LOOKUP locationTable, location\_code, city}

    • If location = IL001, the result is Chicago (using a lookup table named locationTable).

  • {start\_date | DATE\_FORMAT, "01/02/2006" | UPPER}

    • If start_date = 2023-03-15, the result is 03/15/2023 (DATE_FORMAT doesn't typically need UPPER, but shows pipeline capability).

  • {hire\_date | DATE\_FORMAT, "Jan 2, 2006" | REPLACE\_ALL, " ", "\_"}

    • If hire_date = 2023-03-15, the result is Mar_15,_2023.

  • {office\_code | TRIM\_CHARS\_LEFT, ".0" | TRIM\_CHARS\_RIGHT, ".USCA"}

    • If office_code = 000.8675309.USCA, the result is 8675309.

  • {username | REMOVE\_CHARS, ".-\_" | TRIM | UPPER}

    • If username = "–john.doe_–", the result is JOHNDOE.

  • {employee\_id | REMOVE\_CHARS, "#" | TRIM\_CHARS, "0" | LEFT\_PAD, 6, "0"}

    • If employee_id = "##001234##", the result is 001234.

  • {department | REMOVE\_WHITESPACE | LOWER | REPLACE\_ALL, "&", "and"}

    • If department = "Sales & Marketing", the result is salesandmarketing.

  • TEST{| RANDOM_INTEGER, 1000, 9999}

    • Generates test IDs like TEST4827, TEST8391 (see RANDOM_INTEGER for details).

  • user_principal_name

    {first_name | SUB_STRING,0,1 | LOWER}.{last_name | LOWER}

    SUB_STRING,0,1

    LOWER}.{last_name

    email

    {first_name}{last_name}@company.com

    Yes

    Email address

    OktaAccountTransformer OktaUser

    login

    {first_name | SUB_STRING,0,1 | LOWER}.{last_name | LOWER}

    SUB_STRING,0,1

    LOWER}{last_name

    email

    {first_name}{last_name}@company.com

    Yes

    Email address

    username_prefix

    {first_name | SUB_STRING,0,1 | LOWER}.{last_name | LOWER}

    SUB_STRING,0,1

    LOWER}{last_name

    AzureADTransformer AzureADUser

    principal_name

    {first_name}{last_name}

    No

    Primary identifier

    mail_nickname

    {first_name | SUB_STRING,0,1 | LOWER}{last_name | LOWER}

    SUB_STRING,0,1

    LOWER}{last_name

    display_name

    {first_name} {last_name}

    Yes

    Display name

    GoogleAccountTransformer GoogleWorkspaceUser

    email

    {first_name}{last_name}@company.com

    No

    Primary email

    email_addresses

    {username}@company.com

    No

    Email list

    recovery_email

    {personal_email}

    Yes

    Backup email

    ContractorTransformer ActiveDirectoryUser

    account_name

    c-{username}

    No

    Contractor prefix

    distinguished_name

    CN={first_name} {last_name},OU=Contractors,OU={department},DC=company,DC=local

    Yes

    Contractor OU

    description

    Contractor - {vendor_company} - Start Date: {start_date}

    Yes

    Metadata

    RegionalEmailTransformer ExchangeUser

    email_address

    {username}@{region}.company.com

    No

    Regional email

    alias

    {first_name}.{last_name}@{region}.company.com

    Yes

    Regional alias

    ,
    memberOf
    ,
    roleOccupant
  • url, wWWHomePage

  • otherTelephone, otherMobile, otherIpPhone, otherFacsimileTelephoneNumber, otherHomePhone, otherPager, otherMailbox

  • And additional multi-value attributes including: objectClass, postalAddress, postOfficeBox, seeAlso, userCertificate, userSMIMECertificate, userPKCS12, securityIdentifierHistory, altSecurityIdentities, businessCategory, carLicense, homePostalAddress

  • created_by

    “Veza”

    Disabled

    isActive

    true

    Enabled

    manager_id

    " "

    Enabled

    isActive

    false

    Enabled

    first_name

    {first\_name}

    Enabled

    last_name

    {last\_name}

    Enabled

    email

    {first_name}.{last_name}@domain.com {first_name}_{last_name}@domain.com {last_name}@domain.com {firstname_initial}{last_name}@domain.com {firstname_initial}-{last_name}@domain.com {firstname_initial}{middlename_initial}{last_name}@domain.com {firstname_initial}-{last_name}[email protected] {last_name}-{firstname_initial}@domain.com

    -

    username

    `{email | REMOVE_DOMAIN}`

    Removes the domain from the email to create username

    "jsmith" is the output derived from [email protected]

    user_id

    `f{id | UPPER}`

    Converts ID to uppercase

    JSMITH" is the output derived from the userid, "jsmith"

    01/02/2006

    MM/DD/YYYY

    03/15/2023

    2006-01-02

    YYYY-MM-DD

    2023-03-15

    02-Jan-2006

    DD-MMM-YYYY

    15-Mar-2023

    Jan 2, 2006

    MMM D, YYYY

    ADAccountTransformer ActiveDirectoryUser

    account_name

    {display_full_name}

    No

    Basic account name

    distinguished_name

    CN={first_name} {last_name},OU={department},OU={location},DC=company,DC=local

    Yes

    Full AD path

    Attribute Synchronization
    Transformer Reference
    official Go time package documentation
    "[email protected]
    [email protected]

    Mar 15, 2023

    `{start_date | DATE_FORMAT, "01/02/2006"}`
    `{hire_date | DATE_FORMAT, "2006-01-02", "01/02/2006"}`
    `{timestamp | DATE_FORMAT, "20060102150405Z"}`
    `{account_expires | DATE_FORMAT, "20060102150405Z"}`
    `{event_date | DATE_FORMAT, "Monday, January 2, 2006"}`
    {utc_time | DATE_FORMAT, "2006-01-02 15:04:05 MST"}
    {timestamp | DATE_FORMAT, "Win32"}
    {date | DATE_FORMAT, "20010928060000.0Z"}
    {date | DATE_FORMAT, "20010928060000.0+0200"}
    IF sys_attr__would_be_value_len le 20
      {first_name | LOWER}.{last_name | LOWER | NEXT_NUMBER, 2, 3}
    ELSE IF sys_attr__would_be_value_len le 30
      {first_name | LOWER}.{last_name | LOWER | FIRST_N, 1 | NEXT_NUMBER, 2, 3}
    ELSE
      {first_name | LOWER | FIRST_N, 1}.{last_name | LOWER | FIRST_N, 1 | NEXT_NUMBER, 2, 3}
    username
    `{firstname}{lastname}`
    `{$target.username}@sample.com`
    >>[value1, value2, value3]
    organizationalStatus: ["Active", "Employee"]
    >>[Employee, Contractor, Temporary]
    organizationalStatus: ["Active", "Employee", "Contractor", "Temporary"]