Records the functional design for the two remaining application units, before any of their code exists. Security headers have to come from the application, because relying on nginx or IIS configuration is exactly what this deployment model rules out. Strict applies to /admin, /api/v1 and /health; a relaxed policy applies to the public website, which this repository does not author. The strict policy needs style-src 'unsafe-inline'. That is not a shortcut: Radix positions dropdowns and dialogs with inline style attributes recalculated per click and scroll position, and CSP nonces apply only to style elements, never to style attributes. No nonce- or hash-based variant leaves the admin UI working. The exception is bounded to styles — script-src stays closed, which is where XSS actually lives. The website's policy is enforcing rather than absent, so every HTML-serving path carries a CSP and no exception has to be recorded. It still blocks external script origins, so it remains a real boundary. HSTS is skipped in development: browsers remember it per host and localhost is shared with unrelated projects. Every other header applies locally, so a CSP violation surfaces while developing. For observability, browser error reports tunnel through the API rather than going to Sentry directly. Ad blockers block Sentry domains, which loses errors precisely for the users most likely to have browser oddities. The tunnel forwards only to the host derived from the configured DSN — a caller-supplied destination would turn an anonymous endpoint into a request-forgery primitive. Two consequences of the chosen options are recorded rather than left implicit: Enabling SendDefaultPii attaches request headers, and this application carries two standing credentials in them. Besides the refreshToken cookie, X-Master-Api-Key would have been sent to a third party on every error raised during a master/slave call. The scrub list removes the whole Cookie header, Authorization, X-Master-Api-Key and the request body. Console logging at Information plus structured logging to Sentry would, taken literally, mean one Sentry event per request — exhausting the free plan within hours and burying real errors in request noise. The thresholds are split: console keeps Information, Sentry takes warnings and above as events with Information as breadcrumbs, so every event arrives carrying the trail that led to it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HHoJpxYXzHACSQguHrC5fw
2.0 KiB
2.0 KiB
Functional Design Plan — U3 HTTP Security Headers & CSP
Unit: U3 HTTP Security Headers & CSP Round: R2 (with U4 Observability) Requirements: FR-18 Components: C-01, C-02, C-03, U3 portion of C-16
Scope boundary: this stage designs behaviour — which headers apply to which response, what each policy permits, and what happens in edge cases. The pattern decisions (how the policy is composed, how the configuration surface is shaped) belong to this unit's NFR Design, which follows.
Step 1: Analyze unit context
- Read the U3 definition from
unit-of-work.md - Read FR-18 and D-31 from
requirements.md - Read the per-header scoping decision (FU1 = A) and the configuration split (FU2 = A)
- Confirm the settled path layout from U1 as delivered
Step 2: Design header applicability
- Define which headers apply to all responses and which to HTML only
- Define behaviour for redirects,
304 Not Modifiedand error responses - Define behaviour when a header is already present
- Define whether headers apply in Development — see Question 3
Step 3: Design the two policies
- Define what the
Strictpolicy permits for/adminand/api/v1— see Question 1 - Define what the
Relaxedpolicy permits for the public website — see Question 2 - Define how the Umami and Sentry origins enter the policy
- Define behaviour for the placeholder page
Step 4: Design failure behaviour
- Define startup behaviour on an unknown policy name
- Define behaviour when no origins are configured
- Confirm header application never throws into the response path
Step 5: Define business rules
- Enumerate applicability rules
- Enumerate policy-content rules
- Identify error and edge-case scenarios
Step 6: Generate artifacts
- Generate
business-logic-model.md - Generate
business-rules.md - Generate
domain-entities.md - Validate all diagrams against the Mermaid standards
- Verify Security Baseline compliance for this unit's design