diff --git a/nginx.conf b/nginx.conf
index 05258b42f..9774afca3 100644
--- a/nginx.conf
+++ b/nginx.conf
@@ -8,7 +8,7 @@ server {
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# Security headers
- add_header Content-Security-Policy "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; script-src 'self' https://*.jam.dev; worker-src 'self' blob:; frame-src 'self' https://accounts.google.com https://*.jam.dev; connect-src 'self' https://uziwdtkzofptihahfooo.supabase.co https://*.supabase.co https://api.openai.com https://api.anthropic.com https://generativelanguage.googleapis.com https://r.jina.ai https://s.jina.ai https://oauth2.googleapis.com https://www.googleapis.com https://*.ingest.sentry.io https://*.sentry.io https://eu.i.posthog.com https://*.posthog.com;" always;
+ add_header Content-Security-Policy "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; script-src 'self' https://*.jam.dev; worker-src 'self' blob:; frame-src 'self' https://accounts.google.com https://*.jam.dev; connect-src 'self' https://*.jam.dev https://uziwdtkzofptihahfooo.supabase.co https://*.supabase.co https://api.openai.com https://api.anthropic.com https://generativelanguage.googleapis.com https://r.jina.ai https://s.jina.ai https://oauth2.googleapis.com https://www.googleapis.com https://*.ingest.sentry.io https://*.sentry.io https://eu.i.posthog.com https://*.posthog.com;" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
diff --git a/src/lib/observability.ts b/src/lib/observability.ts
index 2b368ebe1..83f3f1400 100644
--- a/src/lib/observability.ts
+++ b/src/lib/observability.ts
@@ -102,7 +102,8 @@ export function initializeObservability(): void {
dsn: sentryDsn,
environment: import.meta.env.MODE,
ignoreErrors: [/^Synthetic observability verification$/],
- sendDefaultPii: false,
+ // No sendDefaultPii: deprecated, and Sentry ignores it whenever
+ // dataCollection is set. The block below is the only PII control.
beforeBreadcrumb: filterObservabilityBreadcrumb,
dataCollection: {
userInfo: false,
diff --git a/src/test/observability.test.ts b/src/test/observability.test.ts
index 62a13a20a..9f779e46e 100644
--- a/src/test/observability.test.ts
+++ b/src/test/observability.test.ts
@@ -210,7 +210,6 @@ describe("observability primitives", () => {
expect(sentryInitMock).toHaveBeenCalledWith(expect.objectContaining({
dsn: "https://public-test@sentry.example/1",
ignoreErrors: [/^Synthetic observability verification$/],
- sendDefaultPii: false,
beforeBreadcrumb: filterObservabilityBreadcrumb,
dataCollection: {
userInfo: false,
@@ -228,6 +227,9 @@ describe("observability primitives", () => {
replaysSessionSampleRate: 0,
replaysOnErrorSampleRate: 1,
}));
+ // Deprecated and ignored whenever dataCollection is set: passing it would
+ // read as a PII control that does nothing.
+ expect(sentryInitMock.mock.calls[0][0]).not.toHaveProperty("sendDefaultPii");
expect(browserTracingIntegrationMock).toHaveBeenCalledOnce();
expect(replayIntegrationMock).toHaveBeenCalledWith({
maskAllText: true,
diff --git a/src/test/vercel-deployment-config.test.ts b/src/test/vercel-deployment-config.test.ts
index c3d6ac90c..6cfe5266f 100644
--- a/src/test/vercel-deployment-config.test.ts
+++ b/src/test/vercel-deployment-config.test.ts
@@ -99,6 +99,8 @@ describe("Vercel frontend deployment configuration", () => {
expect(csp).toContain("script-src 'self' https://*.jam.dev");
expect(csp).toContain("frame-src 'self' https://accounts.google.com https://*.jam.dev");
+ // Loading the recorder is useless if it cannot upload the capture.
+ expect(csp).toContain("connect-src 'self' https://*.jam.dev");
expect(nginxCsp).toBe(csp);
expect(indexHtml).toContain('');
expect(indexHtml).not.toContain('');
diff --git a/vercel.json b/vercel.json
index f4d864b3c..343b031a9 100644
--- a/vercel.json
+++ b/vercel.json
@@ -15,7 +15,7 @@
"headers": [
{
"key": "Content-Security-Policy",
- "value": "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; script-src 'self' https://*.jam.dev; worker-src 'self' blob:; frame-src 'self' https://accounts.google.com https://*.jam.dev; connect-src 'self' https://uziwdtkzofptihahfooo.supabase.co https://*.supabase.co https://api.openai.com https://api.anthropic.com https://generativelanguage.googleapis.com https://r.jina.ai https://s.jina.ai https://oauth2.googleapis.com https://www.googleapis.com https://*.ingest.sentry.io https://*.sentry.io https://eu.i.posthog.com https://*.posthog.com;"
+ "value": "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; script-src 'self' https://*.jam.dev; worker-src 'self' blob:; frame-src 'self' https://accounts.google.com https://*.jam.dev; connect-src 'self' https://*.jam.dev https://uziwdtkzofptihahfooo.supabase.co https://*.supabase.co https://api.openai.com https://api.anthropic.com https://generativelanguage.googleapis.com https://r.jina.ai https://s.jina.ai https://oauth2.googleapis.com https://www.googleapis.com https://*.ingest.sentry.io https://*.sentry.io https://eu.i.posthog.com https://*.posthog.com;"
},
{
"key": "X-Frame-Options",