How to Deliver Personalized Experiences Without Compromising Site Security
Delivering personalized digital experiences while keeping your site secure? It’s not a pipedream anymore. This guide shows how to make Adobe Target and Content Security Policy (CSP) work together—so marketers can personalize freely, and developers can sleep soundly.
What Is CSP?
Think of Content Security Policy (CSP) as your site’s gatekeeper. It defines a set of rules that tells browsers which sources of content such as scripts, styles, images are safe to load and blocks anything suspicious.
CSP is your knight in shining armor against cross-site scripting attacks.
For Marketers: Why You Should Care
A strict CSP, if not configured for Adobe Target, can disrupt your personalization efforts. Problems may include:
- Failed rendering of personalized experiences
- Broken reporting and Analytics
- Unexpected errors in the Visual Experience Composer (VEC)
The fix? Collaborate with your development team to configure CSP correctly to allow personalization through Adobe Target.
For Developers: Making CSP and Adobe Target Work Together
To ensure Adobe Target functions correctly on your site, your Content Security Policy (CSP) must satisfy two key conditions:
1. Authorize the Source of Adobe Target Scripts
Your CSP must explicitly trust the origin of the Target library. This could be:
- A self-hosted at.js file
- An Adobe-managed at.js file
- The AEP Web SDK (alloy.js via Adobe Tags)
- A third-party tag manager
If the source isn’t allowlisted, your CSP will block the tag manager and prevent Adobe Target scripts from loading—disabling personalization features.
2. Allow Inline Scripts and Styles
By default, CSP blocks inline code — exactly what Adobe Target uses to deliver dynamic, personalized content. Inline scripts are also essential for executing Custom Code actions in Adobe Tags. Without this allowance, rule execution fails and Target experiences won’t render as expected.
Getting Started
Here is a five-step approach you could use to meet the key requirements to ensure that Adobe Target functions on your site while complying with your CSP guidelines.
Step 1: Determine your Adobe Target implementation
Identify whether you're using a self-hosted or Adobe-managed (via Adobe Tags) at.js or AEP Web SDK (alloy.js).
Step 2: Decide on an inline code execution strategy
Determine whether you want to use a nonce-based approach (recommended) or 'unsafe-inline' to allow inline scripts and styles essential for personalization.
Step 3: Configure CSP directives
Add the appropriate script, style, frame and connect sources to the CSP directives based on your setup to trust the Target source and enable inline code execution.
Step 4 (if applicable): Configure Adobe Tags to use the nonce
Ensure that Adobe Tags is configured with your nonce-based CSP strategy—or skip to Step 5 if not using nonce.
Step 5: Test thoroughly
Thoroughly test your site to confirm Adobe Target experiences are rendering correctly and personalization is functioning as expected.
Ready? Let's dive in!
Step 1: Determine your Adobe Target implementation
Library Type
- at.js or
- AEP Web SDK (alloy.js)
Implementation Method
- Self-hosted tag library or
- Adobe-managed hosting (via Adobe Tags) or
- No tag manager
Step 2: Decide on an inline code execution strategy
Recommended Approach: Using Nonce
If your organization enforces a strict CSP, implementing a nonce-based solution is the recommended approach for allowing inline styles and scripts securely.
What is a nonce?
A nonce (short for “number used once”) is a unique, server-generated token for each page load that securely authorizes inline styles and scripts.
Implementing a nonce-based CSP:
- Ensure that your site uses at.js version 2.3.0 or higher OR alloy.js
- Generate a fresh nonce for every page load
- Add nonce to the CSP directives
- Configure Adobe Tags to use the nonce
Alternative: Using Unsafe-Inline or Hashes
Unsafe-Inline
When nonce-based configuration isn’t possible, the fallback option is to allow all inline scripts and styles using 'unsafe-inline' directives. This is easier to set up but comes with security risks and should only be used if nonce configuration is not feasible.
Note on Hashes
While hashes offer another option for allowing inline scripts and styles, a hash-based solution is not feasible to use with tag-management systems like Adobe Tags. For more information on the limitations of using hashes with tags in AEP, see the Subresource Integrity (SRI) guide.
Step 3: Configure CSP Directives
The CSP directives detailed below can be configured one of two ways:
- By adding a Content-Security-Policy HTTP header to your server responses, or
- By adding a configured <meta> element in the <head> section of your HTML files
Consult with your technical partners to determine the suitable method for your site.
For at.js
Directive
|
What to Allow
|
Why It Matters
|
Notes
|
connect-src
|
*.tt.omtrdc.net
|
Enables communication with Target edge nodes
|
|
script-src
|
'self'
assets.adobedtm.com
nonce or 'unsafe-inline'
|
Loads tag library, at.js, and inline scripts
|
Also add nonce to targetGlobalSettings.cspScriptNonce
assets.adobe.dtm.com is only required when using Adobe Tags to deliver at.js
|
style-src
|
'self'
nonce or 'unsafe-inline'
|
Enables flicker control and inline styling
|
Also add nonce to targetGlobalSettings.cspScriptStyle
|
frame-src
|
'self'
*.adobe.com
*.adobedtm.com
|
Supports VEC embedded editing
|
*.adobedtm.com is only required when using Adobe Tags to deliver at.js
|
Examples:
script-src
script-src 'self' assets.adobedtm.com 'nonce-2726c7f26c' // Using nonce and Adobe Tags
script-src 'self' 'nonce-2726c7f26c' // Self-hosted and nonce
script-src 'self' assets.adobedtm.com 'unsafe-inline' // Using Adobe Tags but no nonce
HTTP header
Content-Security-Policy: script-src 'self' assets.adobedtm.com 'nonce-2726c7f26c'
HTML <meta> tag
<meta http-equiv="Content-Security-Policy" content="script-src 'self' assets.adobedtm.com 'nonce-2726c7f26c'">
Nonce configuration in targetGlobalSettings
Ensure that targetGlobalSettings is set prior to the at.js script loading, as shown below-
<head>
<script nonce="SERVER-GENERATED-SCRIPT-NONCE">
window.targetGlobalSettings = {
cspScriptNonce: "SERVER-GENERATED-SCRIPT-NONCE",
cspStyleNonce: "SERVER-GENERATED-STYLE-NONCE"
};
</script>
<script nonce="SERVER-GENERATED-SCRIPT-NONCE" src="at.js"></script>
</head>
For AEP Web SDK
Directive
|
What to Allow
|
Why It Matters
|
Notes
|
connect-src
|
'self'
EDGE-DOMAIN
*.demdex.net
|
Enables communication with AEP edge nodes
|
EDGE-DOMAIN = *.adobedc.net OR first-party domain per the edgeDomain setting
Use *.demdex.net only if idMigrationEnabled is turned on
|
default-src
|
'self'
nonce
|
Enables inline scripts and styles securely (Recommended)
|
Also add nonce to the base code script tag when delivering alloy.js without a tag manager
|
style-src
|
'unsafe-inline'
|
Allows all inline styles (Not Recommended)
|
Use only if nonce is not implemented
|
script-src
|
'unsafe-inline'
|
Allows all inline scripts (Not Recommended)
|
Example: default-src 'nonce-SERVER-GENERATED-NONCE'
Add nonce to the AEP Web SDK base code script tag
<script nonce="SERVER-GENERATED-NONCE">
!function(n,o){o.forEach(function(o){n[o]||((n.__alloyNS=n.__alloyNS||
[]).push(o),n[o]=function(){var u=arguments;return new Promise(
function(i,l){n[o].q.push([i,l,u])})},n[o].q=[])})}
(window,["alloy"]);
</script>
Step 4: Configure Adobe Tags to use nonce
This step is for implementations that use Adobe Tags to deliver at.js or alloy.js.
Once your CSP is configured to use nonce, you must then tell Adobe Tags where to find the nonce when loading inline code, as follows:
- Create a data element that references where the nonce is located within your data layer
- Configure the Core Extension and specify which data element you used
- Publish your data element and Core Extension changes
Step 5: Test thoroughly
- Make all changes in a lower-level (LLE) environment
- Use staging, dev, or QA environments to isolate changes
- Ensure the LLE mirrors production settings as closely as possible to simulate a production level environment
- Use browser dev tools to inspect CSP violations
- Open the Console tab to catch blocked resources or inline script issues.
- Look for errors like Refused to execute inline script because it violates the CSP directive
- Confirm personalization experiences load correctly
- Validate that Adobe Target experiences are rendering as expected
- Test across browsers and devices
- Include Chrome, Firefox, Safari, Edge, and mobile browsers
- Migrate changes to production only after full validation
- Ensure all appropriate CSP configurations are in place
- Monitor real time post-launch to catch any post-production issues
Collaboration Is Key
Marketers: Ask your dev team if strict CSP is enabled and share Adobe’s recommended guidelines (this blog!) so you can be unblocked in your personalization efforts.
Developers: Document your CSP exceptions and explain why they are needed for personalization.
In Conclusion
With the right adjustments to your site’s CSP configuration, you don’t have to choose between security and personalization. Developers can enforce strong security policies, and marketers can seamlessly deliver tailored experiences.
***
Are you looking to optimize your website's performance and drive conversions?Look no further than Adobe - the industry leader in A/B testing. With more A/B tests under our belt than any other organization in the world, we have the expertise and knowledge to take your online presence to the next level. Adobe Target is unrivaled in the industry, and with Adobe Consulting, you can have access to this powerful tool and the expertise behind it. Don't miss out on the opportunity to unlock the full potential of your website. Contact us today and discover how Adobe can help your business thrive. If you would like to understand how Adobe can help your business reach out to Adobe Professional Services.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.