Skip to main content

Field Creation and Mapping Configuration

Mapping files tell the migration tool how to translate fields between your source system and nevisID's SCIM schema. This page explains how to create user fields, the two mapping files, the SpEL expression syntax, and how to handle common mapping scenarios.

Pre-migration field setup in nevisIDM

Before running any migration, the target field structure must exist in nevisID - incoming SCIM data will only be stored if the corresponding properties are already defined. Some of this setup can be done through the nevisID administration GUI, specifically onProfileForApp and onRoleForApp properties can be created directly in the interface. However, general-purpose properties - including user global properties, profile global properties, and credential properties - cannot be created through the GUI and must be provisioned via the nevisIDM REST API before the migration is started. Please see examples for this among the references provided. It is therefore recommended to prepare an API script that creates all required custom properties in the correct scope, and to run and verify it against the target nevisID instance as part of the pre-migration setup, before any mapping files are configured or migration jobs are executed.

Pre-migration field setup in nevisIDM

Mapping Overview

Mapping files tell the migration tool how to translate fields between your source system and NevisID's SCIM schema. Mappings are defined in YAML files using Spring Expression Language (SpEL) expressions:

  • inbound_mapping.yml — maps source fields to NevisID SCIM attributes (used in bulk and continuous inbound modes)
  • outbound_mapping.yml — maps NevisID SCIM attributes back to legacy system fields (used in continuous outbound mode)
  • scim_relay_mapping.yml — defines attribute renaming between the NevisID SCIM extension schema and a target SCIM schema (used in SCIM Relay Outbound mode)

A Mapping Generator utility mode is available to automatically produce a skeleton inbound_mapping.yml by introspecting the live NevisID SCIM schema, reducing the manual effort of discovering every field name and building the YAML structure by hand. Complete the pre-migration user field setup before running the mapping generator.

Overview of mapping files

FileUsed in modesDirection
inbound_mapping.ymlBulk, Continuous InboundSource fields → SCIM attributes
outbound_mapping.ymlContinuous Outbound (legacy backend)SCIM attributes → foreign system fields
scim_relay_mapping.ymlContinuous Outbound (SCIM backend)nevisIDM SCIM schema → target SCIM schema

Configure the paths to these files in application.yml:

migration:
mapping:
inbound-file: config/inbound_mapping.yml
outbound-file: config/outbound_mapping.yml
scim-relay-file: config/scim_relay_mapping.yml

SpEL expression variables

Mapping values are Spring Expression Language (SpEL) expressions enclosed in double quotes. The available root variables differ by mode:

VariableAvailable inContains
#sourceInbound mappingMap of the raw source record (one key per column/field)
#scimOutbound mappingThe SCIM User resource (core attributes)
#extOutbound mappingThe nevisIDM extension (urn:nevis:idm:scim:schemas:v1:extension:User)
#credOutbound mapping — credential blockA single credential object from the extension
#profOutbound mapping — profile blockA single profile object from the extension

Expressions are parsed once and cached by SpelExpressionCache, so there is no performance penalty for complex expressions in large migrations.

Inbound mapping example

nevisScim:
userName: "#source['loginId']"
name:
givenName: "#source['firstName']"
familyName: "#source['lastName']"
emails:
- value: "#source['email']"
primary: "true"
urn:nevis:idm:scim:schemas:v1:extension:User:
birthDate: "#source['dob']"
credentials:
- type: "'PASSWORD'"
password: "#source['passwordHash']"
state: "'ACTIVE'"
profiles:
- extId: "#source['profileId']"
name: "#source['profileName']"

Notice that literal string values require inner single quotes: "'PASSWORD'". Field references use bracket notation: "#source['fieldName']".

Outbound mapping example

foreign:
loginId: "#scim['userName']"
firstName: "#scim['name']['givenName']"
email: "#scim['emails'][0]['value']"
birthDate: "#ext['birthDate']"
credential:
type: "#cred['type']"
password: "#cred['type'] == 'PASSWORD' ? #cred['password'] : null"
context: "#cred['type'] == 'MTAN' ? #cred['context'] : null"
profile:
profileId: "#prof['extId']"
profileName: "#prof['name']"

Common mapping scenarios

Concatenating fields

displayName: "#source['firstName'] + ' ' + #source['lastName']"

Conditional value

active: "#source['status'] == 'A' ? 'true' : 'false'"

Default value when source field is null

locale: "#source['locale'] ?: 'de-CH'"

Custom transformation function

Register a custom function via MappingFunctions / FunctionRegistrar in the tool's extension point, then call it in your mapping:

phoneNumber: "#normalizePhone(#source['phone'])"

Supported credential types

The type field in the credentials block must be one of the 22 supported values:

PASSWORD, MTAN, GENERIC, CONTEXTPASSWORD, KERBEROS, SECURID, CERTIFICATE, OATH, FIDO_UAF, SAMLFEDERATION, RECOVERY_CODE, TICKET, SAFEWORDUSER, OTP, TEMPSTRONGPASSWORD, VASCO, PUK, URLTICKET, DEVICEPASSWORD, MOBILESIGNATURE, SECURITYQUESTIONS, FIDO2

Validating your mappings

After editing a mapping file, always validate using test-run mode before a live run:

./gradlew runBulk -PtestRun

The [TEST-RUN] log output shows the full SCIM payload that would be sent for each user, making it easy to confirm field values are correct.

Next steps

  • To run a bulk import using your mapping, see Running Your First Migration.
  • To set up ongoing sync, see Continuous Sync Setup.