Skip to content

fix(realm): allow the AI assistant CDN and the hydration script in the CSP - #394

Merged
h0pped merged 2 commits into
mainfrom
fix/csp-allow-ai-assistant-cdn
Aug 20, 2026
Merged

fix(realm): allow the AI assistant CDN and the hydration script in the CSP#394
h0pped merged 2 commits into
mainfrom
fix/csp-allow-ai-assistant-cdn

Conversation

@h0pped

@h0pped h0pped commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

What/Why/How?

Two script-src additions to the global CSP.

  • https://cdn.redocly.com - The AI assistant playground on the web component docs page loads the widget bundle from this host. A srcdoc iframe inherits the parent page's CSP, so the bundle is blocked and the playground currently renders nothing on prod: window.RedoclyAssistant is undefined and <redocly-ai-assistant> never upgrades.
  • sha256-gOx3nRh8znDQR7T1VkI+fFXDgsNzf5enQqdi7NP11Vk= - The react-router window.__staticRouterHydrationData script. This is unrelated to the playground: it is blocked on every page of the site, and is the likely source of the Minified React error #418 hydration warning in the console.

The /editor block is untouched. The playground is not on that route.

I added the host to the global '**' block rather than a page-scoped one. A more specific pattern replaces the global CSP instead of merging with it, so a scoped block means copying all 40 lines and keeping them in sync. The /editor block already shows that drift: it is missing the HubSpot and Clarity hosts and about ten hashes the global block has gained since.

Reference

Follow-up to Redocly/redocly#26113, which shipped the playground.

Testing

Served the exact srcdoc document from prod behind this branch's CSP on a local server, then loaded it in a browser:

before after
typeof RedoclyAssistant undefined object
custom element upgraded no yes
shadow root attached no yes

Verified redocly.yaml still parses and all ten CSP directives survive the edit.

One violation remains after this change, by design: the playground's preview document also runs a small inline script, and its hash is deliberately not added here. Hash-allowlisting it would mean a CSP change in this repo every time that script's whitespace changes. It will be removed from the docs source instead, in Redocly/redocly. Its only effect is the preview panel's desktop width, so the playground is usable without it.

Screenshots (optional)

Before: (errors and nothing renders):
image

After:
image

Check yourself

  • Code is linted
  • Tested
  • All new/updated code is covered with tests

No test layer covers this repo's response headers.

Security

  • Security impact of change has been considered
  • Code follows company security practices and guidelines

cdn.redocly.com is a Redocly-owned CDN. The added hash pins one exact inline script, which is strictly narrower than a nonce or 'unsafe-inline'. No directive is loosened and no keyword source is added.

h0pped added 2 commits August 20, 2026 11:09
…e CSP

Add `https://cdn.redocly.com` to `script-src`. The AI assistant web
component playground loads the widget bundle from that host, and the
`srcdoc` preview iframe inherits this policy, so the bundle was blocked
and the playground rendered nothing.

Add the hash of the react-router hydration script. That script is on
every page and was blocked site-wide.
@h0pped
h0pped marked this pull request as ready for review August 20, 2026 09:25

@redocly redocly Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

marketing-site AI Review: 🟢 Completed

Redocly Agent has reviewed your changes and found 3 potential issue(s).

Note

Low Risk

Modifies the global Content Security Policy to explicitly allow specific scripts. The additions are restricted to a Redocly-owned CDN and an exact script hash, maintaining the current security posture without broadly loosening directives.

Overview

Updates the global script-src CSP directive in redocly.yaml to include https://cdn.redocly.com and a new script hash (sha256-gOx3nRh8znDQR7T1VkI+fFXDgsNzf5enQqdi7NP11Vk=). This change permits the AI assistant web component playground to render its widget bundle correctly on documentation pages, and unblocks a react-router hydration script across the site to resolve a React hydration console warning.

@h0pped
h0pped merged commit 57f43a3 into main Aug 20, 2026
4 of 7 checks passed
@h0pped
h0pped deleted the fix/csp-allow-ai-assistant-cdn branch August 20, 2026 09:26
Comment thread redocly.yaml
'sha256-v7ddZtWCUr5oF3kgrlEot4fG861CKDXUt0aTaNaIk6Q='
'sha256-+t5Z3fJi7uJxARWEzFEVaSRgtaAn0r97XkxpJNbQiK0=';
'sha256-+t5Z3fJi7uJxARWEzFEVaSRgtaAn0r97XkxpJNbQiK0='
'sha256-gOx3nRh8znDQR7T1VkI+fFXDgsNzf5enQqdi7NP11Vk=';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: Medium

The React hydration script will remain blocked on /editor because its route-specific block replaces the global CSP. Add the new hydration script hash to the /editor block to resolve the hydration error there as well.

Comment thread redocly.yaml
https://js.hs-analytics.net
https://js.hs-banner.com
https://cdn.jsdelivr.net
https://cdn.redocly.com

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: Low

Allowing the entire https://cdn.redocly.com domain in script-src is broader than necessary. Consider using a more restrictive path (e.g., https://cdn.redocly.com/ai-assistant/) to minimize the attack surface while still enabling the widget.

Comment thread redocly.yaml
'sha256-v7ddZtWCUr5oF3kgrlEot4fG861CKDXUt0aTaNaIk6Q='
'sha256-+t5Z3fJi7uJxARWEzFEVaSRgtaAn0r97XkxpJNbQiK0=';
'sha256-+t5Z3fJi7uJxARWEzFEVaSRgtaAn0r97XkxpJNbQiK0='
'sha256-gOx3nRh8znDQR7T1VkI+fFXDgsNzf5enQqdi7NP11Vk=';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Severity: Low

The hash for window.__staticRouterHydrationData may be brittle. Since hydration data typically varies by route, a single static hash in the global CSP might only resolve violations for specific pages, leaving hydration errors elsewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants