Skip to main content

Migration Planning Guide

Before starting the technical migration process, careful planning is essential to ensure a smooth transition. This guide covers critical planning considerations including merging multiple data sources, defining your user attribute structure, and handling social providers and verification methods.

Prerequisites

Review the Migration Overview to understand different migration approaches, then use this guide to plan your specific migration strategy.

Table of Contents

  1. Merging Multiple Data Sources
  2. Defining User Attribute Structure
  3. Handling Social Providers
  4. Handling Verification Methods
  5. Migration Planning Checklist

Merging Multiple Data Sources

When migrating from multiple systems or data sources, you need a clear strategy to merge user data while maintaining data integrity and avoiding duplicates.

Understanding the Challenge

Merging multiple sources presents several challenges:

  • Duplicate Users: The same user may exist in multiple systems with different identifiers
  • Conflicting Data: Different systems may have different values for the same attribute
  • Incomplete Data: Some attributes may only exist in one source system
  • Data Quality: Varying data quality across different sources

Step 1: Identify User Identity Keys

Determine how to uniquely identify the same user across different sources:

Source SystemPrimary IdentifierSecondary IdentifiersNotes
System Aemailusername, customer_idEmail is verified
System Buser_idemail, phoneEmail may be unverified
System Caccount_numberemail, social_idLegacy system

Decision Criteria:

  • Use email as primary identifier if it's verified and unique across systems
  • Use mobile number if email is not reliable
  • Create a mapping table if no single identifier is reliable
  • Consider fuzzy matching for cases where identifiers differ slightly

Step 2: Define Merge Strategy

Choose how to handle conflicts when the same user exists in multiple sources:

Strategy A: Source Priority

Assign priority to each source system. Higher priority sources override lower priority ones.

Example:

Priority 1: CRM System (most up-to-date)
Priority 2: Legacy Auth System (has passwords)
Priority 3: Marketing System (has preferences)

Implementation:

{
"mergeStrategy": "priority",
"sources": [
{"name": "crm", "priority": 1, "fields": ["email", "given_name", "family_name", "customFields"]},
{"name": "auth", "priority": 2, "fields": ["password_hash_info", "userStatus"]},
{"name": "marketing", "priority": 3, "fields": ["customFields.newsletter_consent"]}
]
}

Strategy B: Most Recent Wins

Use the most recently updated value for each field.

Use when:

  • All sources are equally reliable
  • You have reliable timestamp data
  • You want to preserve the latest information

Strategy C: Field-Specific Rules

Define specific merge rules for each field type.

Example Rules:

  • Email: Use verified email over unverified
  • Password: Use the most recent password hash
  • Profile Data: Use the most complete data set
  • Custom Fields: Merge arrays, use latest for single values

Step 3: Handle Duplicate Detection

Implement duplicate detection before migration:

Pre-Migration Deduplication

  1. Extract all users from all source systems
  2. Normalize identifiers (lowercase emails, format phone numbers)
  3. Identify potential duplicates using matching algorithms
  4. Review and confirm duplicates manually or with business rules
  5. Create merge mapping for confirmed duplicates

Matching Algorithms

Exact Match:

  • Same email address
  • Same mobile number
  • Same unique identifier

Fuzzy Match:

  • Similar email addresses (typos, domain variations)
  • Similar names with same identifier
  • Same phone number with different formatting

Example Deduplication Logic:

function identifyDuplicates(users) {
const duplicates = [];
const emailMap = new Map();

users.forEach(user => {
const normalizedEmail = user.email.toLowerCase().trim();
if (emailMap.has(normalizedEmail)) {
duplicates.push({
primary: emailMap.get(normalizedEmail),
duplicate: user,
matchType: 'email'
});
} else {
emailMap.set(normalizedEmail, user);
}
});

return duplicates;
}

Step 4: Create Unified User Structure

Before migrating to cidaas, create a unified user structure that combines data from all sources:

{
"sub": "generated-or-mapped-sub",
"email": "[email protected]",
"email_verified": true,
"mobile_number": "+49123456789",
"mobile_number_verified": true,
"given_name": "John",
"family_name": "Doe",
"userStatus": "VERIFIED",
"provider": "self",
"password_hash_info": {
"algorithmTypeId": "BCRYPT_10",
"passwordHash": "$2b$10$..."
},
"identities": [
{
"provider": "facebook",
"providerUserId": "fb_12345",
"email": "[email protected]"
},
{
"provider": "google",
"providerUserId": "google_67890",
"email": "[email protected]"
}
],
"customFields": {
"customer_id": "CUST-12345",
"legacy_system_id": "LEG-67890",
"newsletter_consent": true,
"marketing_source": "website"
}
}

Step 5: Migration Order

When merging multiple sources, migrate in a specific order:

  1. Primary Source First: Migrate the most authoritative source
  2. Secondary Sources: Add identities and additional data
  3. Verification: Ensure all merged users are correctly linked

Example Migration Sequence:

Week 1: Migrate primary auth system (passwords, basic profile)
Week 2: Add social provider identities from social login system
Week 3: Merge custom fields and preferences from CRM
Week 4: Verify and reconcile any conflicts

Defining User Attribute Structure

Before migration, clearly define which user attributes will be stored in cidaas and how they will be structured.

Step 1: Categorize Attributes

Classify attributes into system fields and custom fields:

System Fields (Built-in)

cidaas provides standard OIDC/OAuth2 system fields:

FieldTypeRequiredDescription
subStringYesUnique user identifier
emailStringRecommendedPrimary email address
email_verifiedBooleanRecommendedEmail verification status
mobile_numberStringOptionalMobile phone number
mobile_number_verifiedBooleanOptionalMobile verification status
given_nameStringOptionalFirst name
family_nameStringOptionalLast name
middle_nameStringOptionalMiddle name
nicknameStringOptionalDisplay name
usernameStringOptionalUsername
userStatusEnumYesVERIFIED, PENDING, DECLINED, DELETED
providerStringYesAuthentication provider (self, facebook, etc.)
birthdateDateOptionalDate of birth
localeStringOptionalUser locale
pictureStringOptionalProfile picture URL

Custom Fields

Define custom fields for business-specific data:

Considerations:

  • Data Type: String, Number, Boolean, Date, Array, Object
  • Required vs Optional: Which fields are mandatory?
  • Validation Rules: Format, length, pattern requirements
  • Sensitivity: PII, financial, health data considerations

Example Custom Fields:

{
"customFields": {
"customer_id": "CUST-12345", // String
"loyalty_points": 1250, // Number
"preferred_language": "en", // String
"newsletter_consent": true, // Boolean
"registration_date": "2024-01-15", // Date (as string)
"preferred_categories": ["electronics", "books"], // Array
"billing_address": { // Object
"street": "123 Main St",
"city": "Berlin",
"zip": "10115"
}
}
}

Step 2: Field Mapping Strategy

Create a mapping document from source systems to cidaas:

Source FieldSource Systemcidaas FieldTransformationNotes
user_emailSystem AemailLowercase, trimPrimary identifier
email_verifiedSystem Aemail_verifiedBoolean conversionMap "yes" → true
first_nameSystem Agiven_nameTitle caseCapitalize first letter
last_nameSystem Afamily_nameTitle caseCapitalize first letter
phoneSystem Amobile_numberE.164 formatAdd country code
statusSystem AuserStatusEnum mapping"active" → "VERIFIED"
customer_numberSystem BcustomFields.customer_idDirectBusiness identifier
preferencesSystem BcustomFields.preferencesJSON stringifyComplex object

Step 3: Data Quality and Validation

Define validation rules for each field:

Email Validation:

  • Format validation (RFC 5322)
  • Domain validation
  • Disposable email detection (configurable)
  • Uniqueness check

Mobile Number Validation:

  • Format validation (E.164 recommended)
  • Country code validation
  • Uniqueness check (if used as identifier)

Custom Field Validation:

  • Type checking
  • Format validation (regex patterns)
  • Length constraints
  • Value constraints (enums, ranges)

Step 4: Field Setup in cidaas

Before migration, configure fields in cidaas:

  1. Enable Required System Fields

    • Navigate to Field Settings
    • Enable all system fields you plan to use
    • Configure field requirements (required, optional, hidden)
  2. Create Custom Fields

    • Define custom field names
    • Set data types
    • Configure validation rules
    • Set field visibility and editability
  3. Test Field Configuration

    • Create test users with all field types
    • Verify validation rules work correctly
    • Test field display in hosted pages

Handling Social Providers

Migrating users with social provider accounts (Facebook, Google, Apple, etc.) requires special consideration to maintain account linking and authentication capabilities.

Understanding Social Provider Identities

In cidaas, social providers are represented as identities linked to a user account. A single user can have multiple identities (e.g., email/password + Facebook + Google).

Step 1: Identify Social Provider Users

From your source systems, identify users who have social provider accounts:

Questions to Answer:

  • Which social providers are currently supported?
  • How many users have social provider accounts?
  • Do users have multiple social providers linked?
  • Are social provider accounts the primary authentication method?

Step 2: Map Social Provider Data

Extract and map social provider information:

Source Datacidaas Identity FieldExample
Provider nameprovider"facebook", "google", "apple"
Provider user IDproviderUserId"1234567890"
Provider emailemail"[email protected]"
Provider usernameusername"johndoe"
Provider picturepicture"https://..."

Step 3: Migration Strategies for Social Providers

Strategy A: Migrate as Identities

If users have a primary account (email/password) and social providers:

  1. Migrate primary account first with email/password
  2. Add social provider identities to the same user using the identities array
  3. Ensure consistent sub across all identities

Example:

{
"sub": "8dfc4306-9f3b-4a33-95d0-98c8954da2c1",
"email": "[email protected]",
"provider": "self",
"password_hash_info": {...},
"identities": [
{
"provider": "facebook",
"providerUserId": "fb_123456789",
"email": "[email protected]"
},
{
"provider": "google",
"providerUserId": "google_987654321",
"email": "[email protected]"
}
]
}

Strategy B: Social-Only Users

If users only have social provider accounts (no email/password):

  1. Use social provider email as primary identifier
  2. Set provider to the social provider name
  3. No password hash required
  4. Consider email verification status from provider

Example:

{
"sub": "8dfc4306-9f3b-4a33-95d0-98c8954da2c1",
"email": "[email protected]",
"email_verified": true,
"provider": "google",
"identities": [
{
"provider": "google",
"providerUserId": "google_987654321",
"email": "[email protected]"
}
]
}

Step 4: Account Linking Considerations

Prevent Duplicate Accounts:

When migrating social provider users, ensure you don't create duplicate accounts:

  1. Check user existence before creating new account
  2. Use email as identifier to link social provider to existing account
  3. Use sub consistently when adding identities to existing users

Example Linking Logic:

async function migrateSocialUser(socialUser) {
// Check if user with this email already exists
const existingUser = await checkUserExistence(socialUser.email);

if (existingUser) {
// Add social provider identity to existing user
return await addIdentityToUser(existingUser.sub, {
provider: socialUser.provider,
providerUserId: socialUser.providerUserId
});
} else {
// Create new user with social provider as primary
return await createUserWithSocialProvider(socialUser);
}
}

Step 5: Post-Migration Verification

After migrating social provider users:

  1. Test social login for each provider
  2. Verify account linking works correctly
  3. Check user profile shows all linked providers
  4. Test account unlinking if supported

Handling Verification Methods

Users may have various verification methods (MFA, email verification, phone verification) that need to be migrated or reconfigured.

Step 1: Identify Verification Methods

Determine which verification methods exist in your source systems:

Verification MethodSource SystemMigration Approach
Email verificationSystem AMigrate email_verified status
Mobile verificationSystem AMigrate mobile_number_verified status
PasswordSystem AMigrate password_hash_info
TOTP (Authenticator)System A Cannot migrate (re-enroll)
Backup codesSystem ACannot migrate (regenerate)
FIDO2/WebAuthnSystem ACannot migrate (re-enroll)
Pattern/PINSystem ACannot migrate (re-enroll)

Step 2: Migratable vs Non-Migratable Methods

Migratable Verification Methods

These can be migrated directly:

Email Verification:

{
"email": "[email protected]",
"email_verified": true // Migrate status from source
}

Mobile Number Verification:

{
"mobile_number": "+49123456789",
"mobile_number_verified": true // Migrate status from source
}

TOTP (Time-based One-Time Password): If your source system uses TOTP and cidaas supports importing TOTP secrets:

{
"verificationMethods": [
{
"method": "TOTP",
"friendlyName": "Google Authenticator",
"secret": "base32_encoded_secret",
"verified": true
}
]
}

Note: TOTP secret migration depends on cidaas API support. Check the Verification API documentation for current capabilities.

Non-Migratable Verification Methods

These require user re-enrollment:

  • SMS OTP: Phone numbers must be re-verified (unless email_verified is true)
  • Email OTP: Email must be re-verified (unless email_verified is true)
  • Backup Codes: Must be regenerated
  • FIDO2/WebAuthn: Security keys must be re-enrolled
  • Pattern/PIN: Must be re-setup
  • Push Notifications: Must be re-configured

Step 3: Migration Strategy for Verification

Strategy A: Migrate Status Only

For email and mobile verification, migrate the verification status:

Advantages:

  • Users don't need to re-verify immediately
  • Smooth user experience
  • Faster migration

Considerations:

  • Only migrate if source system verification is trustworthy
  • Consider re-verification for high-security scenarios

Implementation:

{
"email": "[email protected]",
"email_verified": true, // From source system
"mobile_number": "+49123456789",
"mobile_number_verified": true // From source system
}

Strategy B: Require Re-Verification

Force users to re-verify after migration:

Advantages:

  • Ensures data accuracy
  • Confirms user still has access
  • Higher security

Disadvantages:

  • Users must complete verification flow
  • May cause friction

Implementation:

{
"email": "[email protected]",
"email_verified": false, // Force re-verification
"mobile_number": "+49123456789",
"mobile_number_verified": false // Force re-verification
}

Strategy C: Gradual Re-Verification

Migrate status but require re-verification on next login:

Advantages:

  • Balance between UX and security
  • Users verify when they naturally log in

Implementation:

  1. Migrate with email_verified: true
  2. Set flag to require verification on next login
  3. User verifies during normal login flow

Migration Planning Checklist

Use this comprehensive checklist to ensure all planning aspects are covered:

Pre-Migration Planning

  • Data Source Analysis

    • Identify all source systems
    • Document data structure for each source
    • Assess data quality in each source
    • Identify data owners and stakeholders
  • User Identity Strategy

    • Define primary identifier (email, mobile, custom)
    • Create user identity mapping rules
    • Plan duplicate detection approach
    • Define merge conflict resolution rules
  • Attribute Structure

    • List all attributes to migrate
    • Categorize system vs custom fields
    • Define custom field structure
    • Configure fields in cidaas before migration
    • Create field mapping documentation
  • Social Provider Planning

    • Identify all social providers in use
    • Document social provider user count
    • Plan account linking strategy
    • Test social provider configuration in cidaas
  • Password Migration

    • Identify password hashing algorithms
    • Verify algorithm support in cidaas
    • Plan password hash format conversion
    • Configure migration mode in cidaas

Technical Preparation

  • API Setup

    • Create migration app with cidaas:bulk_user_create scope
    • Test Client Credentials flow
    • Verify API access and permissions
    • Set up monitoring and logging
  • Data Preparation

    • Extract data from all source systems
    • Normalize and clean data
    • Perform duplicate detection
    • Create unified user structure
    • Validate data against cidaas schema
  • Testing

    • Test migration with small user subset (< 100 users)
    • Verify all field mappings
    • Test social provider linking
    • Test verification status migration
    • Validate password authentication
    • Test user login after migration

Migration Execution

  • Pre-Migration

    • Backup source system data
    • Notify users (if required)
    • Schedule maintenance window (if needed)
    • Prepare rollback plan
  • During Migration

    • Monitor migration progress
    • Track errors and failures
    • Validate migrated data
    • Test user authentication
  • Post-Migration

    • Verify all users migrated successfully
    • Reconcile any discrepancies
    • Test all authentication flows
    • Monitor for issues
    • Communicate completion to stakeholders

Next Steps

After completing your migration planning:

  1. Review the Migration Overview for a complete guide to migration procedures and topics
  2. Proceed with User Migration for technical implementation details
  3. Choose your Migration Procedure (one-time, sync, or bidirectional)
  4. Set up your Migration API Access
  5. Begin with a test migration using a small user subset