> For the complete documentation index, see [llms.txt](https://docs.adpage.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.adpage.io/integrations-websites/magento/configuring-content-security-policy.md).

# Configuring Content Security Policy

AdPage's tracking script can get blocked by Content Security Policy. How to identify exactly what's being blocked, and how to allow it properly in Magento.

This article is for Magento developers and IT teams. It explains why AdPage's tracking script and your marketing tags can get blocked by Content Security Policy (CSP), how to identify exactly what's being blocked, and how to allow it properly in Magento.

### What CSP does, and why our script trips it

Content Security Policy is a browser-enforced allowlist. It tells the browser which external sources may be loaded and which inline code may run, which makes Cross-Site Scripting a great deal harder to pull off. Magento ships with the CSP module enabled and, in restrict mode, blocks any external script that hasn't been explicitly allowed.

Our tracking script needs a mention in that allowlist for two reasons:

**It contains additional JavaScript.** Beyond loading the container, the script provides features such as the Cookie Keeper. That's more than a plain vendor snippet does, and some of it runs inline.

**It loads from your own custom domain.** We serve tracking from a subdomain of your site, for example `tagging.yourdomain.com`, configured through a CNAME record in the AdPage dashboard. This makes the request far less likely to be stopped by common adblockers, but it also means the domain is unique to you and cannot be pre-allowlisted by us.

Neither of these is something we can work around from our side. The allowlist lives in your CSP header, so the change has to happen in Magento.

### Find out what's actually being blocked

Don't guess at the domain list. Read it off the browser.

1. Open developer tools (F12) and go to the **Console** tab.
2. Load a page that includes the tracking script (complete a checkout in a test order if you can).
3. Look for CSP violation warnings. Each one names the blocked URL and, importantly, **which directive blocked it**, that tells you where the entry belongs.

A typical violation reads along the lines of *"Refused to load the script … because it violates the following Content Security Policy directive: script-src …"*. The directive name at the end is the one you need to extend.

Two things worth doing while you're in there:

* Check the console again after a checkout, not just on the homepage. Conversion pixels often only fire on the order confirmation page, so a homepage-only check will miss exactly the tags that matter most.
* If your store runs CSP in report-only mode, violations are logged rather than blocked. That's ideal for building your list — but remember that everything will appear to work until you switch to restrict mode.

### The three ways CSP breaks tracking

#### 1. A blocked domain

**Symptom:** the script or a pixel never loads, and the console names the domain.

**Cause:** the domain isn't listed under the relevant directive. This is CSP working as designed, not a misconfiguration.

**Fix:** add the domain to the correct directive. Which directive depends on how the resource is loaded:

| What's loading                                 | Directive                                                      |
| ---------------------------------------------- | -------------------------------------------------------------- |
| Your tagging domain (`tagging.yourdomain.com`) | `script-src`, and `connect-src` if events are sent server-side |
| LinkedIn Insight Tag (`px.ads.linkedin.com`)   | `img-src` (and `script-src` for `snap.licdn.com`)              |
| Pinterest tag (`ct.pinterest.com`)             | `img-src` (and `script-src` for `s.pinimg.com`)                |
| Any tag that posts data via `fetch` or `XHR`   | `connect-src`                                                  |
| Any tag that renders an iframe                 | `frame-src`                                                    |

Treat that table as a pattern, not a complete list. The exact set of domains depends entirely on what's inside your GTM container, and it changes when the container changes. Add only the domains you genuinely use.

#### 2. A blocked inline script (nonce)

**Symptom:** the script loads from an allowed domain, but inline code it injects never executes.

**Cause:** if your `script-src` directive includes a nonce, the browser ignores `unsafe-inline` entirely. From that point on, inline scripts run only when they carry the exact nonce value from the current response header. Google Tag Manager and several tracking scripts inject inline code at runtime, so they're affected.

**Fix:** pass the server-generated nonce through to the container script tag. The server must mint a fresh cryptographic nonce per request, include it in the CSP header, and set the same value as an attribute on the tag:

html

```html
<script
    type="text/javascript"
    src="https://www.googletagmanager.com/gtm.js?id=GTM-XXXXXXX"
    nonce="THE_UNIQUE_NONCE_VALUE">
</script>
```

Recent Magento versions expose a nonce provider you can inject into a block or template rather than generating one yourself — check the Adobe documentation for your specific version before rolling your own.

Be aware that under a strict nonce-based policy, **Custom HTML tags and Custom JavaScript variables in GTM may stop working altogether**, since GTM cannot attach your server's nonce to code it writes at runtime. If a tag depends on Custom HTML, plan on either moving that logic server-side or relaxing the policy for it deliberately.

#### 3. Blocked `eval`

**Symptom:** the container loads, but preview mode or certain custom templates fail with an `unsafe-eval` violation.

**Cause:** some tag templates and GTM's own debug tooling evaluate code at runtime.

**Fix:** there isn't a clean one. Allowing `unsafe-eval` weakens the policy meaningfully, so it's worth first checking whether the tag has an alternative implementation. If you only see this in preview mode, you can often live with it and validate the tag another way.

### Making the change in Magento

Magento's CSP configuration is code-managed, not something to patch into a template. Add allowlist entries through a `csp_whitelist.xml` file in your own module or theme — never by editing core files:

xml

```xml
<?xml version="1.0"?>
<csp_whitelist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Csp:etc/csp_whitelist.xsd">
    <policies>
        <policy id="script-src">
            <values>
                <value id="adpage_tagging" type="host">tagging.yourdomain.com</value>
            </values>
        </policy>
        <policy id="connect-src">
            <values>
                <value id="adpage_tagging_connect" type="host">tagging.yourdomain.com</value>
            </values>
        </policy>
    </policies>
</csp_whitelist>
```

Place it in `app/code/YourVendor/YourModule/etc/`, then flush the config cache. A few things to keep in mind:

* Storefront and admin have **separate** policies. Tracking belongs to the storefront; scoping it correctly avoids loosening the admin unnecessarily.
* Restrict mode versus report-only mode is configurable per area. Deploy your allowlist while in report-only mode, confirm the console is quiet, and only then enforce.
* Adobe's documentation is the authority on the details and on version differences: [Content Security Policies in Adobe Commerce](https://developer.adobe.com/commerce/php/development/security/content-security-policies/). If you're handing this off to someone else, that link plus your domain list is everything they need.

After deploying, retest properly: load the site, submit a form, complete a test order, and confirm in GTM preview mode that every tag still fires.

### This list will go stale

GTM containers change more often than CSP headers do, which is how tracking quietly breaks months after a working implementation. Build a small habit around it:

* Check the browser console for new CSP warnings periodically, not just after an incident.
* When you add a marketing tag, check whether it introduces a new domain before you publish the container.
* Treat a CSP update as part of the work whenever new tracking functionality ships.

### Still stuck?

If tags remain blocked after configuring the allowlist, email <support@adpage.io> and include:

* Your current CSP configuration, or the response header itself
* The exact console violations, copied rather than paraphrased
* Which tags aren't working, and on which pages

That combination usually lets us pinpoint the missing directive on the first reply.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.adpage.io/integrations-websites/magento/configuring-content-security-policy.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
