function extractEntities(
countersBefore: Record<string, number>,
context: PlaceholderContext,
- isSecret: boolean,
): MaskEntity[] {
const entities: MaskEntity[] = [];
const startCount = countersBefore[type] || 0;
// Add entities for each new placeholder created
for (let i = startCount + 1; i <= count; i++) {
- // Build placeholder directly using known format
- const placeholder = isSecret ? `[[SECRET_MASKED_${type}_${i}]]` : `[[${type}_${i}]]`;
+ // Build placeholder directly using known format (same for PII and secrets)
+ const placeholder = `[[${type}_${i}]]`;
if (context.mapping[placeholder]) {
entities.push({ type, placeholder });
const countersBefore = { ...context.counters };
const piiResult = maskPII(maskedText, filteredEntities, context);
maskedText = piiResult.masked;
- allEntities.push(...extractEntities(countersBefore, piiResult.context, false));
+ allEntities.push(...extractEntities(countersBefore, piiResult.context));
// Collect unique entity types for logging
for (const entity of filteredEntities) {
const countersBefore = { ...context.counters };
const secretsMaskResult = maskSecrets(maskedText, secretsResult.locations, context);
maskedText = secretsMaskResult.masked;
- allEntities.push(...extractEntities(countersBefore, secretsMaskResult.context, true));
+ allEntities.push(...extractEntities(countersBefore, secretsMaskResult.context));
// Collect unique secret types for logging
for (const match of secretsResult.matches) {
}
describe("secrets placeholder format", () => {
- test("uses [[SECRET_MASKED_TYPE_N]] format", () => {
+ test("uses [[TYPE_N]] format", () => {
const text = `My API key is ${sampleSecret}`;
const locations: SecretLocation[] = [
{ start: 14, end: 14 + sampleSecret.length, type: "API_KEY_OPENAI" },
];
const result = maskSecrets(text, locations);
- expect(result.masked).toBe("My API key is [[SECRET_MASKED_API_KEY_OPENAI_1]]");
+ expect(result.masked).toBe("My API key is [[API_KEY_OPENAI_1]]");
});
test("increments counter per secret type", () => {
];
const result = maskSecrets(text, locations);
- expect(result.masked).toContain("[[SECRET_MASKED_API_KEY_OPENAI_1]]");
- expect(result.masked).toContain("[[SECRET_MASKED_API_KEY_OPENAI_2]]");
+ expect(result.masked).toContain("[[API_KEY_OPENAI_1]]");
+ expect(result.masked).toContain("[[API_KEY_OPENAI_2]]");
});
test("tracks different secret types separately", () => {
];
const result = maskSecrets(text, locations);
- expect(result.masked).toContain("[[SECRET_MASKED_API_KEY_OPENAI_1]]");
- expect(result.masked).toContain("[[SECRET_MASKED_API_KEY_AWS_1]]");
+ expect(result.masked).toContain("[[API_KEY_OPENAI_1]]");
+ expect(result.masked).toContain("[[API_KEY_AWS_1]]");
});
});
const { masked, context } = maskRequest(request, detection, openaiExtractor);
- expect(masked.messages[0].content).toContain("[[SECRET_MASKED_API_KEY_OPENAI_1]]");
+ expect(masked.messages[0].content).toContain("[[API_KEY_OPENAI_1]]");
expect(masked.messages[0].content).not.toContain(sampleSecret);
expect(masked.messages[1].content).toBe("I'll help you with that.");
expect(Object.keys(context.mapping)).toHaveLength(1);
const { masked, context } = maskRequest(request, detection, openaiExtractor);
- expect(masked.messages[0].content).toBe("Key1: [[SECRET_MASKED_API_KEY_OPENAI_1]]");
- expect(masked.messages[1].content).toBe("Key2: [[SECRET_MASKED_API_KEY_OPENAI_1]]");
+ expect(masked.messages[0].content).toBe("Key1: [[API_KEY_OPENAI_1]]");
+ expect(masked.messages[1].content).toBe("Key2: [[API_KEY_OPENAI_1]]");
expect(Object.keys(context.mapping)).toHaveLength(1);
});
const { masked } = maskRequest(request, detection, openaiExtractor);
const content = masked.messages[0].content as Array<{ type: string; text?: string }>;
- expect(content[0].text).toBe("Key: [[SECRET_MASKED_API_KEY_OPENAI_1]]");
+ expect(content[0].text).toBe("Key: [[API_KEY_OPENAI_1]]");
expect(content[1].type).toBe("image_url");
});
});
describe("streaming with secrets placeholders", () => {
- test("buffers partial [[SECRET_MASKED placeholder", () => {
+ test("buffers partial [[ placeholder", () => {
const context = createSecretsMaskingContext();
- context.mapping["[[SECRET_MASKED_API_KEY_OPENAI_1]]"] = sampleSecret;
+ context.mapping["[[API_KEY_OPENAI_1]]"] = sampleSecret;
- const { output, remainingBuffer } = unmaskSecretsStreamChunk("", "Key: [[SECRET_MAS", context);
+ const { output, remainingBuffer } = unmaskSecretsStreamChunk("", "Key: [[API_KEY", context);
expect(output).toBe("Key: ");
- expect(remainingBuffer).toBe("[[SECRET_MAS");
+ expect(remainingBuffer).toBe("[[API_KEY");
});
test("completes buffered placeholder across chunks", () => {
const context = createSecretsMaskingContext();
- context.mapping["[[SECRET_MASKED_API_KEY_OPENAI_1]]"] = sampleSecret;
+ context.mapping["[[API_KEY_OPENAI_1]]"] = sampleSecret;
const { output, remainingBuffer } = unmaskSecretsStreamChunk(
- "[[SECRET_MAS",
- "KED_API_KEY_OPENAI_1]] done",
+ "[[API_KEY",
+ "_OPENAI_1]] done",
context,
);
test("flushes incomplete buffer as-is", () => {
const context = createSecretsMaskingContext();
- const result = flushSecretsMaskingBuffer("[[SECRET_MAS", context);
- expect(result).toBe("[[SECRET_MAS");
+ const result = flushSecretsMaskingBuffer("[[API_KEY", context);
+ expect(result).toBe("[[API_KEY");
});
});
const { masked, context } = maskSecrets(originalText, locations);
expect(masked).not.toContain(sampleSecret);
- expect(masked).toContain("[[SECRET_MASKED_API_KEY_OPENAI_1]]");
+ expect(masked).toContain("[[API_KEY_OPENAI_1]]");
const restored = unmaskSecrets(masked, context);
expect(restored).toBe(originalText);
describe("unmaskSecretsResponse", () => {
test("unmasks all choices in response", () => {
const context = createSecretsMaskingContext();
- context.mapping["[[SECRET_MASKED_API_KEY_OPENAI_1]]"] = sampleSecret;
+ context.mapping["[[API_KEY_OPENAI_1]]"] = sampleSecret;
const response: OpenAIResponse = {
id: "test",
index: 0,
message: {
role: "assistant",
- content: "Your key is [[SECRET_MASKED_API_KEY_OPENAI_1]]",
+ content: "Your key is [[API_KEY_OPENAI_1]]",
},
finish_reason: "stop",
},
];
const result = maskSecrets(text, locations);
- expect(result.masked).toBe(
- "Key1: [[SECRET_MASKED_API_KEY_OPENAI_1]] Key2: [[SECRET_MASKED_API_KEY_OPENAI_1]]",
- );
+ expect(result.masked).toBe("Key1: [[API_KEY_OPENAI_1]] Key2: [[API_KEY_OPENAI_1]]");
expect(Object.keys(result.context.mapping)).toHaveLength(1);
});
context,
);
- expect(result2.masked).toBe("Another: [[SECRET_MASKED_API_KEY_OPENAI_2]]");
+ expect(result2.masked).toBe("Another: [[API_KEY_OPENAI_2]]");
expect(Object.keys(context.mapping)).toHaveLength(2);
});
});