# Cloudflare Pages headers. Applied at the edge — no app code involved.
# Docs: https://developers.cloudflare.com/pages/configuration/headers/

# Hashed build assets never change for a given URL — cache them forever.
/assets/*
  Cache-Control: public, max-age=31536000, immutable

# The HTML shells must always revalidate so a new deploy is picked up instantly.
# (/index.html is the landing page; /app/index.html is the app shell — 2026-07-07 layout.)
/index.html
  Cache-Control: no-cache
/app/index.html
  Cache-Control: no-cache
# Baseline security headers for every hosted page. The marketing site intentionally has no CSP:
# it currently uses reviewed inline reveal scripts. Applying the app policy globally makes that
# content transparent when the browser correctly blocks those scripts (2026-08-03 incident).
/*
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin
  X-Frame-Options: SAMEORIGIN
  Permissions-Policy: geolocation=(), microphone=(), camera=()
  Strict-Transport-Security: max-age=31536000

# The product shell is external-module-only, so it can keep the strict policy. Provider calls may
# reach HTTPS origins, local Ollama may use loopback, arbitrary user media may render, and the APS
# renderer remains isolated in its separate frame.
/app/*
  Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; form-action 'self'; frame-ancestors 'self'; script-src 'self' 'wasm-unsafe-eval' https://cdn.jsdelivr.net https://static.cloudflareinsights.com https://challenges.cloudflare.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' data: https://fonts.gstatic.com https://fonts.autodesk.com; connect-src 'self' https: wss: http://localhost:* http://127.0.0.1:* ws://localhost:* ws://127.0.0.1:*; img-src 'self' data: blob: https: http:; media-src 'self' data: blob: https: http:; worker-src 'self' blob:; child-src 'self' blob: https://flowgraph-aps-viewer.pages.dev https://challenges.cloudflare.com; frame-src 'self' https://flowgraph-aps-viewer.pages.dev https://challenges.cloudflare.com https://developer.api.autodesk.com; manifest-src 'self'; upgrade-insecure-requests

# This exception must follow the global rule: Workers Static Assets combines every matching
# block in declaration order, and the cross-site host must be frameable only
# by the explicit parent origins named in its CSP.
/aps-viewer-host*
  Cache-Control: no-cache
  Origin-Agent-Cluster: ?1
  ! X-Frame-Options
  Content-Security-Policy: default-src 'none'; script-src 'self' 'unsafe-eval' blob: https://developer.api.autodesk.com https://cdn.derivative.autodesk.com; worker-src blob: https://developer.api.autodesk.com https://cdn.derivative.autodesk.com; style-src 'self' 'unsafe-inline' https://developer.api.autodesk.com; connect-src https://developer.api.autodesk.com https://cdn.derivative.autodesk.com https://*.autodesk.com https://*.autodesk.io wss://cdn.derivative.autodesk.com wss://*.autodesk.com; img-src data: blob: https://developer.api.autodesk.com https://cdn.derivative.autodesk.com https://*.autodesk.com; font-src data: https://fonts.autodesk.com https://developer.api.autodesk.com; frame-ancestors https://flow-graph.com http://localhost:* http://127.0.0.1:*
