Files
bert.hausmans 5c42f27b26 fix: whitelist GlitchTip ingest host in CSP connect-src
PR-3 follow-up. Live smoke surfaced that the @sentry/vue SDK was
running correctly and emitting events, but Crewli's strict
connect-src directive blocked every POST at the browser layer. No
fallback — events evaporated silently with a CSP-violation log in
DevTools console only.

Updated locations (audited the CSP surface; only two locations actually
need the whitelist):

- apps/app/index.html — dev meta CSP, adds http://localhost:8200 to
  connect-src so local dev hits the docker-compose GlitchTip stack.
- deploy/nginx/csp-spa.conf — prod organizer SPA CSP, adds
  https://monitoring.hausdesign.nl to BOTH the report-only and enforce
  add_header lines so a future flip between modes can't silently break
  observability.

NOT updated (deviation from prompt):

- api/config/security.php — the API CSP is `default-src 'none';
  frame-ancestors 'none'` for JSON responses. Browsers don't enforce
  connect-src on JSON contexts (no document, no fetch origin). Adding
  connect-src would be semantically a no-op and confuse the deny-by-
  default policy.

Regression guard: tests/Feature/Security/CspConnectsToObservabilityTest.
Reads both the dev meta tag and the prod nginx conf directly (the SPA's
CSP is not Laravel-served, so $this->get() can't reach it). Apply-with-
revert verified: stashing both fixes makes both cases fail with a clear
"Refused to connect because it violates the following CSP directive"
hint; popping the stash restores green.

SECURITY_AUDIT.md A13-9 updated with a WS-7 follow-up note documenting
the GlitchTip whitelist as an explicit security control: outgoing
observability traffic restricted to a single known host.

Test count 1549 to 1551. Larastan + Pint clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 18:36:05 +02:00
..

Crewli Deployment — Security Configuration

Nginx Security Headers

Copy the configuration snippets to your Nginx server:

API (api.crewli.app)

server {
    server_name api.crewli.app;

    include /path/to/deploy/nginx/security-headers.conf;
    include /path/to/deploy/nginx/csp-api.conf;

    # ... rest of config
}

Organizer App (crewli.app)

server {
    server_name crewli.app;

    include /path/to/deploy/nginx/security-headers.conf;
    include /path/to/deploy/nginx/csp-spa.conf;

    # ... rest of config
}

Legacy portal redirect (portal.crewli.app)

Pre-WS-3 (April 2026), Crewli ran a separate portal SPA at portal.crewli.app. The dual-SPA was consolidated into a single workspace; the legacy host should redirect 301 → crewli.app:

server {
    server_name portal.crewli.app;
    listen 443 ssl;
    # ... TLS config from DirectAdmin / Let's Encrypt ...

    return 301 https://crewli.app$request_uri;
}

DNS retirement of portal.crewli.app is a separate operational task tracked outside this repo. Until DNS is repointed, this redirect handles any stale links.

CSP Rollout Process

  1. Start with Content-Security-Policy-Report-Only (uncomment in csp-spa.conf)
  2. Monitor browser console for CSP violations for 1-2 weeks
  3. Add any missing sources to the policy
  4. Switch to enforcing Content-Security-Policy
  5. Monitor for false positives after enforcement

DirectAdmin Integration

If using DirectAdmin with Nginx:

  1. Place the .conf files in /usr/local/directadmin/data/users/USERNAME/nginx.conf or use DirectAdmin's custom Nginx configuration feature
  2. Reload Nginx: service nginx reload
  3. Verify headers: curl -I https://crewli.app | grep -i security