Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/cli/src/shared/telemetry/tracing.layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class ExportableSpan implements Tracer.Span {
}

attribute(key: string, value: unknown): void {
if (key.endsWith(".header.apikey")) return;
this.attributes.set(key, value);
}

Expand Down
27 changes: 27 additions & 0 deletions apps/cli/src/shared/telemetry/tracing.layer.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,33 @@ describe("tracingLayer – span behaviour", () => {
);
});

it.live("does not write API keys to trace files", () => {
const home = makeTempDir();
const tracesDir = path.join(home, ".supabase", "traces");
const secretKey = `sb_secret_${"a".repeat(40)}`;
return Effect.gen(function* () {
const tracer = yield* Tracer.Tracer;
const span = tracer.span(makeSpanOptions());
span.attribute("http.request.header.apikey", secretKey);
span.end(BigInt(Date.now() + 100) * 1_000_000n, Exit.void);
}).pipe(
Effect.provide(buildTracingLayer({ home })),
Effect.ensuring(
Effect.sync(() => {
try {
const traceFile = readdirSync(tracesDir).find((file) => file.endsWith(".ndjson"));
expect(traceFile).toBeDefined();
const trace = readFileSync(path.join(tracesDir, traceFile!), "utf8");
expect(trace).not.toContain(secretKey);
expect(trace).not.toContain("http.request.header.apikey");
} finally {
rmSync(home, { recursive: true, force: true });
}
}),
),
);
});

it.live("span end does NOT export to NDJSON when SUPABASE_TELEMETRY_DISABLED=1", () => {
const home = makeTempDir();
const configDir = path.join(home, ".supabase");
Expand Down
Loading