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>
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
- Start with
Content-Security-Policy-Report-Only(uncomment incsp-spa.conf) - Monitor browser console for CSP violations for 1-2 weeks
- Add any missing sources to the policy
- Switch to enforcing
Content-Security-Policy - Monitor for false positives after enforcement
DirectAdmin Integration
If using DirectAdmin with Nginx:
- Place the
.conffiles in/usr/local/directadmin/data/users/USERNAME/nginx.confor use DirectAdmin's custom Nginx configuration feature - Reload Nginx:
service nginx reload - Verify headers:
curl -I https://crewli.app | grep -i security