@silmaril-security/sdk 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/README.md +47 -1
- package/dist/adapters/langchain.d.cts +1 -1
- package/dist/adapters/langchain.d.ts +1 -1
- package/dist/adapters/vercel.d.cts +1 -1
- package/dist/adapters/vercel.d.ts +1 -1
- package/dist/{firewall-CEV5hItA.d.cts → firewall-DfZCCDU6.d.cts} +37 -5
- package/dist/{firewall-CEV5hItA.d.ts → firewall-DfZCCDU6.d.ts} +37 -5
- package/dist/index.cjs +104 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +95 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to the Silmaril Firewall TypeScript SDK are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.4.2 - 2026-06-02
|
|
6
|
+
|
|
7
|
+
- Add typed firewall outcome constants, ordered outcome lists, descriptions,
|
|
8
|
+
type guards, and response normalizers.
|
|
9
|
+
- Type `BlockResult.primaryOutcome`, `outcomeScores`, `detectorScores`, and
|
|
10
|
+
`detectorCounts` around the canonical outcome taxonomy.
|
|
11
|
+
- Document simple outcome routing examples for direct `classify()` results.
|
|
12
|
+
|
|
5
13
|
## 0.4.1 - 2026-05-24
|
|
6
14
|
|
|
7
15
|
- Recover the `0.4.x` npm release by moving to `0.4.1`. The `v0.4.0` Git tag
|
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ npm install @silmaril-security/sdk
|
|
|
37
37
|
For reproducible installs, pin a tagged release:
|
|
38
38
|
|
|
39
39
|
```sh
|
|
40
|
-
npm install @silmaril-security/sdk@0.4.
|
|
40
|
+
npm install @silmaril-security/sdk@0.4.2
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
Requires Node 18 or later.
|
|
@@ -117,6 +117,52 @@ internally applied threshold. Direct calls do not throw on malicious verdicts.
|
|
|
117
117
|
The Vercel AI SDK and LangChain.js adapters use `result.threshold` and throw
|
|
118
118
|
`FirewallBlockedException` when enforcement is enabled.
|
|
119
119
|
|
|
120
|
+
## Handle Outcomes
|
|
121
|
+
|
|
122
|
+
Direct calls expose typed outcome labels so applications can choose different
|
|
123
|
+
responses for different firewall decisions:
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import { Firewall, HookLabel, Outcome } from "@silmaril-security/sdk";
|
|
127
|
+
|
|
128
|
+
const result = await fw.classify(userInput, {
|
|
129
|
+
hook: HookLabel.USER_INPUT,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
if (result.score < result.threshold) {
|
|
133
|
+
continueNormally();
|
|
134
|
+
} else {
|
|
135
|
+
switch (result.primaryOutcome) {
|
|
136
|
+
case Outcome.SecretExposure:
|
|
137
|
+
redactAndSuppress(result);
|
|
138
|
+
break;
|
|
139
|
+
case Outcome.InformationDisclosure:
|
|
140
|
+
requireReview(result);
|
|
141
|
+
break;
|
|
142
|
+
case Outcome.ControlAbuse:
|
|
143
|
+
denyAndAskForConfirmation(result);
|
|
144
|
+
break;
|
|
145
|
+
case Outcome.SystemCompromise:
|
|
146
|
+
blockAndEscalate(result);
|
|
147
|
+
break;
|
|
148
|
+
case Outcome.ServiceDisruption:
|
|
149
|
+
blockDisruptiveAction(result);
|
|
150
|
+
break;
|
|
151
|
+
default:
|
|
152
|
+
blockByDefault(result);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Outcome taxonomy:
|
|
158
|
+
|
|
159
|
+
- `benign`: no harmful firewall outcome detected.
|
|
160
|
+
- `information_disclosure`: private data, documents, internal context, logs, traces, customer data, SQL rows, topology, or similar non-secret sensitive information.
|
|
161
|
+
- `secret_exposure`: credentials, tokens, API keys, cookies, passwords, signing keys, OAuth secrets, session material, or webhook secrets.
|
|
162
|
+
- `control_abuse`: misuse of authorized tools or user privileges to send, change, approve, delete, operate, or bypass policy/RBAC without a stronger outcome.
|
|
163
|
+
- `system_compromise`: privilege escalation, account takeover, hostile integration/plugin takeover, persistence, lateral movement, attacker webhook registration, or code/plugin execution.
|
|
164
|
+
- `service_disruption`: downtime, lockout, degradation, alert suppression, destructive loops, resource exhaustion, cost spikes, or hidden outage evidence.
|
|
165
|
+
|
|
120
166
|
## Options
|
|
121
167
|
|
|
122
168
|
```ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
|
2
|
-
import { f as Firewall, L as LangChainAdapterOptions } from '../firewall-
|
|
2
|
+
import { f as Firewall, L as LangChainAdapterOptions } from '../firewall-DfZCCDU6.cjs';
|
|
3
3
|
|
|
4
4
|
declare function createLangChainHandler(firewall: Firewall, options?: LangChainAdapterOptions): Promise<BaseCallbackHandler>;
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
|
2
|
-
import { f as Firewall, L as LangChainAdapterOptions } from '../firewall-
|
|
2
|
+
import { f as Firewall, L as LangChainAdapterOptions } from '../firewall-DfZCCDU6.js';
|
|
3
3
|
|
|
4
4
|
declare function createLangChainHandler(firewall: Firewall, options?: LangChainAdapterOptions): Promise<BaseCallbackHandler>;
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { h as FirewallMiddleware,
|
|
1
|
+
export { h as FirewallMiddleware, z as createMiddleware } from '../firewall-DfZCCDU6.cjs';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { h as FirewallMiddleware,
|
|
1
|
+
export { h as FirewallMiddleware, z as createMiddleware } from '../firewall-DfZCCDU6.js';
|
|
@@ -26,15 +26,47 @@ declare function resolveHooks(hooks: Iterable<FirewallHook | string> | undefined
|
|
|
26
26
|
declare function prependHook(text: string, hook: HookLabel | string | undefined | null): string;
|
|
27
27
|
declare function prependToolName(text: string, toolName: string | undefined | null): string;
|
|
28
28
|
|
|
29
|
+
declare const Outcome: {
|
|
30
|
+
readonly Benign: "benign";
|
|
31
|
+
readonly InformationDisclosure: "information_disclosure";
|
|
32
|
+
readonly SecretExposure: "secret_exposure";
|
|
33
|
+
readonly ControlAbuse: "control_abuse";
|
|
34
|
+
readonly SystemCompromise: "system_compromise";
|
|
35
|
+
readonly ServiceDisruption: "service_disruption";
|
|
36
|
+
};
|
|
37
|
+
declare const unknownOutcomeBrand: unique symbol;
|
|
38
|
+
type KnownPrimaryOutcome = (typeof Outcome)[keyof typeof Outcome];
|
|
39
|
+
type KnownHarmfulOutcome = Exclude<KnownPrimaryOutcome, typeof Outcome.Benign>;
|
|
40
|
+
type UnknownOutcome = string & {
|
|
41
|
+
readonly [unknownOutcomeBrand]: "UnknownOutcome";
|
|
42
|
+
};
|
|
43
|
+
type PrimaryOutcome = KnownPrimaryOutcome | UnknownOutcome;
|
|
44
|
+
type HarmfulOutcome = KnownHarmfulOutcome | UnknownOutcome;
|
|
45
|
+
declare const PRIMARY_OUTCOMES: readonly ["benign", "information_disclosure", "secret_exposure", "control_abuse", "system_compromise", "service_disruption"];
|
|
46
|
+
declare const HARMFUL_OUTCOMES: readonly ["information_disclosure", "secret_exposure", "control_abuse", "system_compromise", "service_disruption"];
|
|
47
|
+
declare const OUTCOME_DESCRIPTIONS: {
|
|
48
|
+
readonly benign: "No harmful firewall outcome detected.";
|
|
49
|
+
readonly information_disclosure: "Exposes private data, documents, internal context, logs, traces, customer data, SQL rows, topology, or similar non-secret sensitive information.";
|
|
50
|
+
readonly secret_exposure: "Exposes credentials, tokens, API keys, cookies, passwords, signing keys, OAuth secrets, session material, or webhook secrets.";
|
|
51
|
+
readonly control_abuse: "Misuses authorized tools or user privileges to send, change, approve, delete, operate, or bypass policy/RBAC without a stronger outcome.";
|
|
52
|
+
readonly system_compromise: "Enables privilege escalation, account takeover, hostile integration or plugin takeover, persistence, lateral movement, attacker webhook registration, or code/plugin execution.";
|
|
53
|
+
readonly service_disruption: "Causes downtime, lockout, degradation, alert suppression, destructive loops, resource exhaustion, cost spikes, or hidden outage evidence.";
|
|
54
|
+
};
|
|
55
|
+
declare function isPrimaryOutcome(value: unknown): value is KnownPrimaryOutcome;
|
|
56
|
+
declare function isHarmfulOutcome(value: unknown): value is KnownHarmfulOutcome;
|
|
57
|
+
declare function normalizePrimaryOutcome(value: unknown, fieldName?: string): PrimaryOutcome;
|
|
58
|
+
declare function normalizeHarmfulOutcome(value: unknown, fieldName?: string): HarmfulOutcome;
|
|
59
|
+
declare function normalizeHarmfulOutcomeMap(values: unknown, fieldName: string): Readonly<Partial<Record<HarmfulOutcome, number>>> | undefined;
|
|
60
|
+
|
|
29
61
|
type Prediction = "BENIGN" | "MALICIOUS";
|
|
30
62
|
interface BlockResult {
|
|
31
63
|
readonly prediction: Prediction;
|
|
32
64
|
readonly score: number;
|
|
33
65
|
readonly threshold: number;
|
|
34
|
-
readonly primaryOutcome?:
|
|
35
|
-
readonly outcomeScores?: Readonly<Record<
|
|
36
|
-
readonly detectorScores?: Readonly<Record<
|
|
37
|
-
readonly detectorCounts?: Readonly<Record<
|
|
66
|
+
readonly primaryOutcome?: PrimaryOutcome;
|
|
67
|
+
readonly outcomeScores?: Readonly<Partial<Record<HarmfulOutcome, number>>>;
|
|
68
|
+
readonly detectorScores?: Readonly<Partial<Record<HarmfulOutcome, number>>>;
|
|
69
|
+
readonly detectorCounts?: Readonly<Partial<Record<HarmfulOutcome, number>>>;
|
|
38
70
|
}
|
|
39
71
|
interface FirewallOptions {
|
|
40
72
|
apiKey: string;
|
|
@@ -162,4 +194,4 @@ declare class Firewall {
|
|
|
162
194
|
private classifySingleChunk;
|
|
163
195
|
}
|
|
164
196
|
|
|
165
|
-
export { ALL_HOOKS as A, type BlockResult as B, type ClassificationMetadata as C, DEFAULT_CHUNK_CONCURRENCY as D, FIREWALL_HOOK_TO_LABEL as F, HookLabel as H, INPUT_HOOKS as I, type LangChainAdapterOptions as L, type MiddlewareOptions as M,
|
|
197
|
+
export { ALL_HOOKS as A, type BlockResult as B, type ClassificationMetadata as C, DEFAULT_CHUNK_CONCURRENCY as D, FIREWALL_HOOK_TO_LABEL as F, HookLabel as H, INPUT_HOOKS as I, type KnownHarmfulOutcome as K, type LangChainAdapterOptions as L, type MiddlewareOptions as M, OUTCOME_DESCRIPTIONS as O, PRIMARY_OUTCOMES as P, type UnknownOutcome as U, type ClassifyBatchOptions as a, type ClassifyEvent as b, type ClassifyOptions as c, DEFAULT_HOOKS as d, DEFAULT_TIMEOUT_MS as e, Firewall as f, FirewallHook as g, type FirewallMiddleware as h, type FirewallOptions as i, HARMFUL_OUTCOMES as j, type HarmfulOutcome as k, type KnownPrimaryOutcome as l, type LangChainFirewallHandler as m, OUTPUT_HOOKS as n, Outcome as o, type Prediction as p, type PrimaryOutcome as q, isHarmfulOutcome as r, isPrimaryOutcome as s, normalizeHarmfulOutcome as t, normalizeHarmfulOutcomeMap as u, normalizePrimaryOutcome as v, prependHook as w, prependToolName as x, resolveHooks as y, createMiddleware as z };
|
|
@@ -26,15 +26,47 @@ declare function resolveHooks(hooks: Iterable<FirewallHook | string> | undefined
|
|
|
26
26
|
declare function prependHook(text: string, hook: HookLabel | string | undefined | null): string;
|
|
27
27
|
declare function prependToolName(text: string, toolName: string | undefined | null): string;
|
|
28
28
|
|
|
29
|
+
declare const Outcome: {
|
|
30
|
+
readonly Benign: "benign";
|
|
31
|
+
readonly InformationDisclosure: "information_disclosure";
|
|
32
|
+
readonly SecretExposure: "secret_exposure";
|
|
33
|
+
readonly ControlAbuse: "control_abuse";
|
|
34
|
+
readonly SystemCompromise: "system_compromise";
|
|
35
|
+
readonly ServiceDisruption: "service_disruption";
|
|
36
|
+
};
|
|
37
|
+
declare const unknownOutcomeBrand: unique symbol;
|
|
38
|
+
type KnownPrimaryOutcome = (typeof Outcome)[keyof typeof Outcome];
|
|
39
|
+
type KnownHarmfulOutcome = Exclude<KnownPrimaryOutcome, typeof Outcome.Benign>;
|
|
40
|
+
type UnknownOutcome = string & {
|
|
41
|
+
readonly [unknownOutcomeBrand]: "UnknownOutcome";
|
|
42
|
+
};
|
|
43
|
+
type PrimaryOutcome = KnownPrimaryOutcome | UnknownOutcome;
|
|
44
|
+
type HarmfulOutcome = KnownHarmfulOutcome | UnknownOutcome;
|
|
45
|
+
declare const PRIMARY_OUTCOMES: readonly ["benign", "information_disclosure", "secret_exposure", "control_abuse", "system_compromise", "service_disruption"];
|
|
46
|
+
declare const HARMFUL_OUTCOMES: readonly ["information_disclosure", "secret_exposure", "control_abuse", "system_compromise", "service_disruption"];
|
|
47
|
+
declare const OUTCOME_DESCRIPTIONS: {
|
|
48
|
+
readonly benign: "No harmful firewall outcome detected.";
|
|
49
|
+
readonly information_disclosure: "Exposes private data, documents, internal context, logs, traces, customer data, SQL rows, topology, or similar non-secret sensitive information.";
|
|
50
|
+
readonly secret_exposure: "Exposes credentials, tokens, API keys, cookies, passwords, signing keys, OAuth secrets, session material, or webhook secrets.";
|
|
51
|
+
readonly control_abuse: "Misuses authorized tools or user privileges to send, change, approve, delete, operate, or bypass policy/RBAC without a stronger outcome.";
|
|
52
|
+
readonly system_compromise: "Enables privilege escalation, account takeover, hostile integration or plugin takeover, persistence, lateral movement, attacker webhook registration, or code/plugin execution.";
|
|
53
|
+
readonly service_disruption: "Causes downtime, lockout, degradation, alert suppression, destructive loops, resource exhaustion, cost spikes, or hidden outage evidence.";
|
|
54
|
+
};
|
|
55
|
+
declare function isPrimaryOutcome(value: unknown): value is KnownPrimaryOutcome;
|
|
56
|
+
declare function isHarmfulOutcome(value: unknown): value is KnownHarmfulOutcome;
|
|
57
|
+
declare function normalizePrimaryOutcome(value: unknown, fieldName?: string): PrimaryOutcome;
|
|
58
|
+
declare function normalizeHarmfulOutcome(value: unknown, fieldName?: string): HarmfulOutcome;
|
|
59
|
+
declare function normalizeHarmfulOutcomeMap(values: unknown, fieldName: string): Readonly<Partial<Record<HarmfulOutcome, number>>> | undefined;
|
|
60
|
+
|
|
29
61
|
type Prediction = "BENIGN" | "MALICIOUS";
|
|
30
62
|
interface BlockResult {
|
|
31
63
|
readonly prediction: Prediction;
|
|
32
64
|
readonly score: number;
|
|
33
65
|
readonly threshold: number;
|
|
34
|
-
readonly primaryOutcome?:
|
|
35
|
-
readonly outcomeScores?: Readonly<Record<
|
|
36
|
-
readonly detectorScores?: Readonly<Record<
|
|
37
|
-
readonly detectorCounts?: Readonly<Record<
|
|
66
|
+
readonly primaryOutcome?: PrimaryOutcome;
|
|
67
|
+
readonly outcomeScores?: Readonly<Partial<Record<HarmfulOutcome, number>>>;
|
|
68
|
+
readonly detectorScores?: Readonly<Partial<Record<HarmfulOutcome, number>>>;
|
|
69
|
+
readonly detectorCounts?: Readonly<Partial<Record<HarmfulOutcome, number>>>;
|
|
38
70
|
}
|
|
39
71
|
interface FirewallOptions {
|
|
40
72
|
apiKey: string;
|
|
@@ -162,4 +194,4 @@ declare class Firewall {
|
|
|
162
194
|
private classifySingleChunk;
|
|
163
195
|
}
|
|
164
196
|
|
|
165
|
-
export { ALL_HOOKS as A, type BlockResult as B, type ClassificationMetadata as C, DEFAULT_CHUNK_CONCURRENCY as D, FIREWALL_HOOK_TO_LABEL as F, HookLabel as H, INPUT_HOOKS as I, type LangChainAdapterOptions as L, type MiddlewareOptions as M,
|
|
197
|
+
export { ALL_HOOKS as A, type BlockResult as B, type ClassificationMetadata as C, DEFAULT_CHUNK_CONCURRENCY as D, FIREWALL_HOOK_TO_LABEL as F, HookLabel as H, INPUT_HOOKS as I, type KnownHarmfulOutcome as K, type LangChainAdapterOptions as L, type MiddlewareOptions as M, OUTCOME_DESCRIPTIONS as O, PRIMARY_OUTCOMES as P, type UnknownOutcome as U, type ClassifyBatchOptions as a, type ClassifyEvent as b, type ClassifyOptions as c, DEFAULT_HOOKS as d, DEFAULT_TIMEOUT_MS as e, Firewall as f, FirewallHook as g, type FirewallMiddleware as h, type FirewallOptions as i, HARMFUL_OUTCOMES as j, type HarmfulOutcome as k, type KnownPrimaryOutcome as l, type LangChainFirewallHandler as m, OUTPUT_HOOKS as n, Outcome as o, type Prediction as p, type PrimaryOutcome as q, isHarmfulOutcome as r, isPrimaryOutcome as s, normalizeHarmfulOutcome as t, normalizeHarmfulOutcomeMap as u, normalizePrimaryOutcome as v, prependHook as w, prependToolName as x, resolveHooks as y, createMiddleware as z };
|
package/dist/index.cjs
CHANGED
|
@@ -437,14 +437,23 @@ __export(src_exports, {
|
|
|
437
437
|
Firewall: () => Firewall,
|
|
438
438
|
FirewallBlockedException: () => FirewallBlockedException,
|
|
439
439
|
FirewallHook: () => FirewallHook,
|
|
440
|
+
HARMFUL_OUTCOMES: () => HARMFUL_OUTCOMES,
|
|
440
441
|
HookLabel: () => HookLabel,
|
|
441
442
|
INPUT_HOOKS: () => INPUT_HOOKS,
|
|
442
443
|
MAX_INPUT_CHARS: () => MAX_INPUT_CHARS,
|
|
443
444
|
MAX_INPUT_TOKENS: () => MAX_INPUT_TOKENS,
|
|
445
|
+
OUTCOME_DESCRIPTIONS: () => OUTCOME_DESCRIPTIONS,
|
|
444
446
|
OUTPUT_HOOKS: () => OUTPUT_HOOKS,
|
|
447
|
+
Outcome: () => Outcome,
|
|
448
|
+
PRIMARY_OUTCOMES: () => PRIMARY_OUTCOMES,
|
|
445
449
|
PromptBlockedException: () => PromptBlockedException,
|
|
446
450
|
SilmarilApiError: () => SilmarilApiError,
|
|
447
451
|
chunkText: () => chunkText,
|
|
452
|
+
isHarmfulOutcome: () => isHarmfulOutcome,
|
|
453
|
+
isPrimaryOutcome: () => isPrimaryOutcome,
|
|
454
|
+
normalizeHarmfulOutcome: () => normalizeHarmfulOutcome,
|
|
455
|
+
normalizeHarmfulOutcomeMap: () => normalizeHarmfulOutcomeMap,
|
|
456
|
+
normalizePrimaryOutcome: () => normalizePrimaryOutcome,
|
|
448
457
|
prependHook: () => prependHook,
|
|
449
458
|
prependToolName: () => prependToolName,
|
|
450
459
|
resolveHooks: () => resolveHooks,
|
|
@@ -744,7 +753,79 @@ function chunkText(text) {
|
|
|
744
753
|
|
|
745
754
|
// src/firewall.ts
|
|
746
755
|
init_exceptions();
|
|
747
|
-
|
|
756
|
+
|
|
757
|
+
// src/outcomes.ts
|
|
758
|
+
var Outcome = {
|
|
759
|
+
Benign: "benign",
|
|
760
|
+
InformationDisclosure: "information_disclosure",
|
|
761
|
+
SecretExposure: "secret_exposure",
|
|
762
|
+
ControlAbuse: "control_abuse",
|
|
763
|
+
SystemCompromise: "system_compromise",
|
|
764
|
+
ServiceDisruption: "service_disruption"
|
|
765
|
+
};
|
|
766
|
+
var PRIMARY_OUTCOMES = [
|
|
767
|
+
Outcome.Benign,
|
|
768
|
+
Outcome.InformationDisclosure,
|
|
769
|
+
Outcome.SecretExposure,
|
|
770
|
+
Outcome.ControlAbuse,
|
|
771
|
+
Outcome.SystemCompromise,
|
|
772
|
+
Outcome.ServiceDisruption
|
|
773
|
+
];
|
|
774
|
+
var HARMFUL_OUTCOMES = [
|
|
775
|
+
Outcome.InformationDisclosure,
|
|
776
|
+
Outcome.SecretExposure,
|
|
777
|
+
Outcome.ControlAbuse,
|
|
778
|
+
Outcome.SystemCompromise,
|
|
779
|
+
Outcome.ServiceDisruption
|
|
780
|
+
];
|
|
781
|
+
var OUTCOME_DESCRIPTIONS = {
|
|
782
|
+
[Outcome.Benign]: "No harmful firewall outcome detected.",
|
|
783
|
+
[Outcome.InformationDisclosure]: "Exposes private data, documents, internal context, logs, traces, customer data, SQL rows, topology, or similar non-secret sensitive information.",
|
|
784
|
+
[Outcome.SecretExposure]: "Exposes credentials, tokens, API keys, cookies, passwords, signing keys, OAuth secrets, session material, or webhook secrets.",
|
|
785
|
+
[Outcome.ControlAbuse]: "Misuses authorized tools or user privileges to send, change, approve, delete, operate, or bypass policy/RBAC without a stronger outcome.",
|
|
786
|
+
[Outcome.SystemCompromise]: "Enables privilege escalation, account takeover, hostile integration or plugin takeover, persistence, lateral movement, attacker webhook registration, or code/plugin execution.",
|
|
787
|
+
[Outcome.ServiceDisruption]: "Causes downtime, lockout, degradation, alert suppression, destructive loops, resource exhaustion, cost spikes, or hidden outage evidence."
|
|
788
|
+
};
|
|
789
|
+
var PRIMARY_OUTCOME_SET = new Set(PRIMARY_OUTCOMES);
|
|
790
|
+
var HARMFUL_OUTCOME_SET = new Set(HARMFUL_OUTCOMES);
|
|
791
|
+
function isPrimaryOutcome(value) {
|
|
792
|
+
return typeof value === "string" && PRIMARY_OUTCOME_SET.has(value);
|
|
793
|
+
}
|
|
794
|
+
function isHarmfulOutcome(value) {
|
|
795
|
+
return typeof value === "string" && HARMFUL_OUTCOME_SET.has(value);
|
|
796
|
+
}
|
|
797
|
+
function normalizePrimaryOutcome(value, fieldName = "primary_outcome") {
|
|
798
|
+
if (typeof value !== "string") {
|
|
799
|
+
throw new Error(`Firewall: invalid ${fieldName} ${JSON.stringify(value)}`);
|
|
800
|
+
}
|
|
801
|
+
return isPrimaryOutcome(value) ? value : value;
|
|
802
|
+
}
|
|
803
|
+
function normalizeHarmfulOutcome(value, fieldName = "outcome") {
|
|
804
|
+
if (typeof value !== "string" || value === Outcome.Benign) {
|
|
805
|
+
throw new Error(`Firewall: invalid ${fieldName} ${JSON.stringify(value)}`);
|
|
806
|
+
}
|
|
807
|
+
return isHarmfulOutcome(value) ? value : value;
|
|
808
|
+
}
|
|
809
|
+
function normalizeHarmfulOutcomeMap(values, fieldName) {
|
|
810
|
+
if (values === void 0 || values === null) {
|
|
811
|
+
return void 0;
|
|
812
|
+
}
|
|
813
|
+
if (typeof values !== "object" || Array.isArray(values)) {
|
|
814
|
+
throw new Error(`Firewall: invalid ${fieldName} ${JSON.stringify(values)}`);
|
|
815
|
+
}
|
|
816
|
+
const out = {};
|
|
817
|
+
for (const [key, value] of Object.entries(values)) {
|
|
818
|
+
const normalizedKey = normalizeHarmfulOutcome(key, `${fieldName} key`);
|
|
819
|
+
if (typeof value !== "number") {
|
|
820
|
+
throw new Error(`Firewall: invalid ${fieldName} value for ${JSON.stringify(key)}`);
|
|
821
|
+
}
|
|
822
|
+
out[normalizedKey] = value;
|
|
823
|
+
}
|
|
824
|
+
return Object.freeze(out);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
// src/firewall.ts
|
|
828
|
+
var SDK_VERSION = "0.4.2";
|
|
748
829
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
749
830
|
var DEFAULT_CHUNK_CONCURRENCY = 8;
|
|
750
831
|
var DEFAULT_MAX_RETRIES = 5;
|
|
@@ -757,22 +838,25 @@ function blockResultFromResponse(data) {
|
|
|
757
838
|
threshold: Number(data.threshold)
|
|
758
839
|
};
|
|
759
840
|
if (data.primary_outcome !== void 0) {
|
|
760
|
-
result.primaryOutcome = data.primary_outcome;
|
|
841
|
+
result.primaryOutcome = normalizePrimaryOutcome(data.primary_outcome);
|
|
761
842
|
}
|
|
762
843
|
if (data.outcome_scores !== void 0) {
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
844
|
+
const outcomeScores = normalizeHarmfulOutcomeMap(data.outcome_scores, "outcome_scores");
|
|
845
|
+
if (outcomeScores !== void 0) {
|
|
846
|
+
result.outcomeScores = outcomeScores;
|
|
847
|
+
}
|
|
766
848
|
}
|
|
767
849
|
if (data.detector_scores !== void 0) {
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
850
|
+
const detectorScores = normalizeHarmfulOutcomeMap(data.detector_scores, "detector_scores");
|
|
851
|
+
if (detectorScores !== void 0) {
|
|
852
|
+
result.detectorScores = detectorScores;
|
|
853
|
+
}
|
|
771
854
|
}
|
|
772
855
|
if (data.detector_counts !== void 0) {
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
856
|
+
const detectorCounts = normalizeHarmfulOutcomeMap(data.detector_counts, "detector_counts");
|
|
857
|
+
if (detectorCounts !== void 0) {
|
|
858
|
+
result.detectorCounts = detectorCounts;
|
|
859
|
+
}
|
|
776
860
|
}
|
|
777
861
|
return Object.freeze(result);
|
|
778
862
|
}
|
|
@@ -1017,14 +1101,23 @@ init_hooks();
|
|
|
1017
1101
|
Firewall,
|
|
1018
1102
|
FirewallBlockedException,
|
|
1019
1103
|
FirewallHook,
|
|
1104
|
+
HARMFUL_OUTCOMES,
|
|
1020
1105
|
HookLabel,
|
|
1021
1106
|
INPUT_HOOKS,
|
|
1022
1107
|
MAX_INPUT_CHARS,
|
|
1023
1108
|
MAX_INPUT_TOKENS,
|
|
1109
|
+
OUTCOME_DESCRIPTIONS,
|
|
1024
1110
|
OUTPUT_HOOKS,
|
|
1111
|
+
Outcome,
|
|
1112
|
+
PRIMARY_OUTCOMES,
|
|
1025
1113
|
PromptBlockedException,
|
|
1026
1114
|
SilmarilApiError,
|
|
1027
1115
|
chunkText,
|
|
1116
|
+
isHarmfulOutcome,
|
|
1117
|
+
isPrimaryOutcome,
|
|
1118
|
+
normalizeHarmfulOutcome,
|
|
1119
|
+
normalizeHarmfulOutcomeMap,
|
|
1120
|
+
normalizePrimaryOutcome,
|
|
1028
1121
|
prependHook,
|
|
1029
1122
|
prependToolName,
|
|
1030
1123
|
resolveHooks,
|