diff --git a/studio/backend/main.py b/studio/backend/main.py
index 19202efcb1..186422bc7f 100644
--- a/studio/backend/main.py
+++ b/studio/backend/main.py
@@ -328,8 +328,15 @@ def _build_csp(script_nonce: "str | None" = None) -> str:
f"{script_src}; "
"font-src 'self' data:; "
# Restrict iframe sources to same-origin only. The assistant
- # HTML/SVG previews use srcdoc (no URL involved) and inherit this
- # CSP, so this also bounds what the preview iframe can do.
+ # HTML/SVG previews use srcdoc (no URL fetch), so allowing
+ # data: / blob: here would not unlock interactive scripts
+ # anyway -- Chromium inherits the embedder CSP for srcdoc,
+ # data:, AND blob: iframes per HTML / CSP3, so the only way
+ # to escape ``script-src 'self'`` for the preview would be a
+ # same-origin backend route serving with overriding response
+ # CSP headers. Tracked as a follow-up; for now the explicit
+ # ``'self'`` setting leaves a visible directive that grep
+ # picks up if a future change tries to relax it.
"frame-src 'self'; "
"frame-ancestors 'none'; "
"form-action 'self'; "
diff --git a/studio/backend/tests/test_middleware.py b/studio/backend/tests/test_middleware.py
index f2a216b9e5..7d6712e181 100644
--- a/studio/backend/tests/test_middleware.py
+++ b/studio/backend/tests/test_middleware.py
@@ -197,11 +197,12 @@ class TestSecurityHeadersMiddleware:
assert "script-src 'self' 'nonce-XYZ';" in nonced
def test_frame_src_is_explicitly_self_only(self, main_module):
- # The assistant HTML/SVG preview iframe uses srcdoc (no URL fetch),
- # so frame-src does not need to permit data: / blob:. Pinning to
- # 'self' explicitly is the strictest setting CSP allows here, and
- # leaves a visible directive a reviewer can grep for if a future
- # change tries to relax it without an audit.
+ # The assistant HTML/SVG preview iframe uses srcdoc (no URL
+ # fetch). Allowing data: / blob: here would not unlock inline
+ # scripts anyway -- Chromium inherits the embedder CSP for
+ # srcdoc, data:, AND blob: iframes per HTML / CSP3. The
+ # explicit 'self' here leaves a visible directive any future
+ # change has to deliberately broaden.
csp = main_module._build_csp()
frame_src = next(
chunk.strip()
diff --git a/studio/frontend/src/components/assistant-ui/__tests__/html-svg-renderer.test.tsx b/studio/frontend/src/components/assistant-ui/__tests__/html-svg-renderer.test.tsx
index 6cbb635d1b..a1463ed9d2 100644
--- a/studio/frontend/src/components/assistant-ui/__tests__/html-svg-renderer.test.tsx
+++ b/studio/frontend/src/components/assistant-ui/__tests__/html-svg-renderer.test.tsx
@@ -39,11 +39,14 @@ describe("HtmlSvgRenderer", () => {
expect(sandboxTokens).toContain("allow-popups-to-escape-sandbox");
expect(sandbox).not.toContain("allow-same-origin");
expect(sandbox).not.toContain("allow-top-navigation");
- // srcdoc carries the assistant HTML plus a defense-in-depth meta CSP
- // that adds ``connect-src 'none'`` and ``frame-src 'none'`` on top of
- // the inherited host CSP. Inline ``';
-// Meta-CSP enforced INSIDE the srcdoc iframe. The iframe inherits the host
-// Studio CSP (every srcdoc / data: / blob: scheme does, per CSP3 § Initialize
-// document CSP), so the host's ``script-src 'self'`` already blocks inline
-//