Skip to content

Enable the CSP (security.csp) in docs and courses, remove what it would block - #12

Merged
casoon merged 2 commits into
mainfrom
fix/csp-security-config
Oct 2, 2026
Merged

casoon merged 2 commits into
mainfrom
fix/csp-security-config

Conversation

@casoon

@casoon casoon commented Oct 1, 2026

Copy link
Copy Markdown
Owner

What was wrong: both apps/docs and apps/courses had csp: { algorithm: 'SHA-256' } at the top level of astro.config.mjs. Astro 6/7 only reads it under security.csp, so the key was silently ignored and neither site shipped a CSP.

What changed

  • security.csp in both configs, with https://fonts.googleapis.com as an extra style source (AppShell loads Inter from Google Fonts).
  • Shiki code blocks: shikiStyleToClass transformer (packages/styles/src/shiki.mjs) turns the inline token styles into classes defined in shiki.css (github-dark), imported by prose.css.
  • Progress bars (ProgressBar, CourseCard, LessonNav): data-width, applied via CSSOM from a bundled script in AppShell; TotalProgress starts at w-0. DocsHero status dot: box-shadow moved to a class.
  • Astro does not hash is:inline/define:vars scripts in the body, so QuizToggle, Tabs, Hint, Quiz and ChatWidget now use bundled scripts (data via data attributes, event delegation / astro:page-load). The stored quiz visibility is applied in AppShell's head script (hashed), so hidden quizzes stay hidden from the first paint.

How tested

  • pnpm check, pnpm type-check (0 errors/warnings/hints), pnpm test (67 tests pass), pnpm build:docs, pnpm build:courses
  • Scan of all built pages (16 + 16): CSP meta on every page, no style attributes, no inline handlers; only external resource is the allowed Google Fonts stylesheet
  • Headless Chromium, every page at 1280 and 390 px: 0 CSP violations, 0 page errors
  • Computed styles of all formerly inline-styled elements vs. a build of main: 2,556 elements, 0 differences
  • Functional: tabs, hint, quiz check, quiz toggle (incl. persistence across reload), progress bars, client-router navigation; chat widget with PUBLIC_CHAT_ENDPOINT set (opens, posts to the endpoint, shows the error)

Known remaining message: on ClientRouter navigations Astro's router inserts <script src="data:application/javascript,"> as a sentinel, which the CSP blocks (console message only; navigation and scripts work).

Not deployed yet.

casoon added 2 commits October 1, 2026 20:03
- Shiki code blocks: a transformer turns the inline styles into classes
  (packages/styles/src/shiki.{mjs,css}).
- Progress bars: width via data-width, applied from a bundled script in
  AppShell; DocsHero status dot: box-shadow moved to a class.
- QuizToggle, Tabs, Hint, Quiz and ChatWidget: is:inline/define:vars
  scripts become bundled scripts (Astro does not hash body inline
  scripts); data moves to data attributes. The stored quiz visibility is
  applied by AppShell's head script, so it holds before first paint.
Astro only reads csp inside security; the top-level key was silently
ignored, so both sites shipped without a CSP. Google Fonts is allowed as
a style source for AppShell's Inter stylesheet.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying knowledge-core with  Cloudflare Pages  Cloudflare Pages

Latest commit: d60cb77
Status: ✅  Deploy successful!
Preview URL: https://773bb8e4.knowledge-core.pages.dev
Branch Preview URL: https://fix-csp-security-config.knowledge-core.pages.dev

View logs

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying knowledge-core-docs with  Cloudflare Pages  Cloudflare Pages

Latest commit: d60cb77
Status: ✅  Deploy successful!
Preview URL: https://81c1ff6d.knowledge-core-docs.pages.dev
Branch Preview URL: https://fix-csp-security-config.knowledge-core-docs.pages.dev

View logs

@casoon
casoon merged commit b4d0344 into main Oct 2, 2026
4 checks passed
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.

1 participant