@neuraltrust/trustguard-sdk 0.1.0 → 0.1.4
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/README.md +25 -9
- package/dist/index.cjs +49 -24
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -24
- package/dist/index.d.ts +50 -24
- package/dist/index.js +49 -24
- package/dist/index.js.map +1 -1
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# TrustGuard Node.js SDK
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@neuraltrust/trustguard-sdk)
|
|
4
|
+
[Documentation](https://docs.neuraltrust.ai/sdks/trustguard/node) · [Python package](https://pypi.org/project/trustguard-sdk/) · [Go module](https://pkg.go.dev/github.com/NeuralTrust/trustguard-sdk/go) · [GitHub](https://github.com/NeuralTrust/trustguard-sdk)
|
|
5
|
+
|
|
6
|
+
Official Node.js / TypeScript client for the TrustGuard runtime evaluate API (`POST /v1/evaluate`). Configure a base URL and an API key, send the payload you want evaluated, and act on the verdict: TrustGuard detects, you enforce.
|
|
4
7
|
|
|
5
8
|
## Install
|
|
6
9
|
|
|
@@ -20,8 +23,8 @@ const client = new TrustGuard({
|
|
|
20
23
|
apiKey: process.env.TRUSTGUARD_API_KEY!,
|
|
21
24
|
});
|
|
22
25
|
|
|
23
|
-
const response = await client.guard({
|
|
24
|
-
if (response.
|
|
26
|
+
const response = await client.guard({ payload: { input: "user text to evaluate" } });
|
|
27
|
+
if (response.isBlocked) {
|
|
25
28
|
// block the request
|
|
26
29
|
}
|
|
27
30
|
```
|
|
@@ -30,20 +33,22 @@ if (response.isFlagged) {
|
|
|
30
33
|
|
|
31
34
|
```typescript
|
|
32
35
|
const response = await client.guard({
|
|
33
|
-
|
|
36
|
+
payload: { input: "user text" },
|
|
34
37
|
direction: "output", // "input" (default) or "output"
|
|
38
|
+
protocol: "llm", // "all" (default), "llm", "mcp", or "a2a"
|
|
35
39
|
sessionId: "conversation-42", // groups multi-turn traffic
|
|
36
40
|
consumerId: "user-7", // the end user behind the request
|
|
41
|
+
attributes: { content_type: "text/plain" }, // routing hints
|
|
37
42
|
});
|
|
38
43
|
```
|
|
39
44
|
|
|
40
45
|
### Attachments
|
|
41
46
|
|
|
42
|
-
Documents are base64-encoded into `
|
|
47
|
+
Documents are base64-encoded into `payload.attachments` for file-aware plugins (or pass a `url` for the server to fetch):
|
|
43
48
|
|
|
44
49
|
```typescript
|
|
45
50
|
const response = await client.guard({
|
|
46
|
-
|
|
51
|
+
payload: { input: "summarize this file" },
|
|
47
52
|
attachments: [{ filename: "doc.pdf", contentType: "application/pdf", data: pdfBytes }],
|
|
48
53
|
});
|
|
49
54
|
```
|
|
@@ -52,8 +57,8 @@ const response = await client.guard({
|
|
|
52
57
|
|
|
53
58
|
| Field | Meaning |
|
|
54
59
|
|---|---|
|
|
55
|
-
| `
|
|
56
|
-
| `findings` |
|
|
60
|
+
| `status` | Most restrictive verdict: `allow`, `block`, `transform`, `report`, or `""` when omitted. `isBlocked` is `true` when it is `block` |
|
|
61
|
+
| `findings` | Nested findings: `source` / `signal` / `outcome` / `evidence` (observational runs omit `signal`/`outcome`) |
|
|
57
62
|
| `transformedPayload` | The payload as rewritten by in-flight masking, `null` when untouched |
|
|
58
63
|
| `traceId` / `requestId` | Correlation ids for TrustGuard telemetry |
|
|
59
64
|
|
|
@@ -65,7 +70,7 @@ Non-2xx responses throw `TrustGuardAPIError` with `status`, `traceId` and `reque
|
|
|
65
70
|
import { TrustGuardAPIError } from "@neuraltrust/trustguard-sdk";
|
|
66
71
|
|
|
67
72
|
try {
|
|
68
|
-
await client.guard({
|
|
73
|
+
await client.guard({ payload: { input: "..." } });
|
|
69
74
|
} catch (err) {
|
|
70
75
|
if (err instanceof TrustGuardAPIError && err.status === 401) {
|
|
71
76
|
// bad API key
|
|
@@ -73,6 +78,17 @@ try {
|
|
|
73
78
|
}
|
|
74
79
|
```
|
|
75
80
|
|
|
81
|
+
## Documentation
|
|
82
|
+
|
|
83
|
+
The full guide is at [docs.neuraltrust.ai](https://docs.neuraltrust.ai/sdks/trustguard/node): setting up the collector
|
|
84
|
+
and its key, guarding input and output, configuration, the attributes
|
|
85
|
+
an evaluation carries, and troubleshooting. The [Evaluate API](https://docs.neuraltrust.ai/trustguard/api/evaluate)
|
|
86
|
+
is the contract every SDK wraps, and [SDKs](https://docs.neuraltrust.ai/sdks/overview) says when to reach
|
|
87
|
+
for TrustGuard and when for TrustGate.
|
|
88
|
+
|
|
89
|
+
The same client in other languages: [Python](https://pypi.org/project/trustguard-sdk/), [Go](https://pkg.go.dev/github.com/NeuralTrust/trustguard-sdk/go). Source, examples and issues:
|
|
90
|
+
[github.com/NeuralTrust/trustguard-sdk](https://github.com/NeuralTrust/trustguard-sdk).
|
|
91
|
+
|
|
76
92
|
## Development
|
|
77
93
|
|
|
78
94
|
```bash
|
package/dist/index.cjs
CHANGED
|
@@ -40,7 +40,7 @@ var TrustGuardAPIError = class extends Error {
|
|
|
40
40
|
};
|
|
41
41
|
|
|
42
42
|
// src/client.ts
|
|
43
|
-
var
|
|
43
|
+
var EVALUATE_PATH = "/v1/evaluate";
|
|
44
44
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
45
45
|
var TrustGuard = class {
|
|
46
46
|
#baseUrl;
|
|
@@ -65,10 +65,10 @@ var TrustGuard = class {
|
|
|
65
65
|
* returns the verdict. Throws TrustGuardAPIError on non-2xx responses.
|
|
66
66
|
*/
|
|
67
67
|
async guard(request) {
|
|
68
|
-
if (!request.
|
|
69
|
-
throw new Error("TrustGuard: request
|
|
68
|
+
if (!request.payload) {
|
|
69
|
+
throw new Error("TrustGuard: request payload is required");
|
|
70
70
|
}
|
|
71
|
-
const response = await this.#fetch(this.#baseUrl +
|
|
71
|
+
const response = await this.#fetch(this.#baseUrl + EVALUATE_PATH, {
|
|
72
72
|
method: "POST",
|
|
73
73
|
headers: {
|
|
74
74
|
Authorization: `Bearer ${this.#apiKey}`,
|
|
@@ -85,44 +85,69 @@ var TrustGuard = class {
|
|
|
85
85
|
}
|
|
86
86
|
};
|
|
87
87
|
function serializeRequest(request) {
|
|
88
|
-
|
|
88
|
+
let payload = request.payload;
|
|
89
|
+
if (request.attachments?.length) {
|
|
90
|
+
payload = { ...payload, attachments: request.attachments.map(serializeAttachment) };
|
|
91
|
+
}
|
|
92
|
+
const body = { payload };
|
|
89
93
|
if (request.direction) body.direction = request.direction;
|
|
94
|
+
if (request.protocol) body.protocol = request.protocol;
|
|
90
95
|
if (request.sessionId) body.session_id = request.sessionId;
|
|
91
96
|
if (request.consumerId) body.consumer_id = request.consumerId;
|
|
92
|
-
|
|
93
|
-
if (request.attachments?.length) {
|
|
94
|
-
metadata = { ...metadata, attachments: request.attachments.map(serializeAttachment) };
|
|
95
|
-
}
|
|
96
|
-
if (metadata && Object.keys(metadata).length > 0) body.metadata = metadata;
|
|
97
|
+
if (request.attributes && Object.keys(request.attributes).length > 0) body.attributes = request.attributes;
|
|
97
98
|
return body;
|
|
98
99
|
}
|
|
99
100
|
function serializeAttachment(attachment) {
|
|
100
|
-
const
|
|
101
|
-
return {
|
|
101
|
+
const entry = {
|
|
102
102
|
filename: attachment.filename,
|
|
103
|
-
content_type: attachment.contentType
|
|
104
|
-
data: bytes.toString("base64")
|
|
103
|
+
content_type: attachment.contentType
|
|
105
104
|
};
|
|
105
|
+
if (attachment.data !== void 0) {
|
|
106
|
+
const bytes = typeof attachment.data === "string" ? Buffer.from(attachment.data, "utf-8") : Buffer.from(attachment.data);
|
|
107
|
+
entry.data = bytes.toString("base64");
|
|
108
|
+
}
|
|
109
|
+
if (attachment.url !== void 0) entry.url = attachment.url;
|
|
110
|
+
return entry;
|
|
106
111
|
}
|
|
107
112
|
function deserializeResponse(wire) {
|
|
113
|
+
const status = wire.status ?? "";
|
|
108
114
|
return {
|
|
109
|
-
|
|
115
|
+
status,
|
|
116
|
+
isBlocked: status === "block",
|
|
110
117
|
transformedPayload: wire.transformed_payload ?? null,
|
|
111
|
-
findings: (wire.findings ?? []).map(
|
|
112
|
-
(f) => ({
|
|
113
|
-
detectionType: f.detection_type,
|
|
114
|
-
confidence: f.confidence,
|
|
115
|
-
ruleName: f.rule_name,
|
|
116
|
-
details: f.details
|
|
117
|
-
})
|
|
118
|
-
),
|
|
118
|
+
findings: (wire.findings ?? []).map(deserializeFinding),
|
|
119
119
|
traceId: wire.trace_id ?? "",
|
|
120
120
|
requestId: wire.request_id ?? ""
|
|
121
121
|
};
|
|
122
122
|
}
|
|
123
|
+
function deserializeFinding(f) {
|
|
124
|
+
const sourceWire = f.source ?? {};
|
|
125
|
+
const source = {
|
|
126
|
+
kind: sourceWire.kind ?? ""
|
|
127
|
+
};
|
|
128
|
+
if (sourceWire.plugin !== void 0) source.plugin = sourceWire.plugin;
|
|
129
|
+
if (sourceWire.detector_id !== void 0) source.detectorId = sourceWire.detector_id;
|
|
130
|
+
if (sourceWire.detector_name !== void 0) source.detectorName = sourceWire.detector_name;
|
|
131
|
+
if (sourceWire.policy_id !== void 0) source.policyId = sourceWire.policy_id;
|
|
132
|
+
if (sourceWire.gate_name !== void 0) source.gateName = sourceWire.gate_name;
|
|
133
|
+
const finding = { source };
|
|
134
|
+
if (f.signal?.type) {
|
|
135
|
+
const signal = { type: f.signal.type };
|
|
136
|
+
if (f.signal.confidence !== void 0) signal.confidence = f.signal.confidence;
|
|
137
|
+
finding.signal = signal;
|
|
138
|
+
}
|
|
139
|
+
if (f.outcome?.action) {
|
|
140
|
+
const outcome = { action: f.outcome.action };
|
|
141
|
+
finding.outcome = outcome;
|
|
142
|
+
}
|
|
143
|
+
if (f.evidence && Object.keys(f.evidence).length > 0) {
|
|
144
|
+
finding.evidence = f.evidence;
|
|
145
|
+
}
|
|
146
|
+
return finding;
|
|
147
|
+
}
|
|
123
148
|
function apiError(status, text) {
|
|
124
149
|
const payload = parseJson(text);
|
|
125
|
-
const message = payload?.error || text.trim() || `HTTP ${status}`;
|
|
150
|
+
const message = payload?.error || payload?.message || text.trim() || `HTTP ${status}`;
|
|
126
151
|
return new TrustGuardAPIError(status, message, payload?.trace_id ?? "", payload?.request_id ?? "");
|
|
127
152
|
}
|
|
128
153
|
function parseJson(text) {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export { TrustGuard } from \"./client.js\";\nexport { TrustGuardAPIError } from \"./errors.js\";\nexport type {\n Attachment,\n Direction,\n Finding,\n GuardRequest,\n GuardResponse,\n TrustGuardOptions,\n} from \"./types.js\";\n","/**\n * A non-2xx response from the TrustGuard API, carrying the status code and the\n * correlation ids needed to chase the request in telemetry. Transport-level\n * failures (network errors, timeouts) are thrown as-is instead.\n */\nexport class TrustGuardAPIError extends Error {\n readonly status: number;\n readonly traceId: string;\n readonly requestId: string;\n\n constructor(status: number, message: string, traceId: string, requestId: string) {\n super(`TrustGuard API error ${status}: ${message} (trace_id=${traceId}, request_id=${requestId})`);\n this.name = \"TrustGuardAPIError\";\n this.status = status;\n this.traceId = traceId;\n this.requestId = requestId;\n }\n}\n","import { TrustGuardAPIError } from \"./errors.js\";\nimport type { Attachment, Finding, GuardRequest, GuardResponse, TrustGuardOptions } from \"./types.js\";\n\nconst GUARD_PATH = \"/v1/guard\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\ninterface WireFinding {\n detection_type?: string;\n confidence?: number;\n rule_name?: string;\n details?: unknown;\n}\n\ninterface WireResponse {\n is_flagged?: boolean;\n transformed_payload?: Record<string, unknown> | null;\n findings?: WireFinding[];\n trace_id?: string;\n request_id?: string;\n}\n\n/** Client for the TrustGuard runtime guard API. */\nexport class TrustGuard {\n readonly #baseUrl: string;\n readonly #apiKey: string;\n readonly #timeoutMs: number;\n readonly #fetch: typeof fetch;\n\n constructor(options: TrustGuardOptions) {\n const baseUrl = options.baseUrl?.trim().replace(/\\/+$/, \"\");\n if (!baseUrl) {\n throw new Error(\"TrustGuard: baseUrl is required\");\n }\n if (!options.apiKey?.trim()) {\n throw new Error(\"TrustGuard: apiKey is required\");\n }\n this.#baseUrl = baseUrl;\n this.#apiKey = options.apiKey;\n this.#timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.#fetch = options.fetch ?? globalThis.fetch;\n }\n\n /**\n * Evaluates the request against the policy attached to the API key and\n * returns the verdict. Throws TrustGuardAPIError on non-2xx responses.\n */\n async guard(request: GuardRequest): Promise<GuardResponse> {\n if (!request.input) {\n throw new Error(\"TrustGuard: request input is required\");\n }\n\n const response = await this.#fetch(this.#baseUrl + GUARD_PATH, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.#apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(serializeRequest(request)),\n signal: AbortSignal.timeout(this.#timeoutMs),\n });\n\n const text = await response.text();\n if (!response.ok) {\n throw apiError(response.status, text);\n }\n\n return deserializeResponse(parseJson(text) ?? {});\n }\n}\n\n/** Maps the camelCase request onto the snake_case wire format, omitting empty optionals (the server rejects unknown top-level fields). */\nfunction serializeRequest(request: GuardRequest): Record<string, unknown> {\n const body: Record<string, unknown> = { input: request.input };\n if (request.direction) body.direction = request.direction;\n if (request.sessionId) body.session_id = request.sessionId;\n if (request.consumerId) body.consumer_id = request.consumerId;\n\n let metadata = request.metadata;\n if (request.attachments?.length) {\n metadata = { ...metadata, attachments: request.attachments.map(serializeAttachment) };\n }\n if (metadata && Object.keys(metadata).length > 0) body.metadata = metadata;\n return body;\n}\n\nfunction serializeAttachment(attachment: Attachment): Record<string, string> {\n const bytes =\n typeof attachment.data === \"string\" ? Buffer.from(attachment.data, \"utf-8\") : Buffer.from(attachment.data);\n return {\n filename: attachment.filename,\n content_type: attachment.contentType,\n data: bytes.toString(\"base64\"),\n };\n}\n\nfunction deserializeResponse(wire: WireResponse): GuardResponse {\n return {\n isFlagged: wire.is_flagged ?? false,\n transformedPayload: wire.transformed_payload ?? null,\n findings: (wire.findings ?? []).map(\n (f): Finding => ({\n detectionType: f.detection_type,\n confidence: f.confidence,\n ruleName: f.rule_name,\n details: f.details,\n }),\n ),\n traceId: wire.trace_id ?? \"\",\n requestId: wire.request_id ?? \"\",\n };\n}\n\nfunction apiError(status: number, text: string): TrustGuardAPIError {\n const payload = parseJson(text) as { error?: string; trace_id?: string; request_id?: string } | undefined;\n const message = payload?.error || text.trim() || `HTTP ${status}`;\n return new TrustGuardAPIError(status, message, payload?.trace_id ?? \"\", payload?.request_id ?? \"\");\n}\n\nfunction parseJson(text: string): WireResponse | undefined {\n try {\n return JSON.parse(text) as WireResponse;\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export { TrustGuard } from \"./client.js\";\nexport { TrustGuardAPIError } from \"./errors.js\";\nexport type {\n Attachment,\n Direction,\n Finding,\n FindingOutcome,\n FindingSignal,\n FindingSource,\n GuardRequest,\n GuardResponse,\n Protocol,\n TrustGuardOptions,\n} from \"./types.js\";\n","/**\n * A non-2xx response from the TrustGuard API, carrying the status code and the\n * correlation ids needed to chase the request in telemetry. Transport-level\n * failures (network errors, timeouts) are thrown as-is instead.\n */\nexport class TrustGuardAPIError extends Error {\n readonly status: number;\n readonly traceId: string;\n readonly requestId: string;\n\n constructor(status: number, message: string, traceId: string, requestId: string) {\n super(`TrustGuard API error ${status}: ${message} (trace_id=${traceId}, request_id=${requestId})`);\n this.name = \"TrustGuardAPIError\";\n this.status = status;\n this.traceId = traceId;\n this.requestId = requestId;\n }\n}\n","import { TrustGuardAPIError } from \"./errors.js\";\nimport type {\n Attachment,\n Finding,\n FindingOutcome,\n FindingSignal,\n FindingSource,\n GuardRequest,\n GuardResponse,\n TrustGuardOptions,\n} from \"./types.js\";\n\nconst EVALUATE_PATH = \"/v1/evaluate\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\ninterface WireFindingSource {\n kind?: string;\n plugin?: string;\n detector_id?: string;\n detector_name?: string;\n policy_id?: string;\n gate_name?: string;\n}\n\ninterface WireFindingSignal {\n type?: string;\n confidence?: number;\n}\n\ninterface WireFindingOutcome {\n action?: string;\n}\n\ninterface WireFinding {\n source?: WireFindingSource;\n signal?: WireFindingSignal;\n outcome?: WireFindingOutcome;\n evidence?: Record<string, unknown>;\n}\n\ninterface WireResponse {\n status?: string;\n transformed_payload?: Record<string, unknown> | null;\n findings?: WireFinding[];\n trace_id?: string;\n request_id?: string;\n}\n\n/** Client for the TrustGuard runtime evaluate API. */\nexport class TrustGuard {\n readonly #baseUrl: string;\n readonly #apiKey: string;\n readonly #timeoutMs: number;\n readonly #fetch: typeof fetch;\n\n constructor(options: TrustGuardOptions) {\n const baseUrl = options.baseUrl?.trim().replace(/\\/+$/, \"\");\n if (!baseUrl) {\n throw new Error(\"TrustGuard: baseUrl is required\");\n }\n if (!options.apiKey?.trim()) {\n throw new Error(\"TrustGuard: apiKey is required\");\n }\n this.#baseUrl = baseUrl;\n this.#apiKey = options.apiKey;\n this.#timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.#fetch = options.fetch ?? globalThis.fetch;\n }\n\n /**\n * Evaluates the request against the policy attached to the API key and\n * returns the verdict. Throws TrustGuardAPIError on non-2xx responses.\n */\n async guard(request: GuardRequest): Promise<GuardResponse> {\n if (!request.payload) {\n throw new Error(\"TrustGuard: request payload is required\");\n }\n\n const response = await this.#fetch(this.#baseUrl + EVALUATE_PATH, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.#apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(serializeRequest(request)),\n signal: AbortSignal.timeout(this.#timeoutMs),\n });\n\n const text = await response.text();\n if (!response.ok) {\n throw apiError(response.status, text);\n }\n\n return deserializeResponse(parseJson(text) ?? {});\n }\n}\n\n/** Maps the camelCase request onto the snake_case wire format, omitting empty optionals (the server rejects unknown top-level fields). */\nfunction serializeRequest(request: GuardRequest): Record<string, unknown> {\n let payload = request.payload;\n if (request.attachments?.length) {\n payload = { ...payload, attachments: request.attachments.map(serializeAttachment) };\n }\n const body: Record<string, unknown> = { payload };\n if (request.direction) body.direction = request.direction;\n if (request.protocol) body.protocol = request.protocol;\n if (request.sessionId) body.session_id = request.sessionId;\n if (request.consumerId) body.consumer_id = request.consumerId;\n if (request.attributes && Object.keys(request.attributes).length > 0) body.attributes = request.attributes;\n return body;\n}\n\nfunction serializeAttachment(attachment: Attachment): Record<string, string> {\n const entry: Record<string, string> = {\n filename: attachment.filename,\n content_type: attachment.contentType,\n };\n if (attachment.data !== undefined) {\n const bytes =\n typeof attachment.data === \"string\" ? Buffer.from(attachment.data, \"utf-8\") : Buffer.from(attachment.data);\n entry.data = bytes.toString(\"base64\");\n }\n if (attachment.url !== undefined) entry.url = attachment.url;\n return entry;\n}\n\nfunction deserializeResponse(wire: WireResponse): GuardResponse {\n const status = wire.status ?? \"\";\n return {\n status,\n isBlocked: status === \"block\",\n transformedPayload: wire.transformed_payload ?? null,\n findings: (wire.findings ?? []).map(deserializeFinding),\n traceId: wire.trace_id ?? \"\",\n requestId: wire.request_id ?? \"\",\n };\n}\n\nfunction deserializeFinding(f: WireFinding): Finding {\n const sourceWire = f.source ?? {};\n const source: FindingSource = {\n kind: sourceWire.kind ?? \"\",\n };\n if (sourceWire.plugin !== undefined) source.plugin = sourceWire.plugin;\n if (sourceWire.detector_id !== undefined) source.detectorId = sourceWire.detector_id;\n if (sourceWire.detector_name !== undefined) source.detectorName = sourceWire.detector_name;\n if (sourceWire.policy_id !== undefined) source.policyId = sourceWire.policy_id;\n if (sourceWire.gate_name !== undefined) source.gateName = sourceWire.gate_name;\n\n const finding: Finding = { source };\n if (f.signal?.type) {\n const signal: FindingSignal = { type: f.signal.type };\n if (f.signal.confidence !== undefined) signal.confidence = f.signal.confidence;\n finding.signal = signal;\n }\n if (f.outcome?.action) {\n const outcome: FindingOutcome = { action: f.outcome.action };\n finding.outcome = outcome;\n }\n if (f.evidence && Object.keys(f.evidence).length > 0) {\n finding.evidence = f.evidence;\n }\n return finding;\n}\n\nfunction apiError(status: number, text: string): TrustGuardAPIError {\n const payload = parseJson(text) as { error?: string; message?: string; trace_id?: string; request_id?: string } | undefined;\n const message = payload?.error || payload?.message || text.trim() || `HTTP ${status}`;\n return new TrustGuardAPIError(status, message, payload?.trace_id ?? \"\", payload?.request_id ?? \"\");\n}\n\nfunction parseJson(text: string): WireResponse | undefined {\n try {\n return JSON.parse(text) as WireResponse;\n } catch {\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKO,IAAM,qBAAN,cAAiC,MAAM;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,QAAgB,SAAiB,SAAiB,WAAmB;AAC/E,UAAM,wBAAwB,MAAM,KAAK,OAAO,cAAc,OAAO,gBAAgB,SAAS,GAAG;AACjG,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,YAAY;AAAA,EACnB;AACF;;;ACLA,IAAM,gBAAgB;AACtB,IAAM,qBAAqB;AAoCpB,IAAM,aAAN,MAAiB;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAA4B;AACtC,UAAM,UAAU,QAAQ,SAAS,KAAK,EAAE,QAAQ,QAAQ,EAAE;AAC1D,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,QAAI,CAAC,QAAQ,QAAQ,KAAK,GAAG;AAC3B,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,SAAK,WAAW;AAChB,SAAK,UAAU,QAAQ;AACvB,SAAK,aAAa,QAAQ,aAAa;AACvC,SAAK,SAAS,QAAQ,SAAS,WAAW;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAM,SAA+C;AACzD,QAAI,CAAC,QAAQ,SAAS;AACpB,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAEA,UAAM,WAAW,MAAM,KAAK,OAAO,KAAK,WAAW,eAAe;AAAA,MAChE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,KAAK,OAAO;AAAA,QACrC,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU,iBAAiB,OAAO,CAAC;AAAA,MAC9C,QAAQ,YAAY,QAAQ,KAAK,UAAU;AAAA,IAC7C,CAAC;AAED,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,SAAS,SAAS,QAAQ,IAAI;AAAA,IACtC;AAEA,WAAO,oBAAoB,UAAU,IAAI,KAAK,CAAC,CAAC;AAAA,EAClD;AACF;AAGA,SAAS,iBAAiB,SAAgD;AACxE,MAAI,UAAU,QAAQ;AACtB,MAAI,QAAQ,aAAa,QAAQ;AAC/B,cAAU,EAAE,GAAG,SAAS,aAAa,QAAQ,YAAY,IAAI,mBAAmB,EAAE;AAAA,EACpF;AACA,QAAM,OAAgC,EAAE,QAAQ;AAChD,MAAI,QAAQ,UAAW,MAAK,YAAY,QAAQ;AAChD,MAAI,QAAQ,SAAU,MAAK,WAAW,QAAQ;AAC9C,MAAI,QAAQ,UAAW,MAAK,aAAa,QAAQ;AACjD,MAAI,QAAQ,WAAY,MAAK,cAAc,QAAQ;AACnD,MAAI,QAAQ,cAAc,OAAO,KAAK,QAAQ,UAAU,EAAE,SAAS,EAAG,MAAK,aAAa,QAAQ;AAChG,SAAO;AACT;AAEA,SAAS,oBAAoB,YAAgD;AAC3E,QAAM,QAAgC;AAAA,IACpC,UAAU,WAAW;AAAA,IACrB,cAAc,WAAW;AAAA,EAC3B;AACA,MAAI,WAAW,SAAS,QAAW;AACjC,UAAM,QACJ,OAAO,WAAW,SAAS,WAAW,OAAO,KAAK,WAAW,MAAM,OAAO,IAAI,OAAO,KAAK,WAAW,IAAI;AAC3G,UAAM,OAAO,MAAM,SAAS,QAAQ;AAAA,EACtC;AACA,MAAI,WAAW,QAAQ,OAAW,OAAM,MAAM,WAAW;AACzD,SAAO;AACT;AAEA,SAAS,oBAAoB,MAAmC;AAC9D,QAAM,SAAS,KAAK,UAAU;AAC9B,SAAO;AAAA,IACL;AAAA,IACA,WAAW,WAAW;AAAA,IACtB,oBAAoB,KAAK,uBAAuB;AAAA,IAChD,WAAW,KAAK,YAAY,CAAC,GAAG,IAAI,kBAAkB;AAAA,IACtD,SAAS,KAAK,YAAY;AAAA,IAC1B,WAAW,KAAK,cAAc;AAAA,EAChC;AACF;AAEA,SAAS,mBAAmB,GAAyB;AACnD,QAAM,aAAa,EAAE,UAAU,CAAC;AAChC,QAAM,SAAwB;AAAA,IAC5B,MAAM,WAAW,QAAQ;AAAA,EAC3B;AACA,MAAI,WAAW,WAAW,OAAW,QAAO,SAAS,WAAW;AAChE,MAAI,WAAW,gBAAgB,OAAW,QAAO,aAAa,WAAW;AACzE,MAAI,WAAW,kBAAkB,OAAW,QAAO,eAAe,WAAW;AAC7E,MAAI,WAAW,cAAc,OAAW,QAAO,WAAW,WAAW;AACrE,MAAI,WAAW,cAAc,OAAW,QAAO,WAAW,WAAW;AAErE,QAAM,UAAmB,EAAE,OAAO;AAClC,MAAI,EAAE,QAAQ,MAAM;AAClB,UAAM,SAAwB,EAAE,MAAM,EAAE,OAAO,KAAK;AACpD,QAAI,EAAE,OAAO,eAAe,OAAW,QAAO,aAAa,EAAE,OAAO;AACpE,YAAQ,SAAS;AAAA,EACnB;AACA,MAAI,EAAE,SAAS,QAAQ;AACrB,UAAM,UAA0B,EAAE,QAAQ,EAAE,QAAQ,OAAO;AAC3D,YAAQ,UAAU;AAAA,EACpB;AACA,MAAI,EAAE,YAAY,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,GAAG;AACpD,YAAQ,WAAW,EAAE;AAAA,EACvB;AACA,SAAO;AACT;AAEA,SAAS,SAAS,QAAgB,MAAkC;AAClE,QAAM,UAAU,UAAU,IAAI;AAC9B,QAAM,UAAU,SAAS,SAAS,SAAS,WAAW,KAAK,KAAK,KAAK,QAAQ,MAAM;AACnF,SAAO,IAAI,mBAAmB,QAAQ,SAAS,SAAS,YAAY,IAAI,SAAS,cAAc,EAAE;AACnG;AAEA,SAAS,UAAU,MAAwC;AACzD,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,47 +1,73 @@
|
|
|
1
1
|
/** Traffic side being evaluated; rules are scoped per side. Defaults to "input" server-side. */
|
|
2
2
|
type Direction = "input" | "output";
|
|
3
|
+
/** Traffic protocol the policy rules are scoped to. Defaults to "all" server-side. */
|
|
4
|
+
type Protocol = "all" | "llm" | "mcp" | "a2a";
|
|
3
5
|
/** A document evaluated alongside the payload by file-aware plugins. */
|
|
4
6
|
interface Attachment {
|
|
5
7
|
filename: string;
|
|
6
8
|
contentType: string;
|
|
7
|
-
/** Raw file content; strings are encoded as UTF-8
|
|
8
|
-
data
|
|
9
|
+
/** Raw file content; strings are encoded as UTF-8, then base64 on the wire. Provide `data` or `url`. */
|
|
10
|
+
data?: Uint8Array | string;
|
|
11
|
+
/** URL for the server to fetch instead of inlining `data`. */
|
|
12
|
+
url?: string;
|
|
9
13
|
}
|
|
10
|
-
/** Payload for a guard evaluation. */
|
|
14
|
+
/** Payload for a guard evaluation (`POST /v1/evaluate`). */
|
|
11
15
|
interface GuardRequest {
|
|
12
|
-
/** The
|
|
13
|
-
|
|
16
|
+
/** The content to evaluate, e.g. `{ input: "..." }` or provider-shaped fields. Required. */
|
|
17
|
+
payload: Record<string, unknown>;
|
|
14
18
|
/** Traffic side; the server defaults to "input" when omitted. */
|
|
15
19
|
direction?: Direction;
|
|
20
|
+
/** Traffic protocol; the server defaults to "all" when omitted. */
|
|
21
|
+
protocol?: Protocol;
|
|
16
22
|
/** Groups multi-turn traffic; the server synthesises one when omitted. */
|
|
17
23
|
sessionId?: string;
|
|
18
24
|
/** Identifies the end user on whose behalf the request runs. */
|
|
19
25
|
consumerId?: string;
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
*/
|
|
24
|
-
metadata?: Record<string, unknown>;
|
|
25
|
-
/** Documents to evaluate; folded into `metadata.attachments` on the wire. */
|
|
26
|
+
/** Optional routing hints. Server-side key: `content_type` (overrides the payload content type). */
|
|
27
|
+
attributes?: Record<string, unknown>;
|
|
28
|
+
/** Documents to evaluate; folded into `payload.attachments` on the wire. */
|
|
26
29
|
attachments?: Attachment[];
|
|
27
30
|
}
|
|
28
|
-
/**
|
|
29
|
-
interface
|
|
30
|
-
|
|
31
|
+
/** Who produced the finding — a detector or a gate. */
|
|
32
|
+
interface FindingSource {
|
|
33
|
+
kind: string;
|
|
34
|
+
plugin?: string;
|
|
35
|
+
detectorId?: string;
|
|
36
|
+
detectorName?: string;
|
|
37
|
+
policyId?: string;
|
|
38
|
+
gateName?: string;
|
|
39
|
+
}
|
|
40
|
+
/** Detection signal when the finding fired (omitted for observational-only runs). */
|
|
41
|
+
interface FindingSignal {
|
|
42
|
+
type: string;
|
|
31
43
|
confidence?: number;
|
|
32
|
-
|
|
33
|
-
|
|
44
|
+
}
|
|
45
|
+
/** Applied execution-rule action when the finding enforced an outcome. */
|
|
46
|
+
interface FindingOutcome {
|
|
47
|
+
action: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A single finding from the evaluate response.
|
|
51
|
+
* Observational (below-threshold) runs keep `source` + `evidence` only.
|
|
52
|
+
*/
|
|
53
|
+
interface Finding {
|
|
54
|
+
source: FindingSource;
|
|
55
|
+
signal?: FindingSignal;
|
|
56
|
+
outcome?: FindingOutcome;
|
|
57
|
+
evidence?: Record<string, unknown>;
|
|
34
58
|
}
|
|
35
59
|
/**
|
|
36
|
-
* Verdict returned by POST /v1/
|
|
37
|
-
* block when `
|
|
60
|
+
* Verdict returned by POST /v1/evaluate. TrustGuard detects; the caller enforces:
|
|
61
|
+
* block when `status` is "block" (`isBlocked` is the convenience signal).
|
|
38
62
|
*/
|
|
39
63
|
interface GuardResponse {
|
|
40
|
-
/**
|
|
41
|
-
|
|
64
|
+
/** Most restrictive verdict: "allow", "block", "transform", "report", or "" when omitted. */
|
|
65
|
+
status: string;
|
|
66
|
+
/** Convenience flag: true when `status === "block"`. */
|
|
67
|
+
isBlocked: boolean;
|
|
42
68
|
/** The payload as rewritten by in-flight masking, null when untouched. */
|
|
43
69
|
transformedPayload: Record<string, unknown> | null;
|
|
44
|
-
/** What every plugin in the policy chain reported. */
|
|
70
|
+
/** What every plugin / gate in the policy chain reported. */
|
|
45
71
|
findings: Finding[];
|
|
46
72
|
/** Correlation ids for TrustGuard telemetry. */
|
|
47
73
|
traceId: string;
|
|
@@ -49,7 +75,7 @@ interface GuardResponse {
|
|
|
49
75
|
}
|
|
50
76
|
/** Configuration for the TrustGuard client. */
|
|
51
77
|
interface TrustGuardOptions {
|
|
52
|
-
/** Base URL of the TrustGuard deployment, e.g. https://
|
|
78
|
+
/** Base URL of the TrustGuard deployment, e.g. https://trustguard.neuraltrust.ai */
|
|
53
79
|
baseUrl: string;
|
|
54
80
|
/** Collector API key, sent as a Bearer token. */
|
|
55
81
|
apiKey: string;
|
|
@@ -59,7 +85,7 @@ interface TrustGuardOptions {
|
|
|
59
85
|
fetch?: typeof fetch;
|
|
60
86
|
}
|
|
61
87
|
|
|
62
|
-
/** Client for the TrustGuard runtime
|
|
88
|
+
/** Client for the TrustGuard runtime evaluate API. */
|
|
63
89
|
declare class TrustGuard {
|
|
64
90
|
#private;
|
|
65
91
|
constructor(options: TrustGuardOptions);
|
|
@@ -82,4 +108,4 @@ declare class TrustGuardAPIError extends Error {
|
|
|
82
108
|
constructor(status: number, message: string, traceId: string, requestId: string);
|
|
83
109
|
}
|
|
84
110
|
|
|
85
|
-
export { type Attachment, type Direction, type Finding, type GuardRequest, type GuardResponse, TrustGuard, TrustGuardAPIError, type TrustGuardOptions };
|
|
111
|
+
export { type Attachment, type Direction, type Finding, type FindingOutcome, type FindingSignal, type FindingSource, type GuardRequest, type GuardResponse, type Protocol, TrustGuard, TrustGuardAPIError, type TrustGuardOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,47 +1,73 @@
|
|
|
1
1
|
/** Traffic side being evaluated; rules are scoped per side. Defaults to "input" server-side. */
|
|
2
2
|
type Direction = "input" | "output";
|
|
3
|
+
/** Traffic protocol the policy rules are scoped to. Defaults to "all" server-side. */
|
|
4
|
+
type Protocol = "all" | "llm" | "mcp" | "a2a";
|
|
3
5
|
/** A document evaluated alongside the payload by file-aware plugins. */
|
|
4
6
|
interface Attachment {
|
|
5
7
|
filename: string;
|
|
6
8
|
contentType: string;
|
|
7
|
-
/** Raw file content; strings are encoded as UTF-8
|
|
8
|
-
data
|
|
9
|
+
/** Raw file content; strings are encoded as UTF-8, then base64 on the wire. Provide `data` or `url`. */
|
|
10
|
+
data?: Uint8Array | string;
|
|
11
|
+
/** URL for the server to fetch instead of inlining `data`. */
|
|
12
|
+
url?: string;
|
|
9
13
|
}
|
|
10
|
-
/** Payload for a guard evaluation. */
|
|
14
|
+
/** Payload for a guard evaluation (`POST /v1/evaluate`). */
|
|
11
15
|
interface GuardRequest {
|
|
12
|
-
/** The
|
|
13
|
-
|
|
16
|
+
/** The content to evaluate, e.g. `{ input: "..." }` or provider-shaped fields. Required. */
|
|
17
|
+
payload: Record<string, unknown>;
|
|
14
18
|
/** Traffic side; the server defaults to "input" when omitted. */
|
|
15
19
|
direction?: Direction;
|
|
20
|
+
/** Traffic protocol; the server defaults to "all" when omitted. */
|
|
21
|
+
protocol?: Protocol;
|
|
16
22
|
/** Groups multi-turn traffic; the server synthesises one when omitted. */
|
|
17
23
|
sessionId?: string;
|
|
18
24
|
/** Identifies the end user on whose behalf the request runs. */
|
|
19
25
|
consumerId?: string;
|
|
20
|
-
/**
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
*/
|
|
24
|
-
metadata?: Record<string, unknown>;
|
|
25
|
-
/** Documents to evaluate; folded into `metadata.attachments` on the wire. */
|
|
26
|
+
/** Optional routing hints. Server-side key: `content_type` (overrides the payload content type). */
|
|
27
|
+
attributes?: Record<string, unknown>;
|
|
28
|
+
/** Documents to evaluate; folded into `payload.attachments` on the wire. */
|
|
26
29
|
attachments?: Attachment[];
|
|
27
30
|
}
|
|
28
|
-
/**
|
|
29
|
-
interface
|
|
30
|
-
|
|
31
|
+
/** Who produced the finding — a detector or a gate. */
|
|
32
|
+
interface FindingSource {
|
|
33
|
+
kind: string;
|
|
34
|
+
plugin?: string;
|
|
35
|
+
detectorId?: string;
|
|
36
|
+
detectorName?: string;
|
|
37
|
+
policyId?: string;
|
|
38
|
+
gateName?: string;
|
|
39
|
+
}
|
|
40
|
+
/** Detection signal when the finding fired (omitted for observational-only runs). */
|
|
41
|
+
interface FindingSignal {
|
|
42
|
+
type: string;
|
|
31
43
|
confidence?: number;
|
|
32
|
-
|
|
33
|
-
|
|
44
|
+
}
|
|
45
|
+
/** Applied execution-rule action when the finding enforced an outcome. */
|
|
46
|
+
interface FindingOutcome {
|
|
47
|
+
action: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A single finding from the evaluate response.
|
|
51
|
+
* Observational (below-threshold) runs keep `source` + `evidence` only.
|
|
52
|
+
*/
|
|
53
|
+
interface Finding {
|
|
54
|
+
source: FindingSource;
|
|
55
|
+
signal?: FindingSignal;
|
|
56
|
+
outcome?: FindingOutcome;
|
|
57
|
+
evidence?: Record<string, unknown>;
|
|
34
58
|
}
|
|
35
59
|
/**
|
|
36
|
-
* Verdict returned by POST /v1/
|
|
37
|
-
* block when `
|
|
60
|
+
* Verdict returned by POST /v1/evaluate. TrustGuard detects; the caller enforces:
|
|
61
|
+
* block when `status` is "block" (`isBlocked` is the convenience signal).
|
|
38
62
|
*/
|
|
39
63
|
interface GuardResponse {
|
|
40
|
-
/**
|
|
41
|
-
|
|
64
|
+
/** Most restrictive verdict: "allow", "block", "transform", "report", or "" when omitted. */
|
|
65
|
+
status: string;
|
|
66
|
+
/** Convenience flag: true when `status === "block"`. */
|
|
67
|
+
isBlocked: boolean;
|
|
42
68
|
/** The payload as rewritten by in-flight masking, null when untouched. */
|
|
43
69
|
transformedPayload: Record<string, unknown> | null;
|
|
44
|
-
/** What every plugin in the policy chain reported. */
|
|
70
|
+
/** What every plugin / gate in the policy chain reported. */
|
|
45
71
|
findings: Finding[];
|
|
46
72
|
/** Correlation ids for TrustGuard telemetry. */
|
|
47
73
|
traceId: string;
|
|
@@ -49,7 +75,7 @@ interface GuardResponse {
|
|
|
49
75
|
}
|
|
50
76
|
/** Configuration for the TrustGuard client. */
|
|
51
77
|
interface TrustGuardOptions {
|
|
52
|
-
/** Base URL of the TrustGuard deployment, e.g. https://
|
|
78
|
+
/** Base URL of the TrustGuard deployment, e.g. https://trustguard.neuraltrust.ai */
|
|
53
79
|
baseUrl: string;
|
|
54
80
|
/** Collector API key, sent as a Bearer token. */
|
|
55
81
|
apiKey: string;
|
|
@@ -59,7 +85,7 @@ interface TrustGuardOptions {
|
|
|
59
85
|
fetch?: typeof fetch;
|
|
60
86
|
}
|
|
61
87
|
|
|
62
|
-
/** Client for the TrustGuard runtime
|
|
88
|
+
/** Client for the TrustGuard runtime evaluate API. */
|
|
63
89
|
declare class TrustGuard {
|
|
64
90
|
#private;
|
|
65
91
|
constructor(options: TrustGuardOptions);
|
|
@@ -82,4 +108,4 @@ declare class TrustGuardAPIError extends Error {
|
|
|
82
108
|
constructor(status: number, message: string, traceId: string, requestId: string);
|
|
83
109
|
}
|
|
84
110
|
|
|
85
|
-
export { type Attachment, type Direction, type Finding, type GuardRequest, type GuardResponse, TrustGuard, TrustGuardAPIError, type TrustGuardOptions };
|
|
111
|
+
export { type Attachment, type Direction, type Finding, type FindingOutcome, type FindingSignal, type FindingSource, type GuardRequest, type GuardResponse, type Protocol, TrustGuard, TrustGuardAPIError, type TrustGuardOptions };
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ var TrustGuardAPIError = class extends Error {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
// src/client.ts
|
|
16
|
-
var
|
|
16
|
+
var EVALUATE_PATH = "/v1/evaluate";
|
|
17
17
|
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
18
18
|
var TrustGuard = class {
|
|
19
19
|
#baseUrl;
|
|
@@ -38,10 +38,10 @@ var TrustGuard = class {
|
|
|
38
38
|
* returns the verdict. Throws TrustGuardAPIError on non-2xx responses.
|
|
39
39
|
*/
|
|
40
40
|
async guard(request) {
|
|
41
|
-
if (!request.
|
|
42
|
-
throw new Error("TrustGuard: request
|
|
41
|
+
if (!request.payload) {
|
|
42
|
+
throw new Error("TrustGuard: request payload is required");
|
|
43
43
|
}
|
|
44
|
-
const response = await this.#fetch(this.#baseUrl +
|
|
44
|
+
const response = await this.#fetch(this.#baseUrl + EVALUATE_PATH, {
|
|
45
45
|
method: "POST",
|
|
46
46
|
headers: {
|
|
47
47
|
Authorization: `Bearer ${this.#apiKey}`,
|
|
@@ -58,44 +58,69 @@ var TrustGuard = class {
|
|
|
58
58
|
}
|
|
59
59
|
};
|
|
60
60
|
function serializeRequest(request) {
|
|
61
|
-
|
|
61
|
+
let payload = request.payload;
|
|
62
|
+
if (request.attachments?.length) {
|
|
63
|
+
payload = { ...payload, attachments: request.attachments.map(serializeAttachment) };
|
|
64
|
+
}
|
|
65
|
+
const body = { payload };
|
|
62
66
|
if (request.direction) body.direction = request.direction;
|
|
67
|
+
if (request.protocol) body.protocol = request.protocol;
|
|
63
68
|
if (request.sessionId) body.session_id = request.sessionId;
|
|
64
69
|
if (request.consumerId) body.consumer_id = request.consumerId;
|
|
65
|
-
|
|
66
|
-
if (request.attachments?.length) {
|
|
67
|
-
metadata = { ...metadata, attachments: request.attachments.map(serializeAttachment) };
|
|
68
|
-
}
|
|
69
|
-
if (metadata && Object.keys(metadata).length > 0) body.metadata = metadata;
|
|
70
|
+
if (request.attributes && Object.keys(request.attributes).length > 0) body.attributes = request.attributes;
|
|
70
71
|
return body;
|
|
71
72
|
}
|
|
72
73
|
function serializeAttachment(attachment) {
|
|
73
|
-
const
|
|
74
|
-
return {
|
|
74
|
+
const entry = {
|
|
75
75
|
filename: attachment.filename,
|
|
76
|
-
content_type: attachment.contentType
|
|
77
|
-
data: bytes.toString("base64")
|
|
76
|
+
content_type: attachment.contentType
|
|
78
77
|
};
|
|
78
|
+
if (attachment.data !== void 0) {
|
|
79
|
+
const bytes = typeof attachment.data === "string" ? Buffer.from(attachment.data, "utf-8") : Buffer.from(attachment.data);
|
|
80
|
+
entry.data = bytes.toString("base64");
|
|
81
|
+
}
|
|
82
|
+
if (attachment.url !== void 0) entry.url = attachment.url;
|
|
83
|
+
return entry;
|
|
79
84
|
}
|
|
80
85
|
function deserializeResponse(wire) {
|
|
86
|
+
const status = wire.status ?? "";
|
|
81
87
|
return {
|
|
82
|
-
|
|
88
|
+
status,
|
|
89
|
+
isBlocked: status === "block",
|
|
83
90
|
transformedPayload: wire.transformed_payload ?? null,
|
|
84
|
-
findings: (wire.findings ?? []).map(
|
|
85
|
-
(f) => ({
|
|
86
|
-
detectionType: f.detection_type,
|
|
87
|
-
confidence: f.confidence,
|
|
88
|
-
ruleName: f.rule_name,
|
|
89
|
-
details: f.details
|
|
90
|
-
})
|
|
91
|
-
),
|
|
91
|
+
findings: (wire.findings ?? []).map(deserializeFinding),
|
|
92
92
|
traceId: wire.trace_id ?? "",
|
|
93
93
|
requestId: wire.request_id ?? ""
|
|
94
94
|
};
|
|
95
95
|
}
|
|
96
|
+
function deserializeFinding(f) {
|
|
97
|
+
const sourceWire = f.source ?? {};
|
|
98
|
+
const source = {
|
|
99
|
+
kind: sourceWire.kind ?? ""
|
|
100
|
+
};
|
|
101
|
+
if (sourceWire.plugin !== void 0) source.plugin = sourceWire.plugin;
|
|
102
|
+
if (sourceWire.detector_id !== void 0) source.detectorId = sourceWire.detector_id;
|
|
103
|
+
if (sourceWire.detector_name !== void 0) source.detectorName = sourceWire.detector_name;
|
|
104
|
+
if (sourceWire.policy_id !== void 0) source.policyId = sourceWire.policy_id;
|
|
105
|
+
if (sourceWire.gate_name !== void 0) source.gateName = sourceWire.gate_name;
|
|
106
|
+
const finding = { source };
|
|
107
|
+
if (f.signal?.type) {
|
|
108
|
+
const signal = { type: f.signal.type };
|
|
109
|
+
if (f.signal.confidence !== void 0) signal.confidence = f.signal.confidence;
|
|
110
|
+
finding.signal = signal;
|
|
111
|
+
}
|
|
112
|
+
if (f.outcome?.action) {
|
|
113
|
+
const outcome = { action: f.outcome.action };
|
|
114
|
+
finding.outcome = outcome;
|
|
115
|
+
}
|
|
116
|
+
if (f.evidence && Object.keys(f.evidence).length > 0) {
|
|
117
|
+
finding.evidence = f.evidence;
|
|
118
|
+
}
|
|
119
|
+
return finding;
|
|
120
|
+
}
|
|
96
121
|
function apiError(status, text) {
|
|
97
122
|
const payload = parseJson(text);
|
|
98
|
-
const message = payload?.error || text.trim() || `HTTP ${status}`;
|
|
123
|
+
const message = payload?.error || payload?.message || text.trim() || `HTTP ${status}`;
|
|
99
124
|
return new TrustGuardAPIError(status, message, payload?.trace_id ?? "", payload?.request_id ?? "");
|
|
100
125
|
}
|
|
101
126
|
function parseJson(text) {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/client.ts"],"sourcesContent":["/**\n * A non-2xx response from the TrustGuard API, carrying the status code and the\n * correlation ids needed to chase the request in telemetry. Transport-level\n * failures (network errors, timeouts) are thrown as-is instead.\n */\nexport class TrustGuardAPIError extends Error {\n readonly status: number;\n readonly traceId: string;\n readonly requestId: string;\n\n constructor(status: number, message: string, traceId: string, requestId: string) {\n super(`TrustGuard API error ${status}: ${message} (trace_id=${traceId}, request_id=${requestId})`);\n this.name = \"TrustGuardAPIError\";\n this.status = status;\n this.traceId = traceId;\n this.requestId = requestId;\n }\n}\n","import { TrustGuardAPIError } from \"./errors.js\";\nimport type {
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/client.ts"],"sourcesContent":["/**\n * A non-2xx response from the TrustGuard API, carrying the status code and the\n * correlation ids needed to chase the request in telemetry. Transport-level\n * failures (network errors, timeouts) are thrown as-is instead.\n */\nexport class TrustGuardAPIError extends Error {\n readonly status: number;\n readonly traceId: string;\n readonly requestId: string;\n\n constructor(status: number, message: string, traceId: string, requestId: string) {\n super(`TrustGuard API error ${status}: ${message} (trace_id=${traceId}, request_id=${requestId})`);\n this.name = \"TrustGuardAPIError\";\n this.status = status;\n this.traceId = traceId;\n this.requestId = requestId;\n }\n}\n","import { TrustGuardAPIError } from \"./errors.js\";\nimport type {\n Attachment,\n Finding,\n FindingOutcome,\n FindingSignal,\n FindingSource,\n GuardRequest,\n GuardResponse,\n TrustGuardOptions,\n} from \"./types.js\";\n\nconst EVALUATE_PATH = \"/v1/evaluate\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\ninterface WireFindingSource {\n kind?: string;\n plugin?: string;\n detector_id?: string;\n detector_name?: string;\n policy_id?: string;\n gate_name?: string;\n}\n\ninterface WireFindingSignal {\n type?: string;\n confidence?: number;\n}\n\ninterface WireFindingOutcome {\n action?: string;\n}\n\ninterface WireFinding {\n source?: WireFindingSource;\n signal?: WireFindingSignal;\n outcome?: WireFindingOutcome;\n evidence?: Record<string, unknown>;\n}\n\ninterface WireResponse {\n status?: string;\n transformed_payload?: Record<string, unknown> | null;\n findings?: WireFinding[];\n trace_id?: string;\n request_id?: string;\n}\n\n/** Client for the TrustGuard runtime evaluate API. */\nexport class TrustGuard {\n readonly #baseUrl: string;\n readonly #apiKey: string;\n readonly #timeoutMs: number;\n readonly #fetch: typeof fetch;\n\n constructor(options: TrustGuardOptions) {\n const baseUrl = options.baseUrl?.trim().replace(/\\/+$/, \"\");\n if (!baseUrl) {\n throw new Error(\"TrustGuard: baseUrl is required\");\n }\n if (!options.apiKey?.trim()) {\n throw new Error(\"TrustGuard: apiKey is required\");\n }\n this.#baseUrl = baseUrl;\n this.#apiKey = options.apiKey;\n this.#timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.#fetch = options.fetch ?? globalThis.fetch;\n }\n\n /**\n * Evaluates the request against the policy attached to the API key and\n * returns the verdict. Throws TrustGuardAPIError on non-2xx responses.\n */\n async guard(request: GuardRequest): Promise<GuardResponse> {\n if (!request.payload) {\n throw new Error(\"TrustGuard: request payload is required\");\n }\n\n const response = await this.#fetch(this.#baseUrl + EVALUATE_PATH, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.#apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(serializeRequest(request)),\n signal: AbortSignal.timeout(this.#timeoutMs),\n });\n\n const text = await response.text();\n if (!response.ok) {\n throw apiError(response.status, text);\n }\n\n return deserializeResponse(parseJson(text) ?? {});\n }\n}\n\n/** Maps the camelCase request onto the snake_case wire format, omitting empty optionals (the server rejects unknown top-level fields). */\nfunction serializeRequest(request: GuardRequest): Record<string, unknown> {\n let payload = request.payload;\n if (request.attachments?.length) {\n payload = { ...payload, attachments: request.attachments.map(serializeAttachment) };\n }\n const body: Record<string, unknown> = { payload };\n if (request.direction) body.direction = request.direction;\n if (request.protocol) body.protocol = request.protocol;\n if (request.sessionId) body.session_id = request.sessionId;\n if (request.consumerId) body.consumer_id = request.consumerId;\n if (request.attributes && Object.keys(request.attributes).length > 0) body.attributes = request.attributes;\n return body;\n}\n\nfunction serializeAttachment(attachment: Attachment): Record<string, string> {\n const entry: Record<string, string> = {\n filename: attachment.filename,\n content_type: attachment.contentType,\n };\n if (attachment.data !== undefined) {\n const bytes =\n typeof attachment.data === \"string\" ? Buffer.from(attachment.data, \"utf-8\") : Buffer.from(attachment.data);\n entry.data = bytes.toString(\"base64\");\n }\n if (attachment.url !== undefined) entry.url = attachment.url;\n return entry;\n}\n\nfunction deserializeResponse(wire: WireResponse): GuardResponse {\n const status = wire.status ?? \"\";\n return {\n status,\n isBlocked: status === \"block\",\n transformedPayload: wire.transformed_payload ?? null,\n findings: (wire.findings ?? []).map(deserializeFinding),\n traceId: wire.trace_id ?? \"\",\n requestId: wire.request_id ?? \"\",\n };\n}\n\nfunction deserializeFinding(f: WireFinding): Finding {\n const sourceWire = f.source ?? {};\n const source: FindingSource = {\n kind: sourceWire.kind ?? \"\",\n };\n if (sourceWire.plugin !== undefined) source.plugin = sourceWire.plugin;\n if (sourceWire.detector_id !== undefined) source.detectorId = sourceWire.detector_id;\n if (sourceWire.detector_name !== undefined) source.detectorName = sourceWire.detector_name;\n if (sourceWire.policy_id !== undefined) source.policyId = sourceWire.policy_id;\n if (sourceWire.gate_name !== undefined) source.gateName = sourceWire.gate_name;\n\n const finding: Finding = { source };\n if (f.signal?.type) {\n const signal: FindingSignal = { type: f.signal.type };\n if (f.signal.confidence !== undefined) signal.confidence = f.signal.confidence;\n finding.signal = signal;\n }\n if (f.outcome?.action) {\n const outcome: FindingOutcome = { action: f.outcome.action };\n finding.outcome = outcome;\n }\n if (f.evidence && Object.keys(f.evidence).length > 0) {\n finding.evidence = f.evidence;\n }\n return finding;\n}\n\nfunction apiError(status: number, text: string): TrustGuardAPIError {\n const payload = parseJson(text) as { error?: string; message?: string; trace_id?: string; request_id?: string } | undefined;\n const message = payload?.error || payload?.message || text.trim() || `HTTP ${status}`;\n return new TrustGuardAPIError(status, message, payload?.trace_id ?? \"\", payload?.request_id ?? \"\");\n}\n\nfunction parseJson(text: string): WireResponse | undefined {\n try {\n return JSON.parse(text) as WireResponse;\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neuraltrust/trustguard-sdk",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Official Node.js SDK for the TrustGuard runtime
|
|
3
|
+
"version": "0.1.4",
|
|
4
|
+
"description": "Official Node.js SDK for the TrustGuard runtime evaluate API (POST /v1/evaluate)",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "NeuralTrust",
|
|
7
7
|
"repository": {
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
"url": "git+https://github.com/NeuralTrust/trustguard-sdk.git",
|
|
10
10
|
"directory": "node"
|
|
11
11
|
},
|
|
12
|
+
"homepage": "https://docs.neuraltrust.ai/sdks/trustguard/node",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/NeuralTrust/trustguard-sdk/issues"
|
|
15
|
+
},
|
|
12
16
|
"keywords": [
|
|
13
17
|
"neuraltrust",
|
|
14
18
|
"trustguard",
|
|
@@ -44,6 +48,6 @@
|
|
|
44
48
|
"@types/node": "^22.10.2",
|
|
45
49
|
"tsup": "^8.3.5",
|
|
46
50
|
"typescript": "^5.7.2",
|
|
47
|
-
"vitest": "^
|
|
51
|
+
"vitest": "^4.1.9"
|
|
48
52
|
}
|
|
49
53
|
}
|