How to Map User Identities

TL;DR

Add identities to LocalUser objects so Veza can correlate users across integrated systems. Use map_to_identity: true in field_mapping for simple cases; use a record-transform hook for conditional or multi-source logic.

Background

When Veza ingests users from multiple systems, it uses identities to link the same person across those systems. For example, a user in your app and the same user in your IdP can be correlated if they share an email address stored as an identity on both records.

Identities are attached to LocalUser objects via add_identity(). Each user can have multiple identities — typically an email address, a username, or an external identifier.

Prerequisites

  • An integration with destination: LocalUser in at least one source

  • Source data that includes a field suitable for identity correlation (email, username, UPN, etc.)



Option 2: Record-transform hook (for conditional or computed identities)

Use a hook when you need to:

  • Skip identity assignment based on a condition

  • Compute an identity from multiple fields

  • Read from a secondary data source

# modules/hooks.py
import logging
from oaa.hooks.decorators import OAAHookEvent, record_transform_non_stream

logger = logging.getLogger(__name__)


@record_transform_non_stream()
def add_email_identity(record, provider, **kwargs):
    user = provider.local_users.get(record['unique_id'])
    if not user:
        return
    if record.get('email'):
        user.add_identity(record['email'])

Register the hook in config.yaml:

hooks:
  - add_email_identity

When to prefer hooks over config

Scenario

Use

Map a single column to identity for all records

map_to_identity: true

Map multiple columns to identity for all records

map_to_identity: true on each

Skip identity assignment based on a field value

Hook

Compute identity from two or more fields

Hook

Look up identity from a second data source

Hook


Verify identities are set

After running the integration in --save-json mode, confirm identities appear in the payload:

oaa app run --config=config.yaml --save-json
jq '.local_users[] | {name: .name, identities: .identities}' output.json

Expected output:

{
  "name": "Alice Smith",
  "identities": ["alice@example.com"]
}