Friday, 29 May 2026

Mastering Identity Resolution in Sitecore CDP: Anonymous to Known Visitors

May 29, 2026 0

 


There is a moment in almost every CDP implementation where the team sits around and asks the same question: how do we know this anonymous visitor is the same person who logged in an hour later from their phone? It sounds simple. In practice, it is one of the more complex problems you will face in a real Sitecore CDP project.

Identity resolution is the process of stitching together all the signals a visitor leaves across sessions, devices, and channels — and associating those signals with a single, unified profile. Get this right, and your personalization becomes sharp and meaningful. Get it wrong, and you end up with fragmented data, duplicate profiles, and personalization logic that fires at the wrong people at the wrong time.

Sitecore CDP has a built-in identity resolution engine, and it is quite capable. But it is not magic. It depends on how you feed it data, in what order, and with what identifiers. Understanding the internals of how it works — and where it breaks — is what separates a solid implementation from a fragile one that starts showing cracks six months post-launch.

This post covers everything an architect or senior developer needs to know about identity resolution in Sitecore CDP. We will go through the mechanics, the event sequencing, the merge strategies, cross-device challenges, privacy implications, and what to do when things go wrong.

How Sitecore CDP Identifies a Visitor

When someone visits your site for the first time, CDP knows almost nothing about them. It knows a browser made a request. That is all. From that point, it starts building a picture using a few key mechanisms.

The browser identifier is the starting point — a first-party cookie set by CDP's JavaScript library on the first page load. This cookie carries a guest reference, which is CDP's internal handle for that anonymous session. Every event that flows in from that browser — page views, product clicks, form interactions — gets tagged with this guest reference and appended to the anonymous profile.

The customer identifier enters the picture when the visitor does something that reveals who they are: logging in, submitting a form with their email, completing a checkout. At that point, your application should fire an IDENTITY event to CDP's Cloud SDK API, including both the guest reference and the real customer identifier. That event is what triggers the merge.



CDP Identifier Types at a Glance:

  Browser Identifier   — Cookie set by CDP JS library on first visit

  Guest Reference      — Internal CDP handle for anonymous sessions

  Customer Identifier  — Real-world ID (email, CRM ID, loyalty number)

  Email Address        — Often used as the primary merge key

  Phone Number         — Secondary identifier in some configurations

  Custom Identifiers   — Any brand-specific ID passed via event payload



The Identity Resolution Algorithm

How Merging Actually Works

Identity resolution is the process of merging an anonymous profile with a known profile. In Sitecore CDP, this happens when the platform receives an event that includes both a guest reference (from the existing anonymous cookie) and a customer identifier (from a login or form submission).

The moment CDP receives that event, it looks up whether a profile already exists for that customer identifier. If one exists, the anonymous guest reference is merged into the known profile. If no existing known profile is found, CDP promotes the current anonymous profile to a known profile by attaching the customer identifier to it.

Here is what the merge process does, roughly speaking. CDP takes the behavioral history from the anonymous profile — sessions, events, page views, goals — and combines it with any data already stored in the known profile. The known profile's customer data (first name, last name, email, attributes from previous interactions) takes precedence in conflict situations, but the event history is additive. You do not lose events from either side.



Profile Reconciliation Logic

One question that comes up a lot is: what happens to the anonymous profile after the merge? In Sitecore CDP, the anonymous guest reference effectively becomes associated with the known profile. Future events from the same browser (using the same anonymous cookie) are automatically attributed to the known profile, even without sending the customer identifier again in every event.

This is an important architectural point. Once a browser has been merged with a known profile, CDP remembers that association. The cookie-to-profile mapping is persisted. So a return visit from the same browser — even without login — will route events to the known profile, not create a new anonymous one.

However, there are edge cases. If the visitor clears cookies, uses a private browsing session, or switches devices, CDP loses that browser-to-profile link. The visitor starts fresh as anonymous again — until they identify themselves once more. This is why cross-device tracking is handled separately, which we will cover shortly.

Handling Conflicts During Merge

Conflict handling is an area where many teams do not think carefully until they hit a problem in production. The most common conflict scenario is when two anonymous profiles need to merge because the same person used two different browsers before logging in.

For example: a visitor browses on Chrome at home, then the next day browses on Firefox at work, and logs in on Firefox. CDP will merge the Firefox anonymous profile with the known profile. But the Chrome anonymous profile is still floating separately, because CDP had no way of knowing they were the same person before login.

Eventually, if the person logs in on Chrome too, that anonymous profile will also get merged. CDP handles this gracefully — it adds the Chrome behavioral history to the existing known profile. But there is a window of time where some behavioral data sits in a separate anonymous profile until the second merge happens.

Event Sequencing and Data Flow

The Full Journey from Anonymous to Known

Understanding the event sequence is critical for implementation. A lot of issues in CDP projects trace back to events being fired in the wrong order, or missing events that should have triggered the identity merge. Here is the typical flow:

 STEP 1 │ First Visit (Anonymous)                                              

        │ CDP JS library loads → sc_anonymous_id cookie set                   

        │ VIEW event fires → anonymous profile created in CDP                  

        │ Guest reference assigned                                                                                                              

 STEP 2 │ Continued Browsing                                                   

        │ More VIEW events fire → behavioral data accumulates                  

        │ All events tagged with same guest reference                                                                                             

 STEP 3 │ Login / Form Submission                                              

        │ User logs in → your app fires IDENTITY event to CDP Cloud SDK API      

        │ IDENTITY event payload includes: guest reference + customer ID                                                                      

 STEP 4 │ Identity Resolution                                                   

        │ CDP checks for existing profile with that customer ID               

        │ If found → merge anonymous history into known profile               

        │ If not found → promote anonymous profile to known                                                                                     

 STEP 5 │ Post-Merge                                                           

        │ All future events from same browser → routed to known profile       

        │ Personalization rules activate based on enriched profile            

        │ Audience segments recalculated in near real time    



Merge Strategies in Real Projects

Sitecore CDP uses deterministic identity matching. Merges happen only when a concrete, known identifier is provided — not based on inferred signals like IP address or browser fingerprint. In most enterprise implementations, this is the right approach. The key is capturing that identifier consistently across every meaningful touchpoint: login, checkout, newsletter signup, account update.

In practice, teams use a few common patterns:
Email-first strategy: Email address is the primary merge key. Everything else (CRM ID, loyalty ID) is treated as supplementary. This works well when email capture is consistent across channels but can cause issues if users have multiple email addresses.
CRM ID strategy: A stable, platform-generated identifier from your CRM or commerce system is the primary key. This is more durable than email (users change emails more often than you might think) and generally recommended for mature implementations.
Multi-identifier strategy: You send multiple identifiers in the IDENTITY event — email , phone or CRM ID, for example — and configure CDP to use a specific one as the primary. This is the most robust approach but requires clear data governance to avoid mismatches.




Duplicate profiles are a reality in any CDP project. They accumulate when the same person enters through different channels before identifying themselves, or uses different email addresses on different touchpoints. Cleanup usually happens via CDP's Batch API — you run a batch of IDENTITY events that link duplicate guest references to the canonical customer identifier, effectively chaining the merges. Most teams need to do at least one cleanup pass post-launch, especially after adding a new integrated channel.

Cross-Device Tracking and Privacy Constraints

Cross-Device Challenges

The only reliable way to link sessions across devices in Sitecore CDP is through authenticated identification. When a user logs in on their phone, the IDENTITY event associates that mobile browser's guest reference with the known profile. When they log in on their laptop, the same thing happens. Over time, CDP builds a unified view.
But the two devices are not connected in real time. If the laptop session never included a login, that behavioral history sits in a separate anonymous profile until the user authenticates on that device too. Cross-device unification is an ongoing process, not a one-time event.
Private browsing is a category of its own. When a visitor uses incognito mode, cookies do not persist across sessions. Every new private window is a fresh anonymous visitor from CDP's perspective. There is no clean technical solution within CDP's native capabilities for this — and trying to engineer around it creates both complexity and privacy risk. Accept it as a limitation and focus your energy on the authenticated journey.

Cookie Consent and GDPR Impact

Consent management has direct functional implications for your tracking layer, not just your legal documentation. CDP relies on its first-party cookie to maintain the anonymous profile across sessions. If a visitor declines tracking consent, that cookie should not be set — which means CDP cannot build a persistent anonymous profile for that visitor.
You need to conditionally initialize CDP's JavaScript library based on the user's consent state. If your CMP signals that analytics or targeting cookies are accepted, CDP initializes with full tracking. If consent is declined, CDP either does not load or operates in a cookieless mode where session continuity is limited. This integration needs to be built and tested from the start — retrofitting consent handling late in a project is painful.

// example — conditional CDP initialization
if (consentManager.hasConsent('analytics')) {
  initializeSitecoreCDP({ guestContextId: getGuestRef() });
} else {
  // CDP loads without persistent cookie tracking
  initializeSitecoreCDP({ cookieless: true });
}

When tracking consent is denied, you can still deliver contextual personalization based on non-personal signals: the current page, URL parameters, campaign attribution, device type, and country-level geography. It is less powerful than profile-driven personalization, but it is compliant and still adds value.


When Identity Resolution Fails

Production always surfaces edge cases that testing does not. Here are the failure scenarios architects encounter most often, and how to handle them.
  • Safari's Intelligent Tracking Prevention (ITP) aggressively restricts third-party cookies and increasingly limits some first-party cookie lifetimes. Even if you are using first-party cookies, ITP may cap their expiry at 7 days in certain configurations. This means a user who visited two weeks ago will appear as a new anonymous visitor, even if they previously identified themselves. The mitigation is to set your CDP cookie as an HTTP-only, server-side cookie rather than a JavaScript-set cookie
  • Ad blockers frequently block requests to CDP's Cloud API endpoint. Client-side event sending is vulnerable to this. For high-value interactions — purchase completions, form submissions — implement server-side event sending via CDP's Batch API as a fallback. Server-to-server calls bypass client-side blocking entirely.
  • Missing or late IDENTITY events are probably the most common implementation bug. This usually happens in SPAs where the login interaction does not trigger the correct event, or where the IDENTITY event fires but with an incomplete payload. Thorough end-to-end testing of the login flow — checking CDP's event stream directly — is the only reliable way to catch this.
  • When identity resolution cannot complete, experiences should degrade gracefully. Every Sitecore Personalize experience should have a sensible default variant that applies when the visitor is unknown or the profile is incomplete. Experiences designed only for fully-known visitors will misfire on a meaningful percentage of real-world sessions.
  • Troubleshooting Approach When identity resolution is not working as expected, the debugging process typically follows this order: First, verify in CDP's event stream that events are being received with the correct guest reference and customer identifier. Second, check the order of events — is the IDENTITY event firing before other post-login events? Third, look at the profile in CDP's Guest Profile Viewer and check whether the known customer identifier is attached. Fourth, inspect the browser's cookie storage to confirm the anonymous cookie is being set and persisted correctly.

Architecture Best Practices

Data Governance Starts at the Identifier Level: 

Before writing a single line of CDP integration code, your team needs to answer one question: what is your canonical customer identifier? This sounds obvious, but in large enterprises with multiple systems — a CRM, a loyalty platform, an e-commerce engine, a mobile app backend — there are often competing identifiers. Your CDP implementation will only be as good as the consistency of the identifiers flowing into it. Resolve this at the architecture stage — not during development.

Event Naming Standards

Define your event taxonomy upfront and treat it as a versioned artifact. CDP is an event-driven platform. The quality of your behavioral data depends entirely on the consistency and clarity of your event taxonomy. Use a standardized naming convention across all channels — web, mobile app, email, contact center. If your web team calls the login event IDENTITY but your mobile team calls it USER_LOGIN with different payload structures, you end up with data that is hard to reconcile.

// ---------------------- CDP EVENT ----------------------
        try {
          await event({
            type: 'CONTACT_DETAILS_FORM_SUBMITTED',
            channel: 'WEB',
            currency: 'USD',
            page: route?.name,
            pageVariantId,
            language,
            payload: {
              Name: formData.firstName + ' ' + (formData.middleName || '') + ' ' + formData.surname,
              Email: formData.email,
              Home: formData.home ? formData.home : '',
              Work: formData.work ? formData.work : '',
            },
          });
        } catch (err) {
          console.error('Error sending event to CDP:', err);
        }

Identifier Strategy

Send multiple identifiers whenever possible — email AND CRM ID, for example — but nominate one as the primary merge key. Configure CDP to use that primary key for identity resolution. The secondary identifiers become attributes on the profile, useful for cross-system lookups but not the basis for merging.

try {
      const { identity } = await import("@sitecore-cloudsdk/events/browser");

      const eventData = {
        channel:  "WEB",
        language: "EN",
        currency: "USD",
        // ← PRIMARY MERGE KEY — provider must match CDP identity rule name
        identifiers: [{ provider: "CRM_ID", id: crmId.trim() }],
        // ← SUPPLEMENTARY PII
        ...(email     && { email:     email.trim()     }),
        ...(firstName && { firstName: firstName.trim() }),
        ...(lastName  && { lastName:  lastName.trim()  }),
        ...(phone     && { phone:     phone.trim()     })
      };

      const extensionData = {
        source: "react-app",
        identityMethod: "CRM_ID",
      };

      log(`Calling identity() — payload: ${JSON.stringify(eventData)}`, "sdk");

      await identity(eventData, extensionData);

      log("IDENTITY event accepted — CDP running linking algorithm", "success");
      log("Guest type: VISITOR → CUSTOMER", "success");

      setProfileData({
        crmId: crmId.trim(),
        ...(email     && { email }),
        ...(firstName && { firstName }),
        ...(lastName  && { lastName }),
        ...(phone     && { phone }),
        guestType:  "customer",
        resolvedAt: new Date().toISOString(),
        sdk:        "@sitecore-cloudsdk/events/browser",
      });
      setStatus("success");
      setActiveTab("profile");

    } catch (err) {
      log(`IDENTITY event failed: ${err.message}`, "error");
      setStatus("error");
    }

Profile Enrichment Considerations

Identity resolution is the foundation, but it is not the end goal. Once you have a unified profile, the next step is enriching it — pulling in attributes from CRM, purchase history from commerce, preference data from loyalty programs. In Sitecore CDP, this happens through the Batch API and stream API ingestion.

API Considerations

CDP has two main APIs for server-side integration: the Cloud SDK API (real-time, synchronous) and the Batch API (asynchronous, bulk). For identity resolution, the Cloud SDK API is the right tool — it processes events in real time and triggers immediate profile merges. The Batch API is better suited for bulk historical data imports and profile attribute updates. Always implement retry logic for Cloud SDK API calls. 

Cloud SDK initialization code-

import { useEffect, JSX } from 'react';
import { SitecorePageProps } from 'lib/page-props';
import { CloudSDK } from '@sitecore-cloudsdk/core/browser';
import '@sitecore-cloudsdk/events/browser';
import '@sitecore-cloudsdk/personalize/browser';
import config from 'temp/config';
import { LayoutServicePageState, RenderingType } from '@sitecore-jss/sitecore-jss-nextjs';

/**
 * The Bootstrap component is the entry point for performing any initialization logic
 * that needs to happen early in the application's lifecycle.
 */
const Bootstrap = (props: SitecorePageProps): JSX.Element | null => {
  // Browser ClientSDK init allows for page view events to be tracked
  useEffect(() => {
    const pageState = props.layoutData?.sitecore?.context.pageState;
    const renderingType = props.layoutData?.sitecore?.context.renderingType;
    console.log('environment', process.env.NODE_ENV);
   
    // Skip initialization in edit and preview modes only
    if (
      pageState !== LayoutServicePageState.Normal ||
      renderingType === RenderingType.Component
    ) {
      console.debug('Browser Events SDK is not initialized in edit and preview modes');
      return;
    }

    // Initialize Cloud SDK in both development and production environments
    try {
      console.debug('Initializing Browser Events SDK');
      CloudSDK({
        sitecoreEdgeUrl: config.sitecoreEdgeUrl,
        sitecoreEdgeContextId: process.env.SITECORE_EDGE_CONTEXT_ID || '7k2RMDcj04zEcytgGeS5Zq',
        siteName: props.site?.name || config.sitecoreSiteName,
        enableBrowserCookie: true,
        // Replace with the top level cookie domain of the website that is being integrated e.g ".example.com" and not "www.example.com"
        cookieDomain: process.env.NEXT_PUBLIC_COOKIE_DOMAIN,
      })
        .addEvents()
        .addPersonalize({ enablePersonalizeCookie: true, webPersonalization: true }) // Initialize the personalize package
        .initialize();
      console.debug('Browser Events SDK initialized successfully');
    } catch (error) {
      console.warn('Cloud SDK initialization failed or already initialized:', error);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [props.site?.name]);

  return null;
};

export default Bootstrap;

Debugging Approaches

For Debugging, maintain a dedicated test profile or set of test profiles in your CDP tenant for integration testing. Use a known, synthetic customer identifier (like test-user-001@yourcompany.com) that you can trace through the entire event sequence. This makes it much easier to verify that identity resolution is working correctly without polluting your production profile data.
Also consider implementing a lightweight event logging middleware that captures every payload sent to CDP before it goes out. Storing these logs (even temporarily) gives you a timeline of exactly what was sent, in what order, which is invaluable for debugging timing and sequencing issues.

What Teams Should Avoid

Avoid sending the IDENTITY event only at one point in the journey (like purchase confirmation) when you could be sending it at login, form submission, and other earlier touchpoints. The earlier you capture identity, the more pre-login behavioral data gets stitched into the known profile.
Do not assume that CDP will handle everything automatically. It is a sophisticated platform, but it is not self-configuring. The quality of your identity resolution is a direct function of the quality of the events you send to it — correct identifiers, correct timing, correct sequencing.
Avoid building personalization experiences that are brittle when identity resolution has not yet completed. Always design for the case where the profile is incomplete, anonymous, or partially merged. Experiences that assume a fully known profile will misfire in a significant percentage of real-world sessions.
Finally, do not skip the post-launch monitoring phase. Identity resolution issues often do not surface in testing because test scenarios are too clean and controlled. In production, you encounter edge cases — users with corrupted cookies, users who logged in through SSO without the IDENTITY event firing correctly, users from consent-restricted geographies. Set up monitoring for profile fragmentation and duplicate detection from day one.

Conclusion

Identity resolution is not a feature you configure once and forget. It is an ongoing architectural concern that touches your data governance, event strategy, consent management, and front-end integration all at once.
Sitecore CDP gives you a capable foundation. The platform's ability to merge anonymous behavioral history with known profiles in near real time is genuinely useful when the data feeding it is clean and correctly sequenced. The implementations that struggle are almost always struggling because of data quality or event sequencing problems — not platform limitations.
The teams that get this right are the ones that treat identifier strategy and event taxonomy as first-class design decisions, not implementation details. If you invest that thinking upfront, the rest of the CDP implementation tends to follow reasonably well.

References 




Tuesday, 21 April 2026

Sitecore AI + Netlify: A Real Issue with Geo Personalization

April 21, 2026 0

 


Problem Statement

We recently faced an issue while working on a Sitecore AI implementation hosted on Netlify.

Our setup was simple. We had deployed the frontend application on Netlify and enabled Sitecore AI embedded personalization. As part of the personalization strategy, we created different page variants based on the user’s country. The expectation was users from different countries should see personalized content to their location.

However, things did not work as expected.

No matter where the user was accessing the site from, the same version of the page was being shown. The personalization rules were not getting applied correctly. At first, it looked like a configuration issue in Sitecore AI, but after checking the rules and setup multiple times, everything seemed fine.


Root Cause Analysis

After digging deeper, we found the real problem.

Sitecore AI was not receiving the actual user’s country information. Instead, it was always picking up the country of the Netlify hosting server. In our case, the site was hosted in the UAE, so every request appeared as if it was coming from the UAE.

Because of this, even if a user accessed the site from Saudi Arabia (or any other country), Sitecore AI still treated them as a UAE user. As a result, the country-based personalization never triggered correctly.

In short, the personalization logic was working, but the input data (user location) was wrong. And because of that, the entire experience broke.


Solution

After understanding the problem, we focused on how Netlify was handling request headers.

We noticed that Netlify always sets the x-forwarded-for header using its edge network IP. Because of this, our logic was always picking that value and skipping any further checks. This caused a bigger issue — Sitecore was reading different edge node IPs on every request. As a result, the detected location kept changing, and users were getting different personalized variants on every page refresh.

To fix this, we changed our approach.

Instead of relying on x-forwarded-for, we decided to always use x-nf-client-connection-ip when it is available. This header gives the actual client IP. This small change ensured that the correct user location is passed every time.

Along with this, we added a middleware in our Next.js application.

We extended the existing PersonalizeMiddleware provided by Sitecore and It overrides one method — getExperienceParams — which is responsible for building the data object sent to Sitecore to decide which personalized variant to show.

class GeoPersonalizeMiddleware extends PersonalizeMiddleware {
  protected getExperienceParams(req: NextRequest) {
    const params = super.getExperienceParams(req);
    const country = req.headers.get('x-country');
    if (country) {
      return { ...params, geo: { country } };
    }
    return params;
  }
}

super.getExperienceParams(req) — first calls the original Sitecore method to get the default params (referrer, UTM, etc.)

req.headers.get('x-country') — reads a header called x-country which Netlify automatically injects on every request with the visitor's detected country code (e.g. "AE", "SA")

If the x-country header exists, it adds a geo: { country } field into the params before sending to Sitecore

This made a big difference. Now Sitecore gets the correct country information on the very first request itself. Because of this, the geo-based personalization rules start working immediately, even before any cookies or user profile data are created.

We also handled one more important case.

Netlify sometimes sends requests from its own prerender system. These are not real users, but background requests used for caching and performance. Netlify marks these requests using a header called netlify-agent-category.

function isNetlifyPrerender(req: NextRequest): boolean {
  const agentCategory = req.headers.get('netlify-agent-category') || '';
  return agentCategory.includes('tooling') || agentCategory.includes('prerender');
}

We added a simple check to detect such requests. If the request is coming from Netlify’s prerender system, we prevent caching for that response. This avoids serving incorrect or cached personalized content to real users.

if (isNetlifyPrerender(req)) {
    response.headers.set('x-middleware-cache', 'no-cache');
    response.headers.set('netlify-cdn-cache-control', 'no-store');
  }

x-middleware-cache: no-cache — tells Next.js middleware layer not to cache this response

In short, the fix had three key parts:

  1. Use the correct client IP instead of the edge IP
  2. Pass the user’s country explicitly to SitecoreAI
  3. Avoid caching issues caused by prerender requests

After applying these changes, the personalization started working correctly for users across different countries.


Tuesday, 31 March 2026

How to Set Up Single Sign-On (SSO) in SitecoreAI (XM Cloud)

March 31, 2026 0

 



In this blog, I'll explain how you can set up Single Sign-On (SSO) in Sitecore AI (XM Cloud). SSO simplifies login management, allowing teams to access the Sitecore Cloud Portal and its applications using their existing identity providers. Sitecore Cloud Portal supports identity providers that use either OpenID Connect (OIDC) or Security Assertion Markup Language (SAML) protocol.

We had a requirement to implement SSO using Microsoft Entra ID. Here I'll explain the step-by-step process to implement that.

Prerequisites

Before starting the configuration, please ensure you have the following access:

  • Azure AD Permissions: The ability to register Sitecore Cloud Portal as an application in Azure AD.
  • Sitecore Cloud Portal Administrative Access: You must hold an Organization Admin or Organization Owner role in Sitecore Cloud Portal.
  • Domain Configuration Access: Permission to create a TXT record with your domain host provider.

Set Up Azure Entra ID

  1. Log in to the Azure Portal.



  2. Go to Microsoft Entra ID → Manage → App registrations.



  3. Click on the New Registration button.
  4. Provide the necessary details:
    • Name – A unique name for your application.
    • Supported account types – Choose based on your requirement:
      • Single tenant only – Use this if your application is meant for users within your organization only.
      • Multi Entra ID tenant – Choose this to allow users from other organizations (e.g., partners) to log in using their credentials.
      • Any Entra ID Tenant + Personal Microsoft accounts – Select this to support both organizational users and personal Microsoft accounts.
      • Personal accounts only – Choose this if the application is intended solely for individual users with personal Microsoft accounts.
    • Redirect URI – Under Redirect URI, select Web and enter https://auth.sitecorecloud.io/login/callback in the URL text box. The redirect URI is the endpoint to which the user is sent by the authorization server after completing its interaction, and to which an access token or authorization code is sent upon successful authorization.




  5. Copy the Application (Client) ID from the newly created app page — you will need it when creating the SSO connection in Sitecore XM Cloud.



  6. Go to the Authentication tab → Settings and check the ID tokens checkbox.



Configure SSO in Sitecore Cloud Portal

  1. Log in to Sitecore Cloud Portal.
  2. Navigate to the SSO Settings:
    • Click on Admin from the top menu.
    • Click Single Sign-On (SSO) from the left navigation, then click Add SSO connection.
    • In the drop-down menu, select OpenID Connect.



  3. In the Add SSO connection dialog, fill in the required details:
    • Email Domain: Enter the email domain(s) associated with this SSO connection (e.g., lng-consultancy.com). You can add up to 50 email domains for a single connection. Only team members with email addresses matching the domains specified here will be able to log in via SSO. Make sure the domains you add are valid and owned by your organization.
    • Connection Type: Choose either Front Channel or Back Channel based on your identity provider's documentation.
    • Discovery URL: Enter the discovery document URL for your Azure Entra ID tenant. Use the Tenant ID copied during the Azure setup. For example: https://login.microsoftonline.com/{yourTenantID}/v2.0/.well-known/openid-configuration
    • Scopes: Include openid, profile, and email. Optionally, add scopes for claims like name, given_name, family_name, and nickname.
    • Client ID: Use the Client ID copied during the Azure Entra ID setup.
    • Client Secret: If using Back Channel (Authorization Code flow), enter the client secret generated in Azure Entra ID.
    • Callback URL: This is the redirect URI provided during app registration (https://auth.sitecorecloud.io/login/callback).



  4. Verifying Your Domain : After saving, a TXT record will be generated. Copy the TXT record and add it to your domain's DNS records. Without domain verification, users will not be able to log in using SSO.
    Example: If your organization owns lng-consultancy.com and lngconsultancy.co.in, you can add both domains in the Email Domain field to allow employees with either domain to log in using their Azure AD credentials.



Enabling the SSO Connection

After verifying the domain and optionally testing your SSO connection, you can enable it.

  1. Navigate to the Sitecore Cloud Portal SSO page.
  2. Locate the SSO connection you want to enable and click Enable.
  3. Once enabled, team members with email addresses matching the SSO connection domain can log in using their identity provider.
I hope this helps you set up SSO in the Sitecore Cloud Portal (XM Cloud). Feel free to drop a comment if you have any questions!

References

Friday, 27 February 2026

Sitecore CDP: From Events to Decisions – An Architect’s Practical Guide

February 27, 2026 0

 


What I’ve Learned Designing CDP the Right Way

When teams implement Sitecore CDP, the focus usually goes to personalization use cases, dashboards, and decision models. But in real projects, I’ve seen something different. If your event model and identity strategy are weak, nothing else works properly. Personalization behaves inconsistently. Reports don’t add up. Profiles get duplicated. Consent becomes messy.

So in this post, I want to walk through what actually matters when designing Sitecore CDP — based on what I’ve seen in real implementations.


1. Event Taxonomy Design for Sitecore CDP

Your event taxonomy is your foundation.

If you don’t define it early and clearly, every team will send data differently — and you’ll spend months fixing it later.

Start With Business Intent, Not Pages

A common mistake is modeling events around pages:

  • home_page_click
  • product_page_click
  • checkout_page_click

This ties your data to the UI.

Instead, model around user intent:

  • product_viewed
  • product_added_to_cart
  • checkout_started
  • checkout_completed

Now your model works across:

  • Web
  • Mobile apps
  • Email journeys
  • Future channels

That’s how you future-proof it.


Naming Conventions

Keep it simple and consistent.

I recommend:

lowercase + underscores + business action

Examples:

  • product_viewed
  • cart_updated
  • form_submitted
  • account_logged_in

Avoid:

  • Environment prefixes (dev_, prod_)
  • Version numbers in event names
  • Brand-specific naming unless absolutely required

Let schema versioning handle evolution — not the event name.


Versioning Strategy

Events will evolve. That’s normal.

The mistake is changing them without a plan.

What works well:

  • Add a schema_version field inside the payload
  • Only add new optional fields
  • Avoid deleting existing properties suddenly

If a field must be removed, deprecate it first.
Remember: decision models might still be using it.

Future-Proofing Your Event Model

Before finalizing your taxonomy, ask:

  • Will this work across brands?
  • Will this work in mobile apps?
  • Will this work in offline or call center scenarios?
  • Will this still make sense 3 years from now?

For example:

Instead of web_banner_clicked use promotion_clicked

Now it works everywhere.

That small decision saves major rework later.

2. Designing Identity Resolution in Complex Ecosystems

Identity is where most CDP projects struggle.

In reality, one user can have:

  • Anonymous browser ID
  • CRM ID
  • Email
  • Mobile app ID
  • Loyalty ID

If you don’t define how these connect, you’ll end up with duplicate or broken profiles.

Anonymous → Known Transitions

This is a critical moment.

A user browses anonymously. Then they log in or submit their email.

What should happen?

You must:

  • Link anonymous history to the known profile
  • Merge safely
  • Avoid losing past behavioral data

Best practice:

  • Send both identifiers during the transition
  • Merge using strong identifiers (email, customer ID)
  • Never merge using weak signals like name only

If this is not designed carefully, you’ll see:

  • Fragmented journeys
  • Reset personalization
  • Inconsistent reporting

Multi-Device and Multi-Brand Scenarios

In enterprise setups, things get more complex.

A customer might:

  • Browse Brand A on desktop
  • Use Brand B mobile app
  • Purchase through call center

Now you must decide:

  • Are profiles shared across brands?
  • Is identity enterprise-wide or brand-level?
  • What about regional data boundaries?

Define clearly:

Identity Scope

  • Brand-level
  • Region-level
  • Enterprise-level

Identifier Priority

For example:

  • Customer ID
  • Email
  • Loyalty ID
  • Device ID

Document this. Socialize it. Govern it.

Identity chaos usually comes from unclear ownership — not technical limitations.

3. Data Modeling Mistakes I See Often

Over-Collection

Some teams send everything:

  • Every click
  • Every scroll
  • Every hover

More data does not mean better personalization.

It usually means:

  • Higher storage cost
  • Slower processing
  • Noisy segments
  • Harder debugging

Before sending any event, ask:

Will this drive a business decision?

If not, don’t send it.

Poor Event Normalization

Across brands, I’ve seen this:

Brand A sends:
productId

Brand B sends:
product_id

Brand C sends:
sku (Stock Keeping Unit)

Now try building a unified segment.

Standardize:

  • Attribute names
  • Data types
  • Value formats

Create a shared event contract and enforce it.

Identity Chaos

This is the hardest to fix later.

Symptoms:

  • Duplicate profiles
  • Conflicting attributes
  • Random merges
  • Personalization behaving unpredictably

Root cause:
No documented identity strategy.

Identity resolution is not just configuration.
It’s enterprise data architecture.

4. GDPR and Consent Architecture with CDP

Consent must be part of your data model from day one.

Not something added later.

What Data to Send

Send:

  • Behavioral interaction data
  • Pseudonymous identifiers
  • Business events
  • Consent status

Be cautious with:

  • Sensitive personal data
  • Financial information
  • Health data

Minimize data collection wherever possible.

What Data to Suppress

Do not send:

  • Events before required consent (based on region)
  • Users who have opted out
  • Internal test traffic

Consent logic should sit before data flows into CDP.

Modeling Consent Events

Treat consent as its own event.

For example:

consent_updated

  • consent_type
  • consent_status
  • timestamp
  • source

This gives you:

  • Full audit history
  • Clean compliance reporting
  • Better suppression logic
  • Dynamic personalization based on consent state

And most importantly — transparency.

Practical Architecture Diagram Outline



Real Enterprise Case Study Example



Final Thoughts

Sitecore CDP is not just about connecting data sources. It’s about designing a clean, scalable event and identity foundation.

If you rush taxonomy and identity design, you’ll spend years fixing personalization issues.

If you invest time upfront, you unlock:

  • Reliable personalization
  • Accurate reporting
  • Predictable decision models
  • Cleaner compliance

In my experience, CDP success has very little to do with features — and everything to do with architecture discipline.


References