Skip to content

docs: record the CSP-enforced production smoke re-run - #15

Merged
LuanTrindade95 merged 1 commit into
mainfrom
docs/c7-smoke-recheck
Sep 23, 2026
Merged

LuanTrindade95 merged 1 commit into
mainfrom
docs/c7-smoke-recheck

Conversation

@LuanTrindade95

Copy link
Copy Markdown
Owner

Validation-only round, brain-only diff. No product code, Compose, Dockerfile or nginx config was touched.

Why

The earlier production hydrated-browser smoke ran on 29a7881. Content-Security-Policy (ADR-30), the optional bearer resolver (ADR-31) and correlation-ID telemetry (ADR-29) landed afterwards and changed frontend/src/server.ts and the backend middleware stack, so that proof no longer covered the shipped code. This round re-ran it on c4eee46 and added CSP to what has to be proven.

What was proven

Two independent passes, each with its own public IP and ports, published on that IP only so the default origin answered connection refused.

  • Canonical, og:url, og:image and JSON-LD carry the configured public origin on the landing, plugin and command pages. Prerendered routes go through the same renderer, with CSP, nonce and Cache-Control: no-store.
  • /runtime-config.js serves the configured values.
  • After a proven hydration barrier — typed search producing a DOM result, routerLink navigation with no new document request — every captured request landed on a configured origin.
  • connect-src carries the configured API and Reverb origins and no defaults, because the header is built from the same resolveRuntimeBrowserConfig() that serves the runtime config. The style-src nonce changes per response.
  • CSP is enforced, not merely announced: browser probes recorded disposition: enforce against an inline style without nonce, an inline script, a foreign script and a foreign fetch, while a style carrying the header nonce applied.
  • The websocket reaches the configured Reverb host under CSP and gets pusher:connection_established.
  • A forged Host, and a forged X-Forwarded-Host with X-Forwarded-Proto: https, never reach canonical or metadata.
  • POST /api/v1/auth/dev-login answers 403 auth.dev_login_disabled before request validation.

Correction to the record

The execution pass blamed a search 500 (Attribute community is not filterable) on direct SQL inserts bypassing the Scout observers. The audit disproved that: a dataset built entirely through Eloquent, with observers and Horizon active, still produced an index with empty filterableAttributes and the same 500.

The real fact, now recorded: no code path applies Meilisearch index settings. Only php artisan scout:sync-index-settings does, which is the documented README.md step. Not a regression, but the mechanism first reported was wrong and would have entered the brain as a false fact.

Findings carried forward

  • Seeding stays broken in the production image (Priority 13), symptom reconfirmed.
  • Access-Control-Allow-Origin: * on every API response, including errors and a forged Origin.
  • Duplicated security headers from nginx and the SecurityHeaders middleware.
  • Whether index settings should be applied by code, or the missing-settings failure surfaced explicitly instead of a generic 500.

Gates

  • Production Docker runtime gate: VALIDATED in both passes.
  • db:seed in the production image: FAILED, for the known Priority 13 reason.
  • Backend and frontend unit, lint and build gates: PENDING — no code changed.

Evidence: brain/handoffs/2026-09-23-production-smoke-csp-recheck.md.

🤖 Generated with Claude Code

Re-run the hydrated-browser smoke on c4eee46, where Content-Security-
Policy is enforced, and record what it proved: the browser stays on the
configured origin, CSP is derived from the same runtime config and bites
in the browser, and the Reverb websocket connects under it.

Correct the record on the search 500: it was not direct SQL bypassing the
Scout observers. No code path applies Meilisearch index settings, so
filterableAttributes stays empty until scout:sync-index-settings runs,
even through the normal ingestion path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@LuanTrindade95
LuanTrindade95 merged commit c10752a into main Sep 23, 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