expect([200, 401, 500, 502]).toContain(res.status);
});
});
-
-describe("POST /openai/v1/chat/completions - Secrets Detection", () => {
- const opensshKey = `-----BEGIN OPENSSH PRIVATE KEY-----
-b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAlwAAAAdzc2gtcn
-NhAAAAAwEAAQAAAIEAyK8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v
-5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v
-5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v
------END OPENSSH PRIVATE KEY-----`;
-
- test("blocks request with OpenSSH private key when action=block", async () => {
- const res = await app.request("/openai/v1/chat/completions", {
- method: "POST",
- body: JSON.stringify({
- messages: [
- {
- role: "user",
- content: `Here is my SSH key: ${opensshKey}`,
- },
- ],
- model: "gpt-4",
- }),
- headers: { "Content-Type": "application/json" },
- });
-
- expect(res.status).toBe(400);
- const body = (await res.json()) as {
- error: { message: string; type: string; code: string };
- };
- expect(body.error.type).toBe("invalid_request_error");
- expect(body.error.message).toContain("Request blocked");
- expect(body.error.message).toContain("secret material");
- expect(body.error.code).toBe("secrets_detected");
-
- // Check headers - secret types are exposed via headers
- expect(res.headers.get("X-PasteGuard-Secrets-Detected")).toBe("true");
- expect(res.headers.get("X-PasteGuard-Secrets-Types")).toContain("OPENSSH_PRIVATE_KEY");
- });
-
- test("blocks request with PEM private key", async () => {
- const rsaKey = `-----BEGIN RSA PRIVATE KEY-----
-MIIEpAIBAAKCAQEAyK8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v
-5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v
-5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v5Q8v
------END RSA PRIVATE KEY-----`;
-
- const res = await app.request("/openai/v1/chat/completions", {
- method: "POST",
- body: JSON.stringify({
- messages: [
- {
- role: "user",
- content: `My RSA key: ${rsaKey}`,
- },
- ],
- model: "gpt-4",
- }),
- headers: { "Content-Type": "application/json" },
- });
-
- expect(res.status).toBe(400);
- const body = (await res.json()) as {
- error: { code: string };
- };
- expect(body.error.code).toBe("secrets_detected");
- // Secret types are in headers
- expect(res.headers.get("X-PasteGuard-Secrets-Detected")).toBe("true");
- expect(res.headers.get("X-PasteGuard-Secrets-Types")).toContain("PEM_PRIVATE_KEY");
- });
-
- test("allows request without secrets", async () => {
- const res = await app.request("/openai/v1/chat/completions", {
- method: "POST",
- body: JSON.stringify({
- messages: [
- {
- role: "user",
- content: "This is just normal text with no secrets",
- },
- ],
- model: "gpt-4",
- }),
- headers: { "Content-Type": "application/json" },
- });
-
- // Should not be blocked for secrets (may fail for other reasons like missing auth)
- // If it's 400, check it's not a secrets_detected error
- if (res.status === 400) {
- const body = (await res.json()) as { error?: { code?: string } };
- expect(body.error?.code).not.toBe("secrets_detected");
- }
- // Should not have secrets detection headers
- expect(res.headers.get("X-PasteGuard-Secrets-Detected")).toBeNull();
- });
-
- test("does not set secrets headers when no secrets detected", async () => {
- const res = await app.request("/openai/v1/chat/completions", {
- method: "POST",
- body: JSON.stringify({
- messages: [
- {
- role: "user",
- content: "Normal message without any private keys",
- },
- ],
- model: "gpt-4",
- }),
- headers: { "Content-Type": "application/json" },
- });
-
- // Should not have secrets headers
- expect(res.headers.get("X-PasteGuard-Secrets-Detected")).toBeNull();
- expect(res.headers.get("X-PasteGuard-Secrets-Types")).toBeNull();
- });
-
- // Note: Tests for API_KEY_OPENAI, JWT_TOKEN, etc. require those entity types
- // to be enabled in config. Detection is thoroughly tested in detect.test.ts.
- // Proxy blocking behavior is tested above with private keys (default entities).
-});