Geodocs.dev

CSP Policy AI Crawler Allowlist Specification

ShareLinkedIn

A Content-Security-Policy that uses nonce- or hash-based script-src (strict CSP) is fully compatible with AI crawlers because crawlers that render JavaScript honor the same nonces a real browser does; the failure modes are missing nonces on hydration scripts, blocked third-party fonts, and frame-ancestors 'none' accidentally applied to embeddable card surfaces.

TL;DR

Ship a strict CSP based on nonces or hashes, run Content-Security-Policy-Report-Only for one full crawl cycle, and verify that bot-class user agents trigger zero violations. Replace X-Frame-Options with frame-ancestors. AI crawlers that fetch raw HTML ignore CSP; AI crawlers that render JavaScript respect it identically to a browser.

Scope

This specification covers the Content-Security-Policy header for sites that want to remain citation-eligible by AI search engines. It applies to canonical content pages, server-rendered apps, single-page apps with hydration, and CDN-edge configurations.

It does not cover Trusted Types, COEP/COOP, or Permissions-Policy; those are addressed in the Security Headers Configuration for AI Crawlers reference.

How AI crawlers interact with CSP

CSP is a browser-side enforcement mechanism. It only takes effect when an AI crawler renders the page in a headless browser. Three classes of AI traffic apply:

  • Raw fetchers (GPTBot, ClaudeBot, Google-Extended, most training crawlers) ignore CSP entirely. They parse HTML and never execute scripts.
  • Rendering crawlers (subset of OAI-SearchBot, PerplexityBot, ChatGPT user-triggered, browsing agents) execute JavaScript. They honor CSP exactly as a Chromium browser does.
  • Agent / tool bots behave like full browsers and respect every directive including report-only.

The practical implication: a CSP that breaks hydration in a real browser will also break it for rendering crawlers, and your content will be invisible in answer surfaces.

Directive matrix for AI crawler compatibility

Directive Recommended value AI crawler note
default-src 'self' Safe baseline; rendering crawlers fetch same-origin assets first.
script-src 'self' 'nonce-{random}' 'strict-dynamic' Strict CSP per web.dev. Crawlers honor nonces.
style-src 'self' 'nonce-{random}' Avoid 'unsafe-inline'. Use nonces for critical CSS.
img-src 'self' data: https: Permissive https: allows third-party CDN images, including embedded video thumbnails AI surfaces depend on.
font-src 'self' https://fonts.gstatic.com Blocked fonts cause render layout shifts; rendering crawlers may flag the page low quality.
connect-src 'self' https://api.example.com Allow any fetch endpoints needed for hydration. Bots time out on blocked XHR.
frame-ancestors 'none' on auth pages; 'self' or specific allowlist elsewhere Per MDN, supersedes X-Frame-Options. Safe for AI crawlers; affects only browser embeds.
base-uri 'self' No effect on crawlers.
form-action 'self' No effect on crawlers (they don't submit forms).
upgrade-insecure-requests Enabled Helps crawlers that follow protocol upgrades.
report-uri / report-to Endpoint URL Required for report-only mode debugging.

Strict CSP recipe

Follow the OWASP strict-CSP recommendation (OWASP, 2025) and Google's web.dev guide. The minimum policy:

Content-Security-Policy:
default-src 'self';
script-src 'self' 'nonce-r4nd0m' 'strict-dynamic' https:;
style-src 'self' 'nonce-r4nd0m';
img-src 'self' data: https:;
font-src 'self' https://fonts.gstatic.com;
connect-src 'self' https://api.example.com;
frame-ancestors 'self';
base-uri 'self';
form-action 'self';
upgrade-insecure-requests;
report-to csp-endpoint

Generate a fresh nonce per request, attach it to every inline