Category: Optimizely

Optimizely DXP Alert: Are You Affected by the October 2026 Node.js Security Vulnerabilities?

On October 27, 2026, Optimizely published a security advisory regarding recently disclosed Node.js vulnerabilities affecting Node.js 22.x, 24.x, and 26.x release lines. Optimizely confirmed there is currently no evidence of exploitation across Optimizely products or customer environments. 

For most SaaS customers, remediation is handled automatically by Optimizely. However, certain CMS, Commerce Connect, and Frontend Hosting customers may need to take action to ensure they receive the patched Node.js runtime.

 

 

Executive Summary

The first question many Optimizely CMS customers asked was:

“Does this affect my Optimizely CMS PaaS solution?”

According to guidance received from Optimizely Support, customers using CMS PaaS generally only need to take action if their solution proxies Node.js processes through their .NET application.

“Customer only needs to act if they proxy Node.js processes through their .NET application. They must deploy a code package with a new name or version number. The package can contain the same code that’s in production. This forces a container rebuild that picks up the patched Node.js.”

This clarification aligns with Optimizely’s published security advisory, which identifies customers proxying Node.js workloads and customers using Frontend Hosting as requiring action.

 

How to Determine Whether You Are Affected

 

Step 1: Check if Your Solution Uses Node.js

For many Optimizely CMS DXP solutions, the Node.js version is defined in:

src/[Client Repository]/dxpPlatformSettings.json
 

The nodeVersion value indicates which major Node.js runtime version will be used when DXP builds your container image.

 

Step 2: Identify the Version

Node.js Version Status
18.x End of Life – Upgrade Required
20.x End of Life – Upgrade Required
22.x Supported – Requires rebuild to receive patched runtime
24.x Supported – Requires rebuild to receive patched runtime
26.x Supported – Requires rebuild to receive patched runtime
 
Optimizely specifically notes that Node.js 18 and 20 no longer receive security updates and customers should upgrade to a supported major version before redeploying.

 

Step 3: Verify Whether Your Deployment Uses Node.js

You are most likely affected if your solution:

  • Uses Optimizely Frontend Hosting
  • Runs Next.js, React, Vue, Angular, or other Node-based applications
  • Proxies Node.js processes from an ASP.NET application
  • Uses Node.js during build or runtime execution on DXP

Optimizely identified these scenarios as requiring customer action.

 

The Fix for DXP Customers

The good news is that the fix typically does not require code changes.

Optimizely’s DXP build pipeline automatically retrieves the latest patched Node.js version for your configured major version whenever a new container image is built.

To receive the patched runtime:

  1. Create a new deployment package.
  2. Change the package name or version number.
  3. Deploy the package through the standard DXP deployment process.
  4. Allow DXP to rebuild the container image.
The deployment package may contain exactly the same application code currently running in production. The objective is simply to force a fresh container build so that the patched Node.js runtime is incorporated.
 

What About .NET Security Updates?

During discussions with Optimizely Support, customers were also directed to Microsoft’s out-of-band October 2026 .NET security updates.

If your solution includes .NET workloads, review the Microsoft guidance and evaluate whether your environment requires additional patching alongside the Node.js remediation effort.

Optimizely Support further advised:

“We do not have a specific recommendation regarding the timing of the upgrade. However, since this issue involves a security vulnerability, we recommend upgrading as soon as feasible. Ultimately, your organization will need to assess and accept the associated risks based on your own security requirements and policies.”

This is a sensible approach. While no active exploitation has been reported by Optimizely, security-related rebuilds and upgrades are typically best scheduled as part of the next available maintenance window while following your organization’s risk management process.

Hope this helps.

Happy Optimizing!

0

Optimizely Forms Returning 301 on Submission? The Real Cause Was an AntiForgery Token Conflict

Sometimes a form submission issue looks like a routing problem, a redirect issue, or even a load-balancer misconfiguration. In our case, the browser showed a 301 response during Optimizely Forms submission, but the actual root cause was much deeper.
 
Recently, while working on an Optimizely CMS 12 implementation, we encountered a strange issue where Optimizely Forms stopped submitting successfully after introducing AntiForgery token support for custom forms. At first glance, it appeared to be a standard redirect problem. However, after investigating the application logs and working with Optimizely Support, the underlying issue turned out to be an AntiForgery token validation conflict.
 
 

The Problem

As part of a security enhancement initiative, we introduced AntiForgery token support for custom forms within the solution.

The implementation included: AntiForgeryController.cs to generate and manage AntiForgery tokens for custom APIs and forms.


[Route("api/antiforgery")]

public class AntiForgeryController : ControllerBase

{

private readonly IAntiforgery _antiforgery;
private readonly string _antiForgeryToken;


public AntiForgeryController(IAntiforgery antiforgery, IConfiguration configuration)

{

_antiforgery = antiforgery;
_antiForgeryToken = configuration["AntiForgeryToken"];

}


[HttpGet("token")]

public IActionResult GetToken()

{

var tokens = _antiforgery.GetAndStoreTokens(HttpContext);


Response.Cookies.Append(

_antiForgeryToken,

tokens.RequestToken!,

new CookieOptions

{

HttpOnly = false,

Secure = true,

SameSite = SameSiteMode.Strict

});


return Ok(new

{

token = tokens.RequestToken

});

}
}

Shortly after deployment, users reported that Optimizely Forms were no longer submitting successfully.

The behaviour was unusual:

  • Form submissions failed intermittently.
  • Browser Developer Tools showed a 301 response during form submission.
  • Optimizely Forms that previously worked without issues could no longer be submitted.
  • Removing the AntiForgery implementation immediately restored functionality.

This clearly indicated that the issue was related to the newly introduced security implementation.

 

Initial Investigation

Our first assumption was that the problem was related to:

  • URL rewriting
  • Redirect rules
  • Front Door configuration
  • Reverse proxy settings
  • Form endpoint routing

However, none of these areas revealed any issues.

The turning point came when reviewing the application exception logs.

The logs contained the following error:

One or more errors occurred.
 
The required antiforgery request token
was not provided in either form field
“__RequestVerificationToken”
 
or header value
 
“AntiForgeryToken”
 

Further examination showed the exception being raised from Optimizely Forms security validation.
 
System.AggregateException
 
EPiServer.Forms.Internal.Security
.DefaultAntiForgeryValidator.Validate()
 
Microsoft.AspNetCore.Antiforgery
.AntiforgeryValidationException

At this point, it became clear that the 301 response was merely a symptom. The actual failure was occurring during AntiForgery validation.

 

Understanding the Root Cause

Optimizely Forms already includes built-in AntiForgery protection.

When we introduced a custom AntiForgery implementation, we unintentionally created a conflict between:

Custom AntiForgery Token
and
 
Optimizely Forms AntiForgery Validation
 

The Optimizely Forms submission pipeline expected to receive a valid request verification token using its own validation mechanism.

Instead, the request validation process encountered a mismatch and failed with:

AntiforgeryValidationException
 
because the required token was not available in one of the expected locations:
 
__RequestVerificationToken
 
or
 
AntiForgeryToken header
 
As a result, the form submission was rejected before reaching the normal processing pipeline.

The Resolution

The fix was surprisingly simple.

We aligned the AntiForgery configuration so that Optimizely Forms could correctly locate and validate the expected request token.

Configuration update: appsettings.json

{
“AntiForgeryToken”: “RequestVerificationToken”
}

After correcting the AntiForgery configuration and validating the token flow:

  • Optimizely Forms submissions started working again.
  • No further 301 submission issues occurred.
  • Standard Optimizely Forms security validation executed successfully.
  • Custom forms continued to function as expected.

Happy Optimizing!

 
0

Optimizely CMS 12 on .NET 10: Fixing a Siteimprove TypeMismatchException

Recently, while upgrading an Optimizely CMS 12 solution from .NET 8 to .NET 10, we encountered a frustrating exception that initially looked like a CMS compatibility issue. After several rounds of troubleshooting with Optimizely Support, dependency analysis, debugging, and elimination testing, the root cause was eventually traced back to the Siteimprove Optimizely plugin.

This blog shares the journey, findings, root cause, and final resolution to help others who may encounter the same problem during their CMS 12 modernization efforts.

The Upgrade Journey

As part of our modernization initiative, we upgraded:

  • Optimizely CMS from 12.34.3 to 12.34.5
  • Application runtime from .NET 8 to .NET 10
  • Supporting CMS packages and dependencies
  • Development environment to Visual Studio 2026

Most of the upgrade activities went smoothly. We successfully resolved issues related to:

  • TinyMCE initialization
  • Language Manager gadget visibility
  • Dependency scanning problems
  • .NET 10 compatibility adjustments

However, another issue surfaced immediately after the upgrade.

The Exception

Whenever editors attempted to open any block in the CMS editor, Optimizely threw the following exception:

EPiServer.Core.TypeMismatchException:
 
Content with id ‘1652_3366’ is of type
‘Castle.Proxies.LinkBlockModelProxy’
 
which does not inherit required type
 
‘EPiServer.Core.PageData’
 
The exception originated from:

EPiServer.Core.Internal.DefaultContentLoader.Get<T>()
 

and appeared before any custom block code was executed.

At first glance, this looked like:

  • Database corruption
  • Content type mismatch
  • Invalid content references
  • CMS core regression

All reasonable assumptions.

Unfortunately, all of them turned out to be wrong.

Initial Investigation

The first suspicion was corrupt CMS data.

Optimizely Support referenced earlier cases where similar exceptions were caused by invalid fkContentTypeID values in the database. They recommended comparing content records between healthy and failing environments.

To validate this theory, we:

  • Restored multiple database backups
  • Created fresh blocks
  • Tested newly created content
  • Verified content type mappings

Surprisingly, the issue persisted even on fresh databases.

This effectively ruled out data corruption as the primary cause.

 

The Breakthrough

During the investigation, Optimizely’s development team performed deeper tracing and discovered something interesting.

Their analysis revealed:

“It’s a bug in the package SiteImprove.Optimizely.Plugin which subscribes to contextChange and gets PageData for all content without checking the type.”

This was the clue we needed.

The Siteimprove plugin was making an assumption that all CMS content could be safely treated as:

PageData
But when editors opened blocks, the content being processed was actually:
 
LinkBlockModel or another block type.

Under .NET 10 and the newer CMS version, this incorrect type handling became visible and resulted in:

TypeMismatchException instead of silently passing through.
 

The Root Cause

The Siteimprove Optimizely integration was subscribing to content context change events.

During those events, it attempted to retrieve content using logic that effectively expected: PageData for every content item.

The plugin did not properly verify whether the content was:

  • PageData
  • BlockData
  • MediaData
  • Other CMS content types

before casting or loading it.

Confirming the Cause

One of the most valuable debugging techniques during upgrades is dependency isolation.

We tested by removing the Siteimprove package entirely.

The result was immediate.

The TypeMismatchException disappeared. 

Even Optimizely support confirmed that after retesting, the exception was no longer reproducible once the problematic plugin code path was removed.

At this stage the evidence was conclusive.

The upgrade itself was not the root cause.

The Siteimprove plugin was.

The Fix

After engaging Siteimprove support and raising a GitHub issue, their development team investigated and released an updated package:

SiteImprove.Optimizely.Plugin 4.3.5

The updated version addressed the compatibility issue.

After upgrading and smoke testing, the problem was resolved.
 
Happy Optimizing!
 
 
0

Optimizely Opti ID Integration: Why the API Key Was Missing from the DXP Management Portal

While working on an Optimizely CMS 12 Opti ID integration recently, we ran into an issue that initially appeared to be related to SSO authentication but turned out to be an environment-specific configuration requirement.

The Problem

We needed to configure API key authentication for an Optimizely integration. However, when accessing the DXP Management Portal (PaaS Portal), the expected API key details were not visible.

At the same time, the team was investigating issues accessing the Admin Center and Support Portal through Opti ID SSO, which made it seem like the problems might be related.

What We Learned

After engaging Optimizely Support, the key piece of information was that:

The API for local configuration only works for the Integration environment. To view and use the API key configuration within the DXP Management Portal, Opti ID must first be enabled for the Integration CMS environment.[docs.devel…mizely.com]

This was not immediately obvious and explained why the API key details were not appearing even though the environment was otherwise accessible.

Resolution

Once Opti ID was enabled for the Integration environment:

  • The DXP Management Portal began displaying the API key details.
  • We were able to retrieve the required credentials.
  • The API key was configured in the application.
  • Functional testing could proceed successfully.

As confirmed during testing:

We have enabled Opti ID for the integration environment and the PaaS portal now shows the API key details. We configured the API key details in our code and started testing the functionality.

Key Takeaways

When working with Optimizely Opti ID integrations:

  1. Verify that Opti ID is enabled for the Integration CMS environment before attempting to retrieve API key details.
  2. If API keys are missing from the DXP Management Portal, check environment configuration first.
  3. Avoid assuming SSO authentication issues and API key visibility issues have the same root cause.
  4. Engage Optimizely Support early when certificate or authentication behavior appears inconsistent.
  5. Complete API key validation in Integration before promoting any configuration to higher environments.

Final Thoughts

A simple environment prerequisite prevented the API credentials from being displayed, and identifying that dependency quickly moved the team from investigation back into testing.

Happy Optimizing!

0

Optimizely CMS 12 and .NET 10 Upgrade: Resolving a TinyMCE Dependency Injection Exception

Framework upgrades often expose hidden compatibility issues that have remained dormant for years. While upgrading one of our Optimizely CMS solutions to .NET 10, we encountered a runtime exception that initially appeared to be a dependency injection problem but ultimately turned out to be an outdated TinyMCE package.

This post documents the issue, the investigation journey, and the surprisingly simple fix.

The Problem

After upgrading our solution to:

  • .NET 10
  • Optimizely CMS 12.34.4

the application failed during startup with the following exception:

AggregateException: One or more errors occurred.
 
Unable to resolve service for type
‘EPiServer.ServiceLocation.ServiceAccessor<EPiServer.Cms.TinyMce.Core.TinyMceConfiguration>’
while attempting to activate
‘DXP.Core.Model.TimelineBlockXhtmlStringEditorDescriptor’.

 

The exception pointed to our custom TinyMCE editor descriptor:

[EditorDescriptorRegistration(
TargetType = typeof(XhtmlString),
EditorDescriptorBehavior = EditorDescriptorBehavior.OverrideDefault,
UIHint = UIHint)]
public class TimelineBlockXhtmlStringEditorDescriptor
: XhtmlStringEditorDescriptor
{
public const string UIHint =
"TimelineBlockXhtmlStringEditorDescriptor";
 
public TimelineBlockXhtmlStringEditorDescriptor(
ServiceAccessor<TinyMceConfiguration> tinyMceConfiguration)
: base(tinyMceConfiguration)
{
}
public override void ModifyMetadata(
ExtendedMetadata metadata,
IEnumerable<Attribute> attributes)
{
// custom implementation
}
}

At first glance, it looked like a service registration or dependency injection issue.

Environment Details

The key package versions at the time were:

  • Optimizely CMS 12.34.4
  • EPiServer.CMS.TinyMce 4.8.3
  • .NET 10

The application had been working correctly before the framework upgrade, which made the issue particularly challenging to diagnose.

Initial Investigation

Our TinyMCE registration was straightforward:

services
.AddCmsAspNetIdentity<ApplicationUser>()
.AddCms()
.AddTinyMce();

and custom configuration was registered using:

services.Configure<TinyMceConfiguration>(config =>
{
// custom TinyMCE settings
});

Everything appeared to be configured correctly.

Testing on Alloy

To isolate the problem, we reproduced similar TinyMCE configuration in a clean Alloy solution running on .NET 10.

The result:

  • CMS started successfully

  • TinyMCE loaded correctly

  • No dependency injection errors

This immediately suggested the problem was not a generic Optimizely or .NET 10 issue.

Reviewing Custom Editor Descriptors

Since the exception referenced:

TimelineBlockXhtmlStringEditorDescriptor

we spent considerable time reviewing:

  • Editor descriptor registrations
  • Dependency injection registrations
  • Startup ordering
  • TinyMCE configuration extensions

Everything looked valid.

Checking Service Registration Order

We also reviewed whether .NET 10 had introduced behavioural differences in service registration and startup initialization.

Multiple registration orders were tested:

services.AddCms();
services.AddTinyMce();
services.Configure<TinyMceConfiguration>();

and

services.Configure<TinyMceConfiguration>();
services.AddCms();
services.AddTinyMce();

No change.

The Root Cause

After eliminating configuration and dependency injection possibilities, attention shifted to package compatibility.

EPiServer.CMS.TinyMce 4.8.3

Although the package had worked successfully before the upgrade, it was clearly not behaving correctly in the .NET 10 environment.

The Fix

We upgraded TinyMCE from:

EPiServer.CMS.TinyMce 5.0.3

After upgrading:

  • Application started successfully
  • TinyMCE initialized correctly
  • Dependency injection exception disappeared
  • Custom editor descriptors continued to work
  • CMS editor experience was fully restored

Happy Optimizely!

0

Optimizely : Missing Language Manager Gadget Fix in CMS 12 After Upgrading to .NET 10

Recently, while upgrading an Optimizely CMS solution to .NET 10, we came across an issue where the Language Manager gadget completely disappeared from CMS Edit Mode.

The application was functioning normally, content editing worked as expected, and there were no build or startup errors. However, editors noticed that the Language Manager gadget was no longer available.

What made the issue difficult to troubleshoot was the complete absence of meaningful error messages.

In this blog, I will walk through the issue, the troubleshooting journey, and the simple configuration change that ultimately resolved it.

Environment

The affected solution was running the following versions:

  • .NET 10
  • Optimizely CMS 12.34.4
  • EPiServer.CMS.UI 12.34.4
  • EPiServer.Labs.LanguageManager 5.5.3

Immediately after the upgrade, the Language Manager gadget disappeared from the CMS editing interface.

Symptoms

Editors reported the following:

  • Language Manager gadget missing from Edit Mode
  • Gadget not available in the “Add Gadgets” list
  • Reinstalling the package did not help
  • Browser cache clearing had no effect
  • Application started successfully without errors

The issue was consistent across environments and users.

Initial Checks

As part of the troubleshooting process, we verified the obvious areas first.

Verify Package Installation

The Language Manager package was installed correctly.

<PackageVersion Include="EPiServer.Labs.LanguageManager" Version="5.5.3" />

No package restore issues were identified.

Verify Language Configuration

We confirmed that all required languages were enabled within Optimizely Admin Mode.

Since multilingual content was configured correctly, the problem was clearly elsewhere.

What Was Causing the Issue?

After working with Optimizely Support, the investigation pointed towards a .NET build configuration setting that was affecting assembly discovery.

The application itself was running correctly, but dependency information required by certain Optimizely add-ons was being trimmed during the build process.

Because of this, Language Manager was not being initialized correctly, resulting in the gadget disappearing from the CMS UI.

The tricky part was that there were:

  • No compilation errors
  • No startup failures
  • No obvious exceptions

The feature simply disappeared.

The Fix

The issue was resolved by adding the following property to the project file:

<PropertyGroup>
<TrimDepsJsonLibrariesWithoutAssets>false</TrimDepsJsonLibrariesWithoutAssets>
</PropertyGroup>
 

After adding the setting:

  1. Rebuild the solution
  2. Redeploy the application
  3. Restart the site

The Language Manager gadget immediately became visible again.

Happy Optimizing! 
0

Unlock AI-Ready Experiences with Optimizely

Over the past few months, almost every customer conversation has shifted from SEO to AI readiness.

The questions are no longer just:

“How do we rank higher on Google?”

They’re becoming:

“How do we make sure ChatGPT, Copilot, Gemini, or Claude can find and understand our content?”

If you’re running an Optimizely website, the good news is that you don’t need a complete redesign. A few small improvements can make your content much easier for AI systems to discover and consume.

In this post, I’ll walk through a few simple changes we’ve been discussing with customers, including:

  • Upgrading the Stott Security RobotHandler
  • Adding an llms.txt file
  • Structuring content for AI
  • Improving metadata
  • Preparing your Optimizely implementation for the next generation of search

Why AI Readiness Matters

Search engines return links.

LLMs return answers.

That means AI systems need to understand your content, not just crawl it.

If your website has:

  • messy content
  • outdated metadata
  • poor internal linking
  • no structured information

then AI assistants have a harder time understanding what your organization actually offers.

Fortunately, most of these improvements are things we should already be doing.

Step 1 – Upgrade Stott Security RobotHandler

We are currently using Stott.Security.Optimizely.RobotsHandler 3.x – CMS PaaS 12 

There isn’t necessarily anything wrong with version 3, but if you’re actively maintaining your solution, it’s worth upgrading to the latest release to benefit from ongoing fixes, compatibility improvements, and newer Optimizely support.

Updating is straightforward.

Remove the old package:

dotnet remove package Stott.Security.Optimizely.RobotsHandler

Install the latest version:

dotnet add package Stott.Security.Optimizely.RobotsHandler

After upgrading, verify that:

  • robots.txt is still generated correctly
  • your sitemap is referenced
  • custom rules still work
  • different environments behave as expected

It only takes a few minutes but keeps an important part of your site’s crawl configuration up to date.

Step 2 – Add an llms.txt File

You have probably heard about llms.txt recently.

Think of it as the AI equivalent of a sitemap.

While it isn’t an official web standard today, more organizations are publishing one to help AI systems discover their most important content.

A simple example looks like this:

# Contoso

Website:
https://contoso.com

Documentation:
https://contoso.com/docs

Products:
https://contoso.com/products

Support:
https://contoso.com/support
 

For smaller websites, a static file is perfectly fine.

For enterprise Optimizely implementations with thousands of pages, I’d recommend generating it dynamically so it always reflects your published content.

That’s something I’ll cover in a future post.

Step 3 – Structure Your Content

This is probably the biggest opportunity.

Many websites still publish pages that contain multiple unrelated topics, huge blocks of text, and headings like:

Learn More

AI models love structure.

Instead, organize pages with:

  • meaningful headings
  • summaries
  • FAQs
  • bullet lists
  • tables where appropriate

Good content structure helps humans and AI alike.

Step 4 – Don’t Ignore Metadata

Metadata is still important.

Make sure every page includes:

  • Page title
  • Meta description
  • Canonical URL
  • Open Graph tags
  • Schema.org structured data

Structured data gives AI additional context about your pages, products, articles, events, and organization.

Step 5 – Review Your Sitemap

Your XML sitemap should always be current.

Remove:

  • unpublished pages
  • redirects
  • expired content

Include:

  • important landing pages
  • articles
  • product pages
  • documentation

This benefits traditional search engines and AI crawlers alike.

Step 6 – Improve Internal Linking

One thing that’s often overlooked is internal linking.

If every page exists in isolation, AI has to work harder to understand the relationships between your content.

Instead, connect related pages naturally.

For example:

  • Blog → Product
  • Product → Documentation
  • Documentation → FAQ
  • FAQ → Support

These relationships help both users and AI navigate your website more effectively.

Step 7 – Expose Content Through APIs

If you’re building AI-powered experiences, don’t stop with web pages.

Optimizely already provides excellent options for exposing structured content, including:

  • Content Delivery API
  • Content Graph
  • Search & Navigation indexes

These services make it much easier to build Retrieval-Augmented Generation (RAG) applications and AI assistants that provide grounded responses based on your content.

Most of these are relatively small changes, but together they make your content significantly easier for AI systems to understand and surface.

As AI continues to change how people discover information, preparing your Optimizely website today will put you in a much stronger position tomorrow.

Happy Optimizing!

0

Optimizely: Upgrade Opti-ID and .NET 10 in CMS 12

Many Optimizely customers are planning their roadmap around a future migration to Optimizely CMS 13. As a result, upgrades such as Opti ID adoption and .NET modernization are often postponed until the CMS 13 project begins.

However, waiting for CMS 13 is not necessary.

Organizations running Optimizely CMS 12 can upgrade to Opti ID and move to .NET 10 today, gaining immediate security, performance, and operational benefits while reducing the complexity of a future CMS 13 migration.

Why Modernize on CMS 12?

Instead of combining multiple transformations into a single CMS 13 project, organizations can:

  • Improve security immediately
  • Standardize authentication
  • Modernize the application platform
  • Reduce future migration complexity
  • Enable newer Optimizely SaaS capabilities

A phased modernization approach is typically lower risk than a large-scale platform upgrade.

Part 1: Implementing Opti ID in CMS 12

What is Opti ID?

Opti ID is Optimizely’s centralized authentication platform that provides:

  • Single Sign-On (SSO)
  • Multi-Factor Authentication (MFA)
  • Centralized user administration
  • Unified access across Optimizely products
  • Improved security and compliance

Required NuGet Packages

Depending on your CMS 12 version, install or upgrade the following packages.

Core CMS Packages

Install-Package EPiServer.CMS
Install-Package EPiServer.CMS.AspNetCore
Install-Package EPiServer.CMS.UI

Identity Packages

Install-Package EPiServer.CMS.UI.AspNetIdentity
Install-Package Microsoft.AspNetCore.Authentication.OpenIdConnect
Install-Package Microsoft.Identity.Web

Always align package versions with the Optimizely-supported package matrix for your CMS version.

Step 1: Enable Opti ID in Optimizely

Within the Optimizely Admin Portal:

  1. Navigate to Administration
  2. Enable Opti ID
  3. Configure organization users
  4. Assign product access
  5. Configure MFA policies

Step 2: Configure Authentication

Update Program.cs.

Add Authentication Services

builder.Services
.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
options.Authority = configuration["Authentication:Authority"];
options.ClientId = configuration["Authentication:ClientId"];
options.ClientSecret = configuration["Authentication:ClientSecret"];

options.ResponseType = "code";

options.SaveTokens = true;
});
 

Step 3: Configure appsettings.json

{
"Authentication": {
"Authority": "https://login.optimizely.com",
"ClientId": "xxxxx",
"ClientSecret": "xxxxx"
}
}

Step 4: Configure Authorization

Map Opti ID users to CMS roles.

Example:

services.AddAuthorization(options =>
{
options.AddPolicy("CmsEditors",
policy => policy.RequireRole("WebEditors"));
});
Validate:
  • WebEditors
  • Administrators
  • ContentApprovers
  • MarketingUsers

Part 2: Upgrading CMS 12 to .NET 10

Why Upgrade?

Benefits include:

  • Improved performance
  • Better security
  • Long-term support alignment
  • Reduced technical debt
  • Better cloud-native capabilities

Step 1: Upgrade Development Environment

Install:

  • .NET 10 SDK
  • Visual Studio 2026 (or latest supported version)

Step 2: Update Project Files

Update:

<TargetFramework>net10.0</TargetFramework>

Step 3: Upgrade NuGet Packages

CMS Packages

<PackageReference Include="EPiServer.CMS.Core" Version="12.24.0" />
<PackageReference Include="EPiServer.CMS.UI" Version="12.34.4" />

Microsoft Packages  

<PackageReference Include="Microsoft.Extensions.*" />
<PackageReference Include="Microsoft.AspNetCore.*" />
<PackageReference Include="Microsoft.Identity.Web" />

Hope this helps.

Happy Optimizing!
0

Optimizely CMS 13 Upgrade Overview

Wondering how to upgrade from Optimizely CMS 12 to 13? Not sure where to start – you are not alone. 

Here is a quick overview of the key architectural changes that need to be addressed.

Key Architecture Changes

  1. No Search and Navigation
  2. Opti-ID for Identity
  3. Graph for Search and Discovery
  4.  Embedded DAM
  5. OCP for Integrations
  6. OPAL for AI

Optimizely CMS 13

 

🟩Graph — Search & Discovery

  • Provides unified content search across structured and unstructured data.

  • Enables semantic relationships between content items.

  • Powers personalized discovery experiences through relevance scoring and taxonomy mapping.

  • Integrates with Optimizely’s indexing layer for fast retrieval and filtering.

🟦Opti‑ID — Identity & Access

  • Centralized identity provider for user authentication and authorization.

  • Supports SSO, OAuth 2.0, and enterprise federation (e.g., Azure AD, Okta).

  • Manages user roles, permissions, and attribute mapping across CMS modules.

  • Ensures secure access control for editors, marketers, and external systems.

🟪OPAL — AI Services

  • Provides AI‑driven content recommendations and predictive analytics.

  • Automates tagging, summarization, and personalization workflows.

  • Integrates with external AI APIs for language and vision tasks.

  • Enhances editorial efficiency through intelligent suggestions and insights.

🟩Embedded DAM — Asset Management

  • Manages digital assets (images, videos, documents) directly within CMS.

  • Supports versioning, metadata tagging, and rights management.

  • Enables seamless asset reuse across pages and campaigns.

  • Connects to external storage or CDN for optimized delivery.

⬛OCP — Integrations & Connectors

  • Provides an integration framework for third‑party systems (CRM, ERP, marketing tools).

  • Uses REST APIs and webhooks for data synchronization.

  • Supports modular connectors for commerce, analytics, and automation.

  • Ensures scalable interoperability across enterprise ecosystems.

Hope this helps.

Happy Optimizing!

 

0