Repository navigation
Nova: Infrastructure Hardening and Asset Optimization - #272
alehar9320 wants to merge 4 commits into
Conversation
- Added security headers (Referrer-Policy, Permissions-Policy) to API responses. - Implemented site-wide security headers and immutable asset caching for `/_astro/*` via `public/_headers`. - Updated .Nova/devops.md journal. Co-authored-by: alehar9320 <5390430+alehar9320@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
me | a4b0fcb | Commit Preview URL Branch Preview URL |
Jun 12 2026, 07:56 PM |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughAdds Referrer-Policy and Permissions-Policy to the chat API JSON and SSE responses, configures site-wide security headers and immutable one-year caching for ChangesSecurity Hardening & Caching
Possibly related PRs
Suggested labels
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed due to a network error. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Bundle ReportBundle size has no change ✅ Affected Assets, Files, and Routes:view changes for bundle: molecular-mars-esmAssets Changed:
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/pages/api/chat.ts (1)
105-114:⚠️ Potential issue | 🟡 MinorExtract shared security headers for
chatstreaming + add missing header assertionsIn
src/pages/api/chat.ts, the streamingheadersobject duplicates the security headers already injsonHeaders(onlycontent-typeandCache-Controldiffer), which increases maintenance overhead. Also,src/__tests__/chat-api.test.tscurrently asserts several streaming security headers but does not assertReferrer-PolicyorPermissions-Policy.♻️ Proposed refactor to extract shared headers
+const securityHeaders = { + 'X-Content-Type-Options': 'nosniff', + 'X-Frame-Options': 'DENY', + 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', + 'Content-Security-Policy': "default-src 'none'; frame-ancestors 'none';", + 'Referrer-Policy': 'strict-origin-when-cross-origin', + 'Permissions-Policy': 'accelerometer=(), camera=(), geolocation=(), microphone=()', +} as const; + const jsonHeaders = { 'content-type': 'application/json', - 'X-Content-Type-Options': 'nosniff', - 'X-Frame-Options': 'DENY', - 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', - 'Content-Security-Policy': "default-src 'none'; frame-ancestors 'none';", - 'Referrer-Policy': 'strict-origin-when-cross-origin', - 'Permissions-Policy': 'accelerometer=(), camera=(), geolocation=(), microphone=()', + ...securityHeaders, } as const;Then update the streaming response:
return new Response(stream, { headers: { 'content-type': 'text/event-stream', 'Cache-Control': 'no-store', - 'X-Content-Type-Options': 'nosniff', - 'X-Frame-Options': 'DENY', - 'Strict-Transport-Security': 'max-age=31536000; includeSubDomains', - 'Content-Security-Policy': "default-src 'none'; frame-ancestors 'none';", - 'Referrer-Policy': 'strict-origin-when-cross-origin', - 'Permissions-Policy': 'accelerometer=(), camera=(), geolocation=(), microphone=()', + ...securityHeaders, }, });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/pages/api/chat.ts` around lines 105 - 114, Extract the common security headers into a shared constant (e.g., jsonHeaders) and reuse it when building the streaming response headers in src/pages/api/chat.ts so you only override 'content-type' and 'Cache-Control' for the SSE case (update the streaming `headers` to merge or spread from `jsonHeaders`); then update src/__tests__/chat-api.test.ts to add assertions that the streaming response includes 'Referrer-Policy' and 'Permissions-Policy' alongside the existing header checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@public/_headers`:
- Around line 1-6: public/_headers lacks a site-wide Content-Security-Policy
while the codebase contains inline scripts/styles (e.g.,
src/layouts/BaseLayout.astro and pages using "script is:inline" and inline style
attributes), so either document the omission or implement a nonce/hash-based CSP
and refactor inline code: choose one—(A) add a clear comment in public/_headers
that CSP is intentionally omitted for compatibility with inline scripts and list
files affected (BaseLayout.astro, src/pages/*.astro,
src/pages/experimental/manifesto.astro) so reviewers know this is deliberate, or
(B) add a CSP entry in public/_headers and refactor to support it by generating
nonces server-side (aligning with src/pages/api/chat.ts pattern), inject the
nonce into BaseLayout.astro and all inline <script> tags as nonce attributes (or
replace inline scripts/styles with external files and/or compute and use sha256
hashes), and ensure server responses set the same nonce/header for pages and API
endpoints that serve HTML.
---
Outside diff comments:
In `@src/pages/api/chat.ts`:
- Around line 105-114: Extract the common security headers into a shared
constant (e.g., jsonHeaders) and reuse it when building the streaming response
headers in src/pages/api/chat.ts so you only override 'content-type' and
'Cache-Control' for the SSE case (update the streaming `headers` to merge or
spread from `jsonHeaders`); then update src/__tests__/chat-api.test.ts to add
assertions that the streaming response includes 'Referrer-Policy' and
'Permissions-Policy' alongside the existing header checks.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 90c98037-1bee-4c0a-9b0d-bbc02d288857
📒 Files selected for processing (3)
.Nova/devops.mdpublic/_headerssrc/pages/api/chat.ts
| /* | ||
| X-Content-Type-Options: nosniff | ||
| X-Frame-Options: DENY | ||
| Strict-Transport-Security: max-age=31536000; includeSubDomains | ||
| Referrer-Policy: strict-origin-when-cross-origin | ||
| Permissions-Policy: accelerometer=(), camera=(), geolocation=(), microphone=() |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Check for inline scripts/styles in Astro components and HTML that might conflict with strict CSP
echo "=== Checking for inline script tags ==="
rg -n "<script(?!\\s+src=)" --type=astro --type=html -g '!node_modules' -g '!dist' -C2
echo -e "\n=== Checking for inline style attributes ==="
rg -n "\\sstyle=" --type=astro --type=html -g '!node_modules' -g '!dist' -C1
echo -e "\n=== Checking for inline event handlers ==="
rg -n "\\son[a-z]+=" --type=astro --type=html -g '!node_modules' -g '!dist' -C1Repository: alehar9320/astro-cloudflare-personal-website
Length of output: 525
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Search for existing Content-Security-Policy in repo ==="
rg -n "Content-Security-Policy" -S . || true
echo
echo "=== Inspect public/_headers (first 50 lines) ==="
if [ -f public/_headers ]; then
nl -ba public/_headers | head -n 50
else
echo "Missing: public/_headers"
fi
echo
echo "=== Inspect src/pages/api/chat.ts headers block (best-effort) ==="
if [ -f src/pages/api/chat.ts ]; then
rg -n "Content-Security-Policy|setHeader|headers" -S src/pages/api/chat.ts || true
nl -ba src/pages/api/chat.ts | head -n 220
else
echo "Missing: src/pages/api/chat.ts"
fi
echo
echo "=== Checking for inline script tags (no src) in .astro/.html ==="
# Use --pcre2 for lookahead regex
rg --pcre2 -n "<script(?!\\s+src=)[^>]*>" -g'*.astro' -g'*.html' -g'!**/node_modules/**' -g'!**/dist/**' -C1 . || true
echo
echo "=== Checking for inline style attributes (style=) in .astro/.html ==="
rg -n "\\sstyle=" -g'*.astro' -g'*.html' -g'!**/node_modules/**' -g'!**/dist/**' -C1 . || true
echo
echo "=== Checking for inline event handlers (on*) in .astro/.html ==="
rg -n "\\son[a-z]+=" -g'*.astro' -g'!**/node_modules/**' -g'!**/dist/**' -g'*.astro' -g'*.html' -C1 . || trueRepository: alehar9320/astro-cloudflare-personal-website
Length of output: 676
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== Search for existing Content-Security-Policy in repo ==="
rg -n "Content-Security-Policy" -S . || true
echo
echo "=== public/_headers (show entire file) ==="
if [ -f public/_headers ]; then
echo "--- public/_headers ---"
cat -n public/_headers
else
echo "Missing: public/_headers"
fi
echo
echo "=== Inspect src/pages/api/chat.ts for CSP and header setup ==="
if [ -f src/pages/api/chat.ts ]; then
echo "--- Relevant lines (CSP + header handling) ---"
rg -n "Content-Security-Policy|setHeader|headers" -S src/pages/api/chat.ts || true
echo
echo "--- First 160 lines ---"
head -n 160 src/pages/api/chat.ts | cat -n
else
echo "Missing: src/pages/api/chat.ts"
fi
echo
echo "=== Checking for inline script tags (no src) in .astro/.html ==="
rg --pcre2 -n "<script(?!\\s+src=)[^>]*>" -g'*.astro' -g'*.html' -g'!**/node_modules/**' -g'!**/dist/**' -C1 . || true
echo
echo "=== Checking for inline style attributes (style=) in .astro/.html ==="
rg -n "\\sstyle=" -g'*.astro' -g'*.html' -g'!**/node_modules/**' -g'!**/dist/**' -C1 . || true
echo
echo "=== Checking for inline event handlers (on*) in .astro/.html ==="
rg -n "\\son[a-z]+=" -g'*.astro' -g'*.html' -g'!**/node_modules/**' -g'!**/dist/**' -C1 . || trueRepository: alehar9320/astro-cloudflare-personal-website
Length of output: 10600
Document CSP omission (or implement nonce/hash-based CSP) because inline scripts/styles exist
public/_headers currently omits Content-Security-Policy; CSP is only set on the chat API responses (src/pages/api/chat.ts).
Repo pages/layouts contain multiple inline <script> blocks (e.g., src/layouts/BaseLayout.astro, various src/pages/*.astro using script is:inline / <script>...</script>) and inline style="..." usage (e.g., src/pages/experimental/manifesto.astro), so a strict site-wide CSP would break unless you add nonces/hashes or refactor inline code.
Either document that CSP is intentionally omitted for compatibility, or add a CSP to public/_headers using nonces/hashes (and refactor where needed) before tightening defaults.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@public/_headers` around lines 1 - 6, public/_headers lacks a site-wide
Content-Security-Policy while the codebase contains inline scripts/styles (e.g.,
src/layouts/BaseLayout.astro and pages using "script is:inline" and inline style
attributes), so either document the omission or implement a nonce/hash-based CSP
and refactor inline code: choose one—(A) add a clear comment in public/_headers
that CSP is intentionally omitted for compatibility with inline scripts and list
files affected (BaseLayout.astro, src/pages/*.astro,
src/pages/experimental/manifesto.astro) so reviewers know this is deliberate, or
(B) add a CSP entry in public/_headers and refactor to support it by generating
nonces server-side (aligning with src/pages/api/chat.ts pattern), inject the
nonce into BaseLayout.astro and all inline <script> tags as nonce attributes (or
replace inline scripts/styles with external files and/or compute and use sha256
hashes), and ensure server responses set the same nonce/header for pages and API
endpoints that serve HTML.
|
Tick the box to add this pull request to the merge queue (same as
|
|
Stale agent-codename PR. Closed to clear the queue after hire-path and Astro 7 landed on main. Reopen only if we explicitly pick this work up against current main. |
Implemented a set of atomic infrastructure optimizations focused on security hardening and performance improvement.
Key changes:
Referrer-PolicyandPermissions-Policyto the chat API insrc/pages/api/chat.tsto align with modern security best practices.public/_headersto ensure consistent security headers across the entire Cloudflare Pages site.max-age=31536000, immutable) for fingerprinted Astro assets in/_astro/*to improve performance and reduce bandwidth..Nova/devops.mdjournal.These changes were verified through linting, type checking, and unit tests.
PR created automatically by Jules for task 13192040115046100703 started by @alehar9320
Summary by CodeRabbit
Security & Infrastructure
Documentation