@silmaril-security/sdk 0.7.5 → 0.7.7
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 +15 -0
- package/README.md +21 -2
- package/dist/adapters/deepagents.d.cts +1 -1
- package/dist/adapters/deepagents.d.ts +1 -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-g3ZLF0xp.d.cts → firewall-CueYday8.d.cts} +12 -5
- package/dist/{firewall-g3ZLF0xp.d.ts → firewall-CueYday8.d.ts} +12 -5
- package/dist/index.cjs +90 -10
- 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 +90 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.7.7
|
|
6
|
+
|
|
7
|
+
- Preserve optional governance response evidence for the canonical resource,
|
|
8
|
+
identity revision, and open-ended decision reason when supplied by the
|
|
9
|
+
serving runtime.
|
|
10
|
+
|
|
11
|
+
## 0.7.6
|
|
12
|
+
|
|
13
|
+
- Send typed governance resources in the runtime's top-level `resource` and
|
|
14
|
+
aligned `resources` fields, preserving compatibility attribution metadata.
|
|
15
|
+
- Reject invalid canonical resource references before submitting a request.
|
|
16
|
+
Caller-supplied agent metadata remains attribution, not authenticated identity.
|
|
17
|
+
|
|
3
18
|
All notable changes to the Silmaril Firewall TypeScript SDK are documented here.
|
|
4
19
|
|
|
5
20
|
## 0.7.5 - 2026-10-12
|
package/README.md
CHANGED
|
@@ -34,10 +34,10 @@ This SDK is distributed as an npm package.
|
|
|
34
34
|
npm install @silmaril-security/sdk
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
After publication, pin version 0.7.7 for reproducible installs:
|
|
38
38
|
|
|
39
39
|
```sh
|
|
40
|
-
npm install @silmaril-security/sdk@0.7.
|
|
40
|
+
npm install @silmaril-security/sdk@0.7.7
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
Requires Node 20 or later.
|
|
@@ -397,6 +397,13 @@ returns the server action, policy version, and optional rule ID. A malicious
|
|
|
397
397
|
prediction or explicit governance block is blocked in Block mode; legacy
|
|
398
398
|
responses without governance remain valid.
|
|
399
399
|
|
|
400
|
+
When supported by the serving runtime, `BlockResult.governance` can also
|
|
401
|
+
include optional decision evidence: the canonical `resource` (`kind`, `id`,
|
|
402
|
+
and `parentId` for MCP tools), `identityRevision`, and `reason`. Older runtimes
|
|
403
|
+
may omit these fields, and reason strings are open-ended so callers should
|
|
404
|
+
preserve unknown values. This response evidence does not establish request
|
|
405
|
+
identity and does not change enforcement behavior.
|
|
406
|
+
|
|
400
407
|
## Errors
|
|
401
408
|
|
|
402
409
|
- `SilmarilApiError`: thrown when native `fetch` returns a non-2xx response to
|
|
@@ -637,3 +644,15 @@ npm publish --access public
|
|
|
637
644
|
|
|
638
645
|
This SDK is distributed under the license terms in [LICENSE](LICENSE). It is not
|
|
639
646
|
permissive open source.
|
|
647
|
+
|
|
648
|
+
## Governance resource requests
|
|
649
|
+
|
|
650
|
+
Typed governance resources are sent in the classify request's top-level
|
|
651
|
+
`resource` field or aligned nullable `resources` array for batch calls. Resource
|
|
652
|
+
IDs must be non-empty; MCP tools also require their canonical server parent ID.
|
|
653
|
+
The compatibility metadata copy remains attribution only. Caller agent metadata
|
|
654
|
+
does not supply an authenticated principal.
|
|
655
|
+
|
|
656
|
+
This source prepares version 0.7.7. Its registry install command becomes
|
|
657
|
+
available after the authorized main-branch release workflow publishes the package.
|
|
658
|
+
Confirm registry publication before installing this version.
|
|
@@ -12,7 +12,7 @@ import * as _langchain_core_utils_types from '@langchain/core/utils/types';
|
|
|
12
12
|
import * as langchain from 'langchain';
|
|
13
13
|
import { CreateAgentParams } from 'langchain';
|
|
14
14
|
import * as _langchain_core_tools from '@langchain/core/tools';
|
|
15
|
-
import { h as FirewallMode, b as ClassifyEvent, e as Firewall } from '../firewall-
|
|
15
|
+
import { h as FirewallMode, b as ClassifyEvent, e as Firewall } from '../firewall-CueYday8.cjs';
|
|
16
16
|
|
|
17
17
|
declare const SAFE_TOOL_MESSAGE = "Silmaril Firewall blocked this tool interaction. Choose a different safe action.";
|
|
18
18
|
declare const SAFE_FINAL_MESSAGE = "Silmaril Firewall stopped this request after repeated unsafe actions.";
|
|
@@ -12,7 +12,7 @@ import * as _langchain_core_utils_types from '@langchain/core/utils/types';
|
|
|
12
12
|
import * as langchain from 'langchain';
|
|
13
13
|
import { CreateAgentParams } from 'langchain';
|
|
14
14
|
import * as _langchain_core_tools from '@langchain/core/tools';
|
|
15
|
-
import { h as FirewallMode, b as ClassifyEvent, e as Firewall } from '../firewall-
|
|
15
|
+
import { h as FirewallMode, b as ClassifyEvent, e as Firewall } from '../firewall-CueYday8.js';
|
|
16
16
|
|
|
17
17
|
declare const SAFE_TOOL_MESSAGE = "Silmaril Firewall blocked this tool interaction. Choose a different safe action.";
|
|
18
18
|
declare const SAFE_FINAL_MESSAGE = "Silmaril Firewall stopped this request after repeated unsafe actions.";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
|
2
|
-
import { e as Firewall, L as LangChainAdapterOptions } from '../firewall-
|
|
2
|
+
import { e as Firewall, L as LangChainAdapterOptions } from '../firewall-CueYday8.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 { e as Firewall, L as LangChainAdapterOptions } from '../firewall-
|
|
2
|
+
import { e as Firewall, L as LangChainAdapterOptions } from '../firewall-CueYday8.js';
|
|
3
3
|
|
|
4
4
|
declare function createLangChainHandler(firewall: Firewall, options?: LangChainAdapterOptions): Promise<BaseCallbackHandler>;
|
|
5
5
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { g as FirewallMiddleware, Q as createMiddleware } from '../firewall-
|
|
1
|
+
export { g as FirewallMiddleware, Q as createMiddleware } from '../firewall-CueYday8.cjs';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { g as FirewallMiddleware, Q as createMiddleware } from '../firewall-
|
|
1
|
+
export { g as FirewallMiddleware, Q as createMiddleware } from '../firewall-CueYday8.js';
|
|
@@ -74,11 +74,15 @@ type Prediction = "BENIGN" | "MALICIOUS";
|
|
|
74
74
|
type FirewallMode = "shadow" | "warn" | "block";
|
|
75
75
|
type GovernanceAction = "allow" | "block";
|
|
76
76
|
type GovernanceResourceKind = "agent" | "tool" | "mcp_server" | "mcp_tool" | "plugin" | "skill" | "extension";
|
|
77
|
-
|
|
78
|
-
readonly kind:
|
|
79
|
-
readonly id
|
|
80
|
-
readonly parentId
|
|
81
|
-
}
|
|
77
|
+
type GovernanceResource = {
|
|
78
|
+
readonly kind: "mcp_tool";
|
|
79
|
+
readonly id: string;
|
|
80
|
+
readonly parentId: string;
|
|
81
|
+
} | {
|
|
82
|
+
readonly kind: Exclude<GovernanceResourceKind, "mcp_tool">;
|
|
83
|
+
readonly id: string;
|
|
84
|
+
readonly parentId?: never;
|
|
85
|
+
};
|
|
82
86
|
interface GovernanceContext {
|
|
83
87
|
readonly agent?: string;
|
|
84
88
|
readonly resource?: GovernanceResource;
|
|
@@ -87,6 +91,9 @@ interface GovernanceDecision {
|
|
|
87
91
|
readonly action: GovernanceAction;
|
|
88
92
|
readonly ruleId?: string;
|
|
89
93
|
readonly policyVersion: string;
|
|
94
|
+
readonly resource?: GovernanceResource;
|
|
95
|
+
readonly identityRevision?: string;
|
|
96
|
+
readonly reason?: string;
|
|
90
97
|
}
|
|
91
98
|
interface BlockResult {
|
|
92
99
|
readonly prediction: Prediction;
|
|
@@ -74,11 +74,15 @@ type Prediction = "BENIGN" | "MALICIOUS";
|
|
|
74
74
|
type FirewallMode = "shadow" | "warn" | "block";
|
|
75
75
|
type GovernanceAction = "allow" | "block";
|
|
76
76
|
type GovernanceResourceKind = "agent" | "tool" | "mcp_server" | "mcp_tool" | "plugin" | "skill" | "extension";
|
|
77
|
-
|
|
78
|
-
readonly kind:
|
|
79
|
-
readonly id
|
|
80
|
-
readonly parentId
|
|
81
|
-
}
|
|
77
|
+
type GovernanceResource = {
|
|
78
|
+
readonly kind: "mcp_tool";
|
|
79
|
+
readonly id: string;
|
|
80
|
+
readonly parentId: string;
|
|
81
|
+
} | {
|
|
82
|
+
readonly kind: Exclude<GovernanceResourceKind, "mcp_tool">;
|
|
83
|
+
readonly id: string;
|
|
84
|
+
readonly parentId?: never;
|
|
85
|
+
};
|
|
82
86
|
interface GovernanceContext {
|
|
83
87
|
readonly agent?: string;
|
|
84
88
|
readonly resource?: GovernanceResource;
|
|
@@ -87,6 +91,9 @@ interface GovernanceDecision {
|
|
|
87
91
|
readonly action: GovernanceAction;
|
|
88
92
|
readonly ruleId?: string;
|
|
89
93
|
readonly policyVersion: string;
|
|
94
|
+
readonly resource?: GovernanceResource;
|
|
95
|
+
readonly identityRevision?: string;
|
|
96
|
+
readonly reason?: string;
|
|
90
97
|
}
|
|
91
98
|
interface BlockResult {
|
|
92
99
|
readonly prediction: Prediction;
|
package/dist/index.cjs
CHANGED
|
@@ -818,7 +818,7 @@ function sanitizeText(text) {
|
|
|
818
818
|
}
|
|
819
819
|
|
|
820
820
|
// src/firewall.ts
|
|
821
|
-
var SDK_VERSION = "0.7.
|
|
821
|
+
var SDK_VERSION = "0.7.7";
|
|
822
822
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
823
823
|
var DEFAULT_MAX_RETRIES = 5;
|
|
824
824
|
var MAX_BACKOFF_SECONDS = 30;
|
|
@@ -870,7 +870,7 @@ function blockResultFromResponse(data, requestedMode) {
|
|
|
870
870
|
result.detectorCounts = detectorCounts;
|
|
871
871
|
}
|
|
872
872
|
}
|
|
873
|
-
if (data.governance !== void 0) {
|
|
873
|
+
if (data.governance !== void 0 && data.governance !== null) {
|
|
874
874
|
result.governance = governanceDecisionFromResponse(data.governance);
|
|
875
875
|
}
|
|
876
876
|
return Object.freeze(result);
|
|
@@ -894,15 +894,75 @@ function withSdkMetadata(metadata, info) {
|
|
|
894
894
|
};
|
|
895
895
|
return payload;
|
|
896
896
|
}
|
|
897
|
+
var GOVERNANCE_RESOURCE_KINDS = [
|
|
898
|
+
"agent",
|
|
899
|
+
"tool",
|
|
900
|
+
"mcp_server",
|
|
901
|
+
"mcp_tool",
|
|
902
|
+
"plugin",
|
|
903
|
+
"skill",
|
|
904
|
+
"extension"
|
|
905
|
+
];
|
|
906
|
+
function isGovernanceResourceKind(value) {
|
|
907
|
+
return typeof value === "string" && GOVERNANCE_RESOURCE_KINDS.includes(value);
|
|
908
|
+
}
|
|
909
|
+
function governanceResourceToWire(resource) {
|
|
910
|
+
if (!isGovernanceResourceKind(resource.kind)) {
|
|
911
|
+
throw new Error("Firewall: invalid governance resource kind");
|
|
912
|
+
}
|
|
913
|
+
if (typeof resource.id !== "string" || !resource.id.trim()) {
|
|
914
|
+
throw new Error("Firewall: governance resource id must be a non-empty string");
|
|
915
|
+
}
|
|
916
|
+
if (resource.kind === "mcp_tool") {
|
|
917
|
+
if (typeof resource.parentId !== "string" || !resource.parentId.trim()) {
|
|
918
|
+
throw new Error("Firewall: mcp_tool resource requires a non-empty parentId");
|
|
919
|
+
}
|
|
920
|
+
} else if (resource.parentId !== void 0) {
|
|
921
|
+
throw new Error("Firewall: parentId is valid only for mcp_tool resources");
|
|
922
|
+
}
|
|
923
|
+
return {
|
|
924
|
+
kind: resource.kind,
|
|
925
|
+
id: resource.id,
|
|
926
|
+
...resource.parentId === void 0 ? {} : { parent_id: resource.parentId }
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
function governanceResourceFromResponse(value) {
|
|
930
|
+
if (!isRecord2(value)) {
|
|
931
|
+
throw new Error("Firewall: response governance resource must be an object");
|
|
932
|
+
}
|
|
933
|
+
if (!isGovernanceResourceKind(value.kind)) {
|
|
934
|
+
throw new Error("Firewall: response governance resource has an invalid kind");
|
|
935
|
+
}
|
|
936
|
+
if (typeof value.id !== "string" || !value.id.trim()) {
|
|
937
|
+
throw new Error("Firewall: response governance resource id must be a non-empty string");
|
|
938
|
+
}
|
|
939
|
+
if (value.kind === "mcp_tool") {
|
|
940
|
+
if (typeof value.parent_id !== "string" || !value.parent_id.trim()) {
|
|
941
|
+
throw new Error(
|
|
942
|
+
"Firewall: response governance mcp_tool resource requires a non-empty parent_id"
|
|
943
|
+
);
|
|
944
|
+
}
|
|
945
|
+
return Object.freeze({
|
|
946
|
+
kind: value.kind,
|
|
947
|
+
id: value.id,
|
|
948
|
+
parentId: value.parent_id
|
|
949
|
+
});
|
|
950
|
+
}
|
|
951
|
+
if (value.parent_id !== void 0 && value.parent_id !== null) {
|
|
952
|
+
throw new Error(
|
|
953
|
+
"Firewall: response governance parent_id is valid only for mcp_tool resources"
|
|
954
|
+
);
|
|
955
|
+
}
|
|
956
|
+
return Object.freeze({
|
|
957
|
+
kind: value.kind,
|
|
958
|
+
id: value.id
|
|
959
|
+
});
|
|
960
|
+
}
|
|
897
961
|
function governanceContextToWire(context) {
|
|
898
962
|
return {
|
|
899
963
|
...context.agent === void 0 ? {} : { agent: context.agent },
|
|
900
964
|
...context.resource === void 0 ? {} : {
|
|
901
|
-
resource:
|
|
902
|
-
kind: context.resource.kind,
|
|
903
|
-
...context.resource.id === void 0 ? {} : { id: context.resource.id },
|
|
904
|
-
...context.resource.parentId === void 0 ? {} : { parent_id: context.resource.parentId }
|
|
905
|
-
}
|
|
965
|
+
resource: governanceResourceToWire(context.resource)
|
|
906
966
|
}
|
|
907
967
|
};
|
|
908
968
|
}
|
|
@@ -916,13 +976,25 @@ function governanceDecisionFromResponse(value) {
|
|
|
916
976
|
if (typeof value.policy_version !== "string" || value.policy_version.length === 0) {
|
|
917
977
|
throw new Error("Firewall: response governance policy_version must be a non-empty string");
|
|
918
978
|
}
|
|
919
|
-
if (value.rule_id !== void 0 && typeof value.rule_id !== "string") {
|
|
979
|
+
if (value.rule_id !== void 0 && value.rule_id !== null && typeof value.rule_id !== "string") {
|
|
920
980
|
throw new Error("Firewall: response governance rule_id must be a string when provided");
|
|
921
981
|
}
|
|
982
|
+
if (value.identity_revision !== void 0 && value.identity_revision !== null && typeof value.identity_revision !== "string") {
|
|
983
|
+
throw new Error(
|
|
984
|
+
"Firewall: response governance identity_revision must be a string when provided"
|
|
985
|
+
);
|
|
986
|
+
}
|
|
987
|
+
if (value.reason !== void 0 && value.reason !== null && typeof value.reason !== "string") {
|
|
988
|
+
throw new Error("Firewall: response governance reason must be a string when provided");
|
|
989
|
+
}
|
|
990
|
+
const resource = value.resource === void 0 || value.resource === null ? void 0 : governanceResourceFromResponse(value.resource);
|
|
922
991
|
return Object.freeze({
|
|
923
992
|
action: value.action,
|
|
924
|
-
...value.rule_id === void 0 ? {} : { ruleId: value.rule_id },
|
|
925
|
-
policyVersion: value.policy_version
|
|
993
|
+
...value.rule_id === void 0 || value.rule_id === null ? {} : { ruleId: value.rule_id },
|
|
994
|
+
policyVersion: value.policy_version,
|
|
995
|
+
...resource === void 0 ? {} : { resource },
|
|
996
|
+
...value.identity_revision === void 0 || value.identity_revision === null ? {} : { identityRevision: value.identity_revision },
|
|
997
|
+
...value.reason === void 0 || value.reason === null ? {} : { reason: value.reason }
|
|
926
998
|
});
|
|
927
999
|
}
|
|
928
1000
|
async function readCappedErrorBody(response) {
|
|
@@ -1122,6 +1194,11 @@ var Firewall = class {
|
|
|
1122
1194
|
...options.governance?.[index] === void 0 ? {} : { governance: options.governance[index] }
|
|
1123
1195
|
})
|
|
1124
1196
|
);
|
|
1197
|
+
if (options.governance !== void 0) {
|
|
1198
|
+
payload.resources = options.governance.map(
|
|
1199
|
+
(context) => context?.resource === void 0 ? null : governanceResourceToWire(context.resource)
|
|
1200
|
+
);
|
|
1201
|
+
}
|
|
1125
1202
|
const data = await this.postWithRetry(payload, options.signal);
|
|
1126
1203
|
if (!Array.isArray(data.predictions)) {
|
|
1127
1204
|
throw new Error("Firewall: response predictions must be an array");
|
|
@@ -1190,6 +1267,9 @@ var Firewall = class {
|
|
|
1190
1267
|
if (options.toolName !== void 0) {
|
|
1191
1268
|
payload.tool_name = options.toolName;
|
|
1192
1269
|
}
|
|
1270
|
+
if (options.governance?.resource !== void 0) {
|
|
1271
|
+
payload.resource = governanceResourceToWire(options.governance.resource);
|
|
1272
|
+
}
|
|
1193
1273
|
payload.metadata = withSdkMetadata(options.metadata, {
|
|
1194
1274
|
...metadataInfo,
|
|
1195
1275
|
...options.governance === void 0 ? {} : { governance: options.governance }
|