[Content Security Policy](https://developer.mozilla.org/docs/Web/HTTP/CSP) (CSP) is a widely supported Web
security standard intended to prevent certain types of injection-based attacks
by giving developers control over the resources loaded by their applications.
Use this guide to understand how to deploy Google Tag Manager on sites that
use a CSP.

> [!NOTE]
> **Note:** To ensure the CSP behaves as expected, it is best to use the [`report-to`](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy/report-to) directives to get reports of policy violations.

## Enable the container tag to use CSP

To use Google Tag Manager on a page with a CSP, the CSP must allow for the
execution of your Tag Manager container code. This code is built as inline
JavaScript code that injects the `gtm.js` script. There are several ways to do
this, such as the use of a nonce or a hash. The recommended method is to use a
[nonce](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/nonce), which should be an unguessable, random value that the server generates
individually for each response. Supply the nonce value in the
Content-Security-Policy `script-src-elem` directive as
`nonce-{SERVER-GENERATED-NONCE}`, and use the nonce-aware version of the inline
Tag Manager container code. Set the `nonce` attribute on the inline script
element to this same value:

```html
<!-- Google Tag Manager -->
<script nonce='{SERVER-GENERATED-NONCE}'>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;var n=d.querySelector('[nonce]');
n&&j.setAttribute('nonce',n.nonce||n.getAttribute('nonce'));f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXX');</script>
<!-- End Google Tag Manager -->
```

Tag Manager will then propagate the nonce to any scripts that it adds to
the page.

There are other approaches to enabling the execution of an inline script, such
as supplying the [hash of the inline script](https://developer.mozilla.org/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#Unsafe_inline_script) in the CSP.

If the recommended nonce or hash approaches are not feasible, it is possible to
enable the Tag Manager inline script by adding the `'unsafe-inline'`
directive to the CSP's `script-src-elem` section.

> [!CAUTION]
> The use of `'unsafe-inline'` is discouraged. You should carefully consider the security ramifications of adding this directive to the CSP before using this approach.

The following must be allowed by the CSP to use this approach:

| Directive | Content |
|---|---|
| `script-src-elem` | `https://www.googletagmanager.com 'unsafe-inline'` |
| `img-src` | `https://www.googletagmanager.com` |
| `connect-src` | `https://www.googletagmanager.com https://www.google.com` |

> [!NOTE]
> **Note:** Certain tags load content from or make requests to other origins, so they require the use of additional CSP directives to function properly.

## Custom JavaScript Variables

Due to how [Custom JavaScript variables](https://support.google.com/tagmanager/answer/7683362#custom_javascript) are implemented, they
will evaluate to `undefined` in the presence of a CSP unless the
`'unsafe-eval'` directive is given in the `script-src` section of the CSP.

> [!CAUTION]
> To avoid potential security vulnerabilities, use `'unsafe-eval'` only when absolutely necessary.

| Directive | Content |
|---|---|
| `script-src` | `'unsafe-eval'` |

> [!NOTE]
> **Note:** [Custom Templates](https://developers.google.com/tag-platform/tag-manager/templates.md.txt) are the recommended alternative to Custom JavaScript variables. They can be used to create custom tags and variables that don't require the use of `'unsafe-eval'`.

## Preview Mode

In order to use Google Tag Manager's [Preview Mode](https://support.google.com/tagmanager/answer/6107056), the CSP must allow the
following:

| Directive | Content |
|---|---|
| `script-src-elem` | `https://www.googletagmanager.com https://tagmanager.google.com` |
| `style-src` | `https://www.googletagmanager.com https://tagmanager.google.com https://fonts.googleapis.com` |
| `img-src` | `https://www.googletagmanager.com https://ssl.gstatic.com https://www.gstatic.com` |
| `font-src` | `https://fonts.gstatic.com data:` |

## Google Analytics

To use Google Analytics, the CSP must allow the following:

| Directive | Content |
|---|---|
| `script-src-elem` | `https://www.googletagmanager.com` |
| `img-src` | `https://www.googletagmanager.com https://*.google-analytics.com https://*.google.com https://*.google.<TLD> https://*.g.doubleclick.net` |
| `connect-src` | `https://www.googletagmanager.com https://*.google-analytics.com https://*.google.com https://*.google.<TLD> https://*.g.doubleclick.net https://pagead2.googlesyndication.com` |
| `frame-src` | `https://www.googletagmanager.com` |

> [!NOTE]
> **Note:** Each Google top-level domain (TLD) must be specified individually, since CSP syntax does not allow the use of wildcards on the right side of the hostname. A list of all supported Google TLDs is available at: <https://www.google.com/supported_domains>.

> [!NOTE]
> **Note:** The preceding includes endpoints specifically required for advertising features used by Google Ads-linked properties, which we recommend including during initial setup so that the CSP does not need to be updated if you link Google Ads later.

To use Google Analytics without any Ads features, the CSP must allow the
following:

| Directive | Content |
|---|---|
| `script-src-elem` | `https://www.googletagmanager.com` |
| `img-src` | `https://www.googletagmanager.com https://*.google-analytics.com` |
| `connect-src` | `https://www.googletagmanager.com https://*.google-analytics.com https://*.google.com` |

## Google Ads

To use a Google Ads Conversion, Remarketing, or Conversion Linker tag, the CSP
must allow the following:

| Directive | Content |
|---|---|
| `script-src-elem` | `https://www.googletagmanager.com https://www.googleadservices.com https://www.google.com` |
| `img-src` | `https://www.googletagmanager.com https://www.googleadservices.com https://googleads.g.doubleclick.net https://pagead2.googlesyndication.com https://www.google.com https://www.google.<TLD>` |
| `connect-src` | `https://www.googletagmanager.com https://www.googleadservices.com https://googleads.g.doubleclick.net https://pagead2.googlesyndication.com https://www.google.com https://www.google.<TLD> https://ad.doubleclick.net` |
| `frame-src` | `https://www.googletagmanager.com` |

## Google Ads User Data

To use the Google Ads user data beacons when running in secure contexts, the CSP
must allow the following:

| Directive | Content |
|---|---|
| `script-src-elem` | `https://www.googletagmanager.com` |
| `connect-src` | `https://www.google.com` |
| `frame-src` | `https://www.googletagmanager.com` |

The Google ads user data beacon does not run in insecure contexts, so CSP
configuration in those cases is not applicable.

## Floodlight

To use Floodlight, the CSP must allow the following:

| Directive | Content |
|---|---|
| `img-src` | `https://www.googletagmanager.com https://ad.doubleclick.net https://ade.googlesyndication.com https://adservice.google.com` |
| `connect-src` | `https://pagead2.googlesyndication.com https://www.google.com https://www.googleadservices.com https://ad.doubleclick.net` |
| `frame-src` | `https://www.googletagmanager.com` |

To use Floodlight custom scripts, the CSP must also allow the following (in
addition to the preceding):

| Directive | Content |
|---|---|
| `frame-src` | `https://*.fls.doubleclick.net` |

## Merchant Center

To use Merchant Center, the CSP must allow the following:

| Directive | Content |
|---|---|
| `script-src-elem` | `https://www.googletagmanager.com` |
| `img-src` | `https://*.merchant-center-analytics.goog` |
| `connect-src` | `https://*.merchant-center-analytics.goog` |

## Google tag gateway for advertisers

When you use [Google tag gateway for advertisers](https://developers.google.com/tag-platform/tag-manager/gateway), the Google tag
is loaded from and sends data to a measurement path on your website (for
example, `https://www.example.com/metrics`). Some tags still send requests to
Google domains, so keep the directives listed for each product, and also allow
the following:

| Directive | Content | Purpose |
|---|---|---|
| `script-src-elem` | `'self'` | Loading the Google tag from your measurement path |
| `img-src` | `'self'` | Measurement requests |
| `connect-src` | `'self'` | Measurement requests |
| `worker-src` | `'self'` | Service worker |

Make sure your CDN or web server doesn't add your website's
`Content-Security-Policy` header to responses from your measurement path.
Otherwise, the browser can block the service worker.

## Server-side tagging

When the Google tag sends data to a [server container](https://developers.google.com/tag-platform/tag-manager/server-side),
the CSP must also allow your tagging server. These directives don't replace the
directives listed for each product, such as `https://www.googletagmanager.com`.
What you add depends on where your tagging server is hosted:

| Directive | Same-origin setup | Subdomain setup | Purpose |
|---|---|---|---|
| `img-src` | `'self'` | `https://TAGGING_SERVER_DOMAIN` | Measurement requests |
| `connect-src` | `'self'` | `https://TAGGING_SERVER_DOMAIN` | Measurement requests |
| `frame-src` | `'self'` | `https://TAGGING_SERVER_DOMAIN` | Service worker |
| `worker-src` | `'self'` | Not needed | Service worker |
| `script-src-elem` | `'self'` | `https://TAGGING_SERVER_DOMAIN` | Only if you load the Google tag from your tagging server |

In a same-origin setup, the tagging server is served from a path on your
website (for example, `https://www.example.com/metrics`). In a subdomain setup,
replace `TAGGING_SERVER_DOMAIN`
with your tagging server domain (for example, `sgtm.example.com`).

In a same-origin setup, make sure your CDN or web server doesn't add your
website's `Content-Security-Policy` header to responses from the tagging path.
Otherwise, the browser can block the service worker.

## Service worker

The Google tag uses a service worker only when you use Google tag gateway for
advertisers or server-side tagging. For the directives that each setup needs,
see [Google tag gateway for advertisers](https://developers.google.com/tag-platform/security/guides/csp.md.txt#google_tag_gateway_for_advertisers)
and [Server-side tagging](https://developers.google.com/tag-platform/security/guides/csp.md.txt#server-side_tagging). If you use both, the CSP must
allow both.

## Troubleshoot with Tag Assistant

To troubleshoot Content Security Policy (CSP) issues, use [Tag Assistant](https://tagassistant.google.com). Tag Assistant will display the list of resources that are blocked by your Content Security Policy.

1. Open [Tag Assistant](https://tagassistant.google.com) and Enter your website's URL. A new tab with your website opens.

2. If the Content Security Policy on your page is blocking a resource, a CSP issue is displayed in the **Page issues** section of Tag Assistant.

   ![Screenshot of Tag Assistant showing CSP issue](https://developers.google.com/static/tag-platform/security/images/csp-issue.png)
3. Select **View issue** next to the CSP issue to view the list of all blocked resources on your page.
   ![Screenshot of Tag Assistant showing the CSP issue slider](https://developers.google.com/static/tag-platform/security/images/csp-issue-slider.png)

4. Add all blocked resources to your Content Security Policy.