Configure fallback formatters for uniquely identifying attributes during identity synchronization
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.
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 Sync Identities Action to ensure new users can be onboarded efficiently, regardless of naming 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.
Fallback formatters can be configured as part of the "Sync Identities" action within a Lifecycle Management workflow:
Edit or create a Lifecycle Management policy
Edit the workflow containing the Sync Identities action
In the Sync Identities action configuration, click Add Fallback
Configure the Transformer to use as a fallback pattern for the unique attribute that might experience conflicts
Close the action sidebar and save your changes to the policy.
Several transformers can be used for implementing fallback formatters depending on your specific use case.
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
In addition to NEXT_NUMBER
, other transformers can be valuable for creating fallback formatters:
Using Random Alphanumeric for Unique Usernames:
{first_initial}{last_name}{RANDOM_ALPHANUMERIC_GENERATOR(4)}
This could generate usernames like jsmith8f3d
instead of sequential jsmith1
, jsmith2
, etc.
Using UUID for Guaranteed Uniqueness:
{first_initial}{last_name}-{UUID_GENERATOR() | SUB_STRING,0,8}
This would append the first 8 characters of a UUID, creating identifiers like jsmith-a7f3e9c2
.
When configuring a fallback formatter with the NEXT_NUMBER
transformer:
Select the attribute that requires uniqueness (e.g., username, email)
Configure the primary pattern (e.g., {first_initial}{last_name}
)
Add a fallback using the NEXT_NUMBER
transformer to generate sequential alternatives:
{first_initial}{last_name}{NEXT_NUMBER(1, 10)}
This will generate up to 10 alternatives: jsmith1, jsmith2, ... jsmith10
Here are some commonly used fallback patterns:
{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
{first_name}{last_initial}
{first_name}{last_initial}{NEXT_NUMBER(1, 10)}
johns, johns1, johns2
When Lifecycle Management attempts to provision a new identity with a unique attribute value that already exists:
The system first tries the primary format (e.g., jsmith
)
If a conflict is detected, it automatically tries the first alternative using the NEXT_NUMBER
transformer (e.g., jsmith1
)
If that value also exists, it tries the next alternative (e.g., jsmith2
)
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)
This automated conflict resolution ensures provisioning can proceed without manual intervention, even when your standard naming conventions result in conflicts.
Configure how user attributes from a source of identity are transformed and synchronized for target user accounts
When creating workflows in Lifecycle Management policies to create, sync, or de-provision 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 from the source of identity, such as an identity provider, HR system, or CSV upload. Attributes can be synchronized once or kept in continuous sync as changes occur over the user’s lifetime.
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.
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: Mote a user’s Active Directory account to an OU reserved for terminated accounts.
When synchronizing a user’s attributes, Veza can apply one (or more) transformations to convert the source attribute values to a more suitable format, and apply the result within the target application as user account attribute.
For example, a transformer might remove the domain from an email address, replace special characters, or convert a string from upper case to lower case. Transformers can apply to any attribute on the target user account with the complexity varying depending on your business requirements.
See the following sections for more information about formatting destination attributes and possible transformations:
Continuous Sync keeps identity attributes in target systems up to date with your source of truth. It has three configuration levels that work together to determine how attributes are synchronized:
Workflow Level
The workflow's continuous sync setting controls change detection:
When enabled: The workflow monitors for any changes in the source system
When disabled: The workflow only runs during initial provisioning
Action Level
For Sync Identity actions, this controls whether existing entities can be updated:
When enabled: The action can update existing entities
When disabled: The action only sets attributes during initial creation
Attribute Level
Individual attributes can be configured for continuous sync:
When enabled: The attribute will be updated when changes are detected
When disabled: The attribute is only set during initial creation
All three levels must be enabled for an attribute to be continuously synchronized. For example, if you want to keep an employee's department updated:
Enable continuous sync on the workflow to monitor for changes
Enable continuous sync on the sync action to allow updates
Enable continuous sync on the department attribute transformer
Recommended Settings
Enable continuous sync for attributes that change during employment:
Employee name
Department
Title
Manager
Cost Center
AD Distinguished Name (DN)
AD User Principal Name (UPN)
AD Email
Disable continuous sync for stable identifiers:
Active Directory sAMAccountName
Email Addresses (for Email Write-Back action)
This configuration ensures that dynamic attributes stay updated while preserving stable identifiers.
As part of implementing lifecycle management processes with Veza, you should create sets of common transformers to define how values such as username, login, or ID should be sourced for each target application. These transformers can then be reused across all identity sync and de-provision workflows involving those targets. Create common transformers to consistently form attributes for specific entity types, and re-use them to avoid errors and save time when creating actions for that entity type.
For instance, 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:
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
user_principal_name
{username}@company.com
Yes
UPN format
{username}@company.com
Yes
Email address
OktaAccountTransformer OktaUser
login
{username}@company.com
No
Primary login
{username}@company.com
Yes
Email address
username_prefix
{first_name | SUB_STRING,0,1 | LOWER}{last_name | LOWER}
No
Username creation
AzureADTransformer AzureADUser
principal_name
{username}@company.com
No
Primary identifier
mail_nickname
{first_name | SUB_STRING,0,1 | LOWER}{last_name | LOWER}
No
Email alias
display_name
{first_name} {last_name}
Yes
Display name
GoogleAccountTransformer GoogleWorkspaceUser
{username}@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
Transformers can be defined at the policy level or when configuring an individual action in a workflow. To configure a transformer, add basic details as well as how to source the value of each attribute:
Give the transformer a name and description, and specify the data source it applies to.
Entity Type: Choose the target entity type in the destination system.
Click Add Attribute. The Destination Attribute dropdown will list available attributes for the chosen entity type.
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: Combine attribute formatters with the |
character to apply more complex transformations, such as combining the first letter of a first_name
and the first four characters of a last_name
to generate a local username
. See Pipeline Functions for more examples
Continuous Sync: Enabling this option always syncs the attribute, whilst applying any defined transformations. By default, attributes will not sync if the target identity is already created.
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 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 according to a function, or some combination of the three.
Note that 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 over the user or account lifecycle.
To create a destination attribute with a fixed value, enter the desired value when configuring the formatter.
For setting the creator attribute:
created_by
"Veza"
Disabled
For activating a re-hired employee:
active
true
Enabled
To set empty values (common for de-provisioning flows):
manager_id
" "
Enabled
active
false
Enabled
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:
first_name
{first_name}
Enabled
last_name
{last_name}
Enabled
{first_name}.{last_name}@domain.com
-
Based on the user metadata that is available from your source of identity, 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. If an attribute value needs to be altered for compatibility with the target system, 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:
username
{email | REMOVE_DOMAIN}
Removes domain from email to create username
user_id
{id | UPPER}
Converts ID to uppercase
Table of transformation functions
See the table below for all supported 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
Please contact Veza if additional transformations are required for your use case.
ASCII
Removes non-printable characters and replaces non-ASCII characters with their closest ASCII equivalents.
None
Yes
No
ASCII("Łukasz Gruba")
results in Lukasz Gruba
COUNTRY_CODE_ISO3166
Transforms country code to ISO 3166 format.
Format (STRING, optional): [alpha2, alpha3, numeric], defaults to alpha2
Yes
No
COUNTRY_CODE_ISO3166("US", alpha3)
results in USA
DATE_FORMAT
Transforms dates to a different format using Go time layout syntax.
Output Layout (STRING, required): Go time layout for output format. Input Layout (STRING, optional): Go time layout for input format
Yes
No
{start_date | DATE_FORMAT, "01/02/2006"}
formats date as MM/DD/YYYY
FIRST_N
Picks the first N characters of a string.
Length (NUMBER, required): Number of characters to return
Yes
No
FIRST_N("first_name", 4)
results in firs
FROM_ENTITY_ATTRIBUTE
Transforms a string from an attribute of another entity in the graph.
EntityType (STRING, required), SourceAttribute (STRING, required), TargetAttribute (STRING, required)
Yes
No
FROM_ENTITY_ATTRIBUTE("Employee", "ID", "ManagerID")
results in the Manager ID for the employee
LANGUAGE_RFC5646
Transforms language to RFC 5646 format.
None
Yes
No
LANGUAGE_RFC5646("Spanish")
results in es
LAST_N
Picks the last N characters of a string.
Length (NUMBER, required): Number of characters to return
Yes
No
LAST_N("last_name", 5)
results in name
LEFT_PAD
Left pads a string with a character.
Length (NUMBER, required), Pad (CHARACTER, optional): Default is space
Yes
No
LEFT_PAD("123", 5, "0")
results in 00123
LOOKUP
Transforms a value using a lookup table.
Table Name (STRING, required), Column Name (STRING, required), Return Column Name (STRING, required)
Yes
No
LOOKUP("IL001", "locationTable", "location_code", "city")
results in Chicago
LOWER
Transforms string to lowercase.
None
Yes
No
LOWER("HELLO")
results in hello
LOWER_CAMEL_CASE
Transforms string to lower camel case.
None
Yes
No
LOWER_CAMEL_CASE("hello world")
results in helloWorld
LOWER_SNAKE_CASE
Transforms string to lowercase with underscores.
None
Yes
No
LOWER_SNAKE_CASE("Hello World")
results in hello_world
NEXT_NUMBER
Generates a set of integers as strings.
BeginInteger (NUMBER, required), Length (NUMBER, required)
No
Yes
NEXT_NUMBER(2, 3)
results in "", "2", "3", "4"
. Note: NEXT_NUMBER can also be used within IF/ELSE conditional transformers for intelligent username generation with automatic fallback strategies.
PHONE_NUMBER_E164
Transforms phone number to E.164 format.
Region (STRING, optional): ISO 3166-1 alpha-2 format
Yes
No
PHONE_NUMBER_E164("+1-800-555-1212")
results in +18005551212
RANDOM_ALPHANUMERIC_GENERATOR
Generates a random alphanumeric string.
Length (NUMBER, required)
No
No
RANDOM_ALPHANUMERIC_GENERATOR(8)
results in a1B2c3D4
RANDOM_NUMBER_GENERATOR
Generates a random number string.
Length (NUMBER, required)
No
No
RANDOM_NUMBER_GENERATOR(4)
results in 4829
RANDOM_STRING_GENERATOR
Generates a random string.
Length (NUMBER, required)
No
No
RANDOM_STRING_GENERATOR(6)
results in uFkLxw
REMOVE_CHARS
Removes all instances of specified characters from a string.
Characters (STRING, required): Characters to be removed
Yes
No
REMOVE_CHARS("[email protected]", "@.")
results in FirstLastexamplecom
REMOVE_DIACRITICS
Removes diacritics (accents, etc.) from input string.
None
Yes
No
REMOVE_DIACRITICS("José")
results in Jose
REMOVE_DOMAIN
Removes the domain from an email.
None
Yes
No
REMOVE_DOMAIN("[email protected]")
results in user
REMOVE_WHITESPACE
Removes all whitespace characters from a string.
None
Yes
No
REMOVE_WHITESPACE("First Last")
results in FirstLast
REPLACE_ALL
Replaces all instances of one string with another.
Original (STRING, required), New (STRING, required)
Yes
No
REPLACE_ALL("hello world", " ", "_")
results in hello_world
RIGHT_PAD
Right pads a string with a character.
Length (NUMBER, required), Pad (CHARACTER, optional): Default is space
Yes
No
RIGHT_PAD("123", 5, "0")
results in 12300
SPLIT
Splits a string and returns the string at the given index.
Split String (STRING, required), Index (NUMBER, required)
Yes
No
SPLIT("[email protected]", "@", 0)
results in first.last
SUB_STRING
Picks a substring from the original value.
Offset (NUMBER, required), Length (NUMBER, required)
Yes
No
SUB_STRING("hello", 0, 3)
results in hel
TRIM
Removes spaces before and after a string.
None
Yes
No
TRIM(" hello ")
results in hello
TRIM_CHARS
Removes all specified characters from the beginning and end of a string.
Characters (STRING, required): Characters to be trimmed
Yes
No
TRIM_CHARS("....first.last----", ".-")
results in first.last
TRIM_CHARS_LEFT
Removes all specified characters from the beginning of a string.
Characters (STRING, required): Characters to be trimmed from the left
Yes
No
TRIM_CHARS_LEFT("....first.last----", ".-")
results in first.last----
TRIM_CHARS_RIGHT
Removes all specified characters from the end of a string.
Characters (STRING, required): Characters to be trimmed from the right
Yes
No
TRIM_CHARS_RIGHT("....first.last----", ".-")
results in ....first.last
UPPER
Transforms string to uppercase.
None
Yes
No
UPPER("hello")
results in HELLO
UPPER_CAMEL_CASE
Transforms string to upper camel case.
None
Yes
No
UPPER_CAMEL_CASE("hello world")
results in HelloWorld
UPPER_SNAKE_CASE
Transforms string to uppercase with underscores.
None
Yes
No
UPPER_SNAKE_CASE("hello world")
results in HELLO_WORLD
UUID_GENERATOR
Generates a UUID.
None
No
No
UUID_GENERATOR()
results in 123e4567-e89b-12d3-a456-426614174000
The ASCII transformer is particularly useful when working with international user data or systems that have strict character limitations (such as Active Directory sAMAccountName restrictions). This transformer performs two main operations:
Removes all non-printable characters (including control codes, zero-width spaces, tabs, and newlines)
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.
The DATE_FORMAT transformer formats date strings using Go time package layout syntax. This transformer is useful for converting between different date formats, such as transforming dates for LDAP integration or standardizing 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 official Go time package documentation.
Date Components:
2006
= 4-digit year
06
= 2-digit year
01
= 2-digit month (01-12)
1
= 1-digit month (1-12)
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
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)
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)
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
Common Layout Examples
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
Mar 15, 2023
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
Usage Examples
Basic Date Formatting:
{start_date | DATE_FORMAT, "01/02/2006"}
Formats any recognized date input into MM/DD/YYYY format.
Converting Between Specific Formats:
{hire_date | DATE_FORMAT, "2006-01-02", "01/02/2006"}
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 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.
{timestamp | DATE_FORMAT, "20060102150405Z"}
Converts a date to LDAP Z time format for directory integration.
Example for LDAP account expiration:
{account_expires | DATE_FORMAT, "20060102150405Z"}
Human-Readable Format:
{event_date | DATE_FORMAT, "Monday, January 2, 2006"}
Outputs a full, human-readable date format.
Time Zone Handling:
{utc_time | DATE_FORMAT, "2006-01-02 15:04:05 MST"}
Includes time zone information in the output.
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
These transformers provide capabilities for cleaning, formatting, and standardizing 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 "[email protected]", the result is "johndoeexamplecom"
Phone number formatting: {phone_number | REMOVE_CHARS, "()- "}
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
REMOVE_WHITESPACE
The REMOVE_WHITESPACE transformer removes all whitespace characters (spaces, tabs, newlines) from a string. It can help create compact identifiers or ensuring 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}
If department is "Human Resources", the result is "humanresources"
Creating system identifiers: {cost_center | REMOVE_WHITESPACE}
Ensures cost center codes have no embedded spaces
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, "-_"}
If code is "---ABC123___", the result is "ABC123"
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"}
If identifier is "xxxABC123", the result is "ABC123"
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"}
If code is "ABC123temp", the result is "ABC123"
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:
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}
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.
You can pipeline multiple transformation functions together, separated by a |
. 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}
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
.
Use lookup tables to transform identity attributes for target systems
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
Geographic Information:
Transform location codes to country, region, city, or timezone information
Map office codes to physical addresses or facility types
Organizational Mapping:
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
The Table Lookup Transformer references CSV-based mappings between source and destination values. When synchronizing user attributes, Veza:
Takes the source attribute value
Looks up this value in the specified lookup table
Returns the corresponding value from the designated return column
Applies this value to the target attribute
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:
location_code,state_code,state,city
MN001,MN,Minnesota,Minneapolis
CA001,CA,California,Los Angeles
TX001,TX,Texas,Houston
TX002,TX,Texas,Austin
To create a new lookup table:
Navigate to the Lookup Tables tab within your policy configuration
Click Edit mode to enable policy changes
Click Add New to create a new lookup table
Provide a Name and optional Description for the lookup table
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
From the Lookup Tables tab, you can:
Edit table descriptions or upload a new CSV
Delete tables that are no longer needed
To use a Table Lookup Transformer in a common or action-synced attribute:
In Destination Attribute, choose the attribute on the target entity that will be updated
In Formatter, choose the source attribute to transform
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:
{<value> | LOOKUP <table_name>, <column_name>, <return_column_name>}
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
<return_column_name>
is the column containing the value to return
Assuming a user has "location": "IL001"
and a lookup table named locationTable
structured as shown earlier:
{location} | LOOKUP locationTable, location_code, city
"Chicago"
{location} | LOOKUP locationTable, location_code, state
"Illinois"
{location} | LOOKUP locationTable, location_code, state_code
"IL"
You can combine lookup transformations with other transformation functions in a pipeline:
{location | LOOKUP locationTable, location_code, state_code | LOWER}
This would look up the state_code
corresponding to the location
value and convert it to lowercase.
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.
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
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.
Document Mappings: Add descriptions for each lookup table to explain its purpose
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.
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