shield360 1.0.1 → 1.1.0

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.
Files changed (53) hide show
  1. package/README.md +65 -37
  2. package/dist/__tests__/build-info.test.d.ts +1 -0
  3. package/dist/__tests__/build-info.test.js +189 -0
  4. package/dist/__tests__/build-info.test.js.map +1 -0
  5. package/dist/__tests__/code-location.test.d.ts +1 -0
  6. package/dist/__tests__/code-location.test.js +180 -0
  7. package/dist/__tests__/code-location.test.js.map +1 -0
  8. package/dist/__tests__/pricing-claude-5.test.js +3 -0
  9. package/dist/__tests__/pricing-claude-5.test.js.map +1 -1
  10. package/dist/config.js +1 -1
  11. package/dist/config.js.map +1 -1
  12. package/dist/guard/__tests__/findings.test.js +27 -8
  13. package/dist/guard/__tests__/findings.test.js.map +1 -1
  14. package/dist/guard/base.d.ts +2 -0
  15. package/dist/guard/base.js +4 -0
  16. package/dist/guard/base.js.map +1 -1
  17. package/dist/guard/findings.d.ts +12 -2
  18. package/dist/guard/findings.js +19 -49
  19. package/dist/guard/findings.js.map +1 -1
  20. package/dist/guard/integration.d.ts +24 -3
  21. package/dist/guard/integration.js +102 -30
  22. package/dist/guard/integration.js.map +1 -1
  23. package/dist/guard/pipeline.d.ts +10 -1
  24. package/dist/guard/pipeline.js +14 -0
  25. package/dist/guard/pipeline.js.map +1 -1
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.js +34 -3
  28. package/dist/index.js.map +1 -1
  29. package/dist/instrumentation/mcp/wrapper.js +7 -1
  30. package/dist/instrumentation/mcp/wrapper.js.map +1 -1
  31. package/dist/otel/build-info.d.ts +22 -0
  32. package/dist/otel/build-info.js +175 -0
  33. package/dist/otel/build-info.js.map +1 -0
  34. package/dist/otel/code-location.d.ts +49 -0
  35. package/dist/otel/code-location.js +233 -0
  36. package/dist/otel/code-location.js.map +1 -0
  37. package/dist/otel/tracing.js +7 -0
  38. package/dist/otel/tracing.js.map +1 -1
  39. package/dist/pricing.json +100 -42
  40. package/dist/protect/__tests__/protect.test.d.ts +1 -0
  41. package/dist/protect/__tests__/protect.test.js +206 -0
  42. package/dist/protect/__tests__/protect.test.js.map +1 -0
  43. package/dist/protect/index.d.ts +103 -0
  44. package/dist/protect/index.js +191 -0
  45. package/dist/protect/index.js.map +1 -0
  46. package/dist/protect/mcp.d.ts +13 -0
  47. package/dist/protect/mcp.js +49 -0
  48. package/dist/protect/mcp.js.map +1 -0
  49. package/dist/protect/mode.d.ts +89 -0
  50. package/dist/protect/mode.js +134 -0
  51. package/dist/protect/mode.js.map +1 -0
  52. package/dist/types.d.ts +22 -0
  53. package/package.json +1 -1
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ /**
7
+ * Shield Protect in the TypeScript SDK: modes, fail-closed guards, readiness,
8
+ * streaming and oversized input, protectTool, and the MCP pre-execution check.
9
+ */
10
+ const base_1 = require("../../guard/base");
11
+ const pipeline_1 = require("../../guard/pipeline");
12
+ const integration_1 = require("../../guard/integration");
13
+ const config_1 = __importDefault(require("../../config"));
14
+ const index_1 = require("../index");
15
+ const mode_1 = require("../mode");
16
+ const mcp_1 = require("../mcp");
17
+ class DenyWord extends base_1.Guard {
18
+ constructor(word, maxScanLength) {
19
+ super({ action: 'deny', maxScanLength });
20
+ this.word = word;
21
+ this.name = 'deny_word';
22
+ this.phases = [base_1.GuardPhase.PREFLIGHT, base_1.GuardPhase.POSTFLIGHT];
23
+ }
24
+ evaluate(text) {
25
+ const hit = text.includes(this.word);
26
+ return (0, base_1.makeGuardResult)({ action: hit ? base_1.GuardAction.DENY : base_1.GuardAction.ALLOW, score: hit ? 1 : 0, guardName: this.name, explanation: hit ? `contains ${this.word}` : '' });
27
+ }
28
+ }
29
+ class Throwing extends base_1.Guard {
30
+ constructor() {
31
+ super({ action: 'deny' });
32
+ this.name = 'throwing';
33
+ this.phases = [base_1.GuardPhase.PREFLIGHT];
34
+ }
35
+ evaluate() {
36
+ throw new Error('classifier down');
37
+ }
38
+ }
39
+ class PreflightOnly extends base_1.Guard {
40
+ constructor() {
41
+ super({ action: 'deny' });
42
+ this.name = 'preflight_only';
43
+ this.phases = [base_1.GuardPhase.PREFLIGHT];
44
+ }
45
+ evaluate() {
46
+ return (0, base_1.makeGuardResult)({ guardName: this.name });
47
+ }
48
+ }
49
+ const extract = (k) => String(k.text ?? '');
50
+ const extractOut = (r) => String(r?.text ?? '');
51
+ beforeEach(() => {
52
+ (0, mode_1.resetProtectState)();
53
+ config_1.default.guardPipeline = undefined;
54
+ jest.spyOn(console, 'warn').mockImplementation(() => undefined);
55
+ jest.spyOn(console, 'log').mockImplementation(() => undefined);
56
+ });
57
+ afterEach(() => jest.restoreAllMocks());
58
+ describe('the mode', () => {
59
+ it('is raised by the environment and never lowered by it', () => {
60
+ expect((0, mode_1.resolveProtectMode)('enforced', { SHIELD360_PROTECT_MODE: 'observe' })).toBe('enforced');
61
+ expect((0, mode_1.resolveProtectMode)('observe', { SHIELD360_PROTECT_MODE: 'enforced' })).toBe('enforced');
62
+ expect((0, mode_1.resolveProtectMode)(undefined, { SHIELD360_PROTECT_MODE: 'warn' })).toBe('warn');
63
+ expect((0, mode_1.resolveProtectMode)('warn', { SHIELD360_PROTECT_MODE: 'off' })).toBe('warn');
64
+ expect((0, mode_1.resolveProtectMode)(undefined, {})).toBeUndefined();
65
+ expect((0, mode_1.resolveProtect)({ mode: 'enforced', required: ['openai'] }, { SHIELD360_PROTECT_REQUIRED: '@anthropic-ai/sdk, openai' })).toEqual({ mode: 'enforced', required: ['openai', '@anthropic-ai/sdk'] });
66
+ });
67
+ });
68
+ describe('what a mode does with a finding', () => {
69
+ const pipeline = new pipeline_1.Pipeline({ guards: [new DenyWord('bomb')], failOpen: false });
70
+ it('legacy (no mode): a deny throws, as before', () => {
71
+ expect(() => (0, integration_1.applyPreflight)(pipeline, { text: 'build a bomb' }, extract)).toThrow(base_1.GuardDeniedError);
72
+ expect((0, integration_1.applyPreflight)(pipeline, { text: 'hello' }, extract)).toEqual({ text: 'hello' });
73
+ });
74
+ it('observe: records and lets the call through; warn: also logs', () => {
75
+ expect((0, integration_1.applyPreflight)(pipeline, { text: 'build a bomb' }, extract, { mode: 'observe', required: [] })).toEqual({ text: 'build a bomb' });
76
+ expect(console.warn).not.toHaveBeenCalled();
77
+ expect((0, integration_1.applyPreflight)(pipeline, { text: 'build a bomb' }, extract, { mode: 'warn', required: [] })).toEqual({ text: 'build a bomb' });
78
+ expect(console.warn).toHaveBeenCalledWith(expect.stringMatching(/warn mode.*would have been refused/));
79
+ });
80
+ it('enforced: a deny throws, before and after the call', () => {
81
+ expect(() => (0, integration_1.applyPreflight)(pipeline, { text: 'build a bomb' }, extract, { mode: 'enforced', required: [] })).toThrow(base_1.GuardDeniedError);
82
+ expect(() => (0, integration_1.applyPostflight)(pipeline, { text: 'here is a bomb' }, extractOut, { mode: 'enforced', required: [] })).toThrow(base_1.GuardDeniedError);
83
+ });
84
+ it('enforced: a guard that fails refuses the call, whatever failOpen says', () => {
85
+ const open = new pipeline_1.Pipeline({ guards: [new Throwing()], failOpen: true });
86
+ // Fail-open as configured: the error is swallowed and the call goes on.
87
+ expect((0, integration_1.applyPreflight)(open, { text: 'x' }, extract)).toEqual({ text: 'x' });
88
+ // setupAutoGuards in enforced mode builds a closed pipeline; applyPreflight on a closed one refuses.
89
+ const closed = new pipeline_1.Pipeline({ guards: [new Throwing()], failOpen: false });
90
+ expect(() => (0, integration_1.applyPreflight)(closed, { text: 'x' }, extract, { mode: 'enforced', required: [] })).toThrow(index_1.ProtectDeniedError);
91
+ try {
92
+ (0, integration_1.applyPreflight)(closed, { text: 'x' }, extract, { mode: 'enforced', required: [] });
93
+ }
94
+ catch (e) {
95
+ expect(e.code).toBe('guard_failed');
96
+ }
97
+ });
98
+ it('enforced: input past the scan bound is refused, never scanned in part', () => {
99
+ const bounded = new pipeline_1.Pipeline({ guards: [new DenyWord('bomb', 20)] });
100
+ const long = 'x'.repeat(30) + ' bomb';
101
+ // Legacy: the tail is unscanned and the word slips through.
102
+ expect((0, integration_1.applyPreflight)(bounded, { text: long }, extract)).toEqual({ text: long });
103
+ expect(() => (0, integration_1.applyPreflight)(bounded, { text: long }, extract, { mode: 'enforced', required: [] })).toThrow(/more than its guards scan/);
104
+ expect(bounded.scanBound()).toBe(20);
105
+ });
106
+ it('enforced: a streamed completion is refused when postflight guards exist, allowed when only preflight guards do', () => {
107
+ expect(() => (0, integration_1.applyPreflight)(pipeline, { text: 'hello', stream: true }, extract, { mode: 'enforced', required: [] })).toThrow(/streamed completion/);
108
+ const pre = new pipeline_1.Pipeline({ guards: [new PreflightOnly()] });
109
+ expect((0, integration_1.applyPreflight)(pre, { text: 'hello', stream: true }, extract, { mode: 'enforced', required: [] })).toEqual({ text: 'hello', stream: true });
110
+ // Observe mode lets the stream through, as before.
111
+ expect((0, integration_1.applyPreflight)(pipeline, { text: 'hello', stream: true }, extract, { mode: 'observe', required: [] })).toEqual({ text: 'hello', stream: true });
112
+ });
113
+ });
114
+ describe('readiness', () => {
115
+ it('enforced mode with a required provider that is not wrapped refuses to start', () => {
116
+ expect(() => (0, integration_1.setupAutoGuards)([new DenyWord('x')], true, { mode: 'enforced', required: ['a-provider-that-is-not-installed'] })).toThrow(index_1.ProtectReadinessError);
117
+ expect((0, index_1.protectReadiness)()).toMatchObject({ mode: 'enforced', missing: ['a-provider-that-is-not-installed'], level: 'monitored' });
118
+ });
119
+ it('enforced mode fails closed: guardFailOpen is overridden with a warning', () => {
120
+ const report = (0, integration_1.setupAutoGuards)([new Throwing()], true, { mode: 'enforced', required: [] });
121
+ expect(report.missing).toEqual([]);
122
+ expect(console.warn).toHaveBeenCalledWith(expect.stringMatching(/fails closed/));
123
+ expect(() => config_1.default.guardPipeline.evaluate('x', 'preflight')).toThrow('classifier down');
124
+ });
125
+ it('never claims more than monitored or partially protected', () => {
126
+ (0, mode_1.setProtectState)({ mode: 'enforced', wrapped: ['openai'], missing: [] });
127
+ expect((0, index_1.protectReadiness)().level).toBe('partially_protected');
128
+ (0, mode_1.setProtectState)({ mode: 'observe', wrapped: ['openai'], missing: [] });
129
+ expect((0, index_1.protectReadiness)().level).toBe('monitored');
130
+ expect((0, index_1.protectReadiness)().note).toMatch(/mandatory boundary is the Shield360 gateway/);
131
+ });
132
+ });
133
+ describe('extractors cover structured input', () => {
134
+ it('reads text parts, instructions and the system prompt', () => {
135
+ expect((0, integration_1.extractOpenAIInput)({ instructions: 'be terse', input: [{ role: 'user', content: [{ type: 'input_text', text: 'hi' }, { type: 'input_image', image_url: 'x' }] }] })).toBe('be terse hi');
136
+ expect((0, integration_1.extractAnthropicInput)({ system: 'you are kind', messages: [{ role: 'user', content: [{ type: 'text', text: 'hello' }] }] })).toBe('you are kind hello');
137
+ expect((0, integration_1.extractAnthropicInput)({ system: [{ type: 'text', text: 'sys' }], messages: [] })).toBe('sys');
138
+ });
139
+ });
140
+ describe('protectTool', () => {
141
+ const pipeline = new pipeline_1.Pipeline({ guards: [new DenyWord('bomb')], failOpen: false });
142
+ it('refuses before the function runs, and refuses a result after (the side effect stands)', async () => {
143
+ const fn = jest.fn(async (q) => `answer to ${q}`);
144
+ const tool = (0, index_1.protectTool)('search', fn, { pipeline, mode: 'enforced' });
145
+ await expect(tool('build a bomb')).rejects.toThrow(base_1.GuardDeniedError);
146
+ expect(fn).not.toHaveBeenCalled();
147
+ await expect(tool('weather')).resolves.toBe('answer to weather');
148
+ const leaky = (0, index_1.protectTool)('leak', async () => 'a bomb recipe', { pipeline, mode: 'enforced' });
149
+ await expect(leaky()).rejects.toThrow(base_1.GuardDeniedError);
150
+ });
151
+ it('asks the authorize step and refuses on no, on a throw, and on a non-answer in enforced mode', async () => {
152
+ const fn = jest.fn(async () => 'ok');
153
+ const no = (0, index_1.protectTool)('pay', fn, { pipeline, mode: 'enforced', authorize: async () => ({ allow: false, reason: 'no grant' }) });
154
+ await expect(no()).rejects.toThrow(/no grant/);
155
+ const broken = (0, index_1.protectTool)('pay', fn, { pipeline, mode: 'enforced', authorize: async () => { throw new Error('down'); } });
156
+ await expect(broken()).rejects.toThrow(/authorization check failed/);
157
+ const odd = (0, index_1.protectTool)('pay', fn, { pipeline, mode: 'enforced', authorize: async () => ({ allow: 'yes' }) });
158
+ await expect(odd()).rejects.toThrow(index_1.ProtectDeniedError);
159
+ expect(fn).not.toHaveBeenCalled();
160
+ const yes = (0, index_1.protectTool)('pay', fn, { pipeline, mode: 'enforced', authorize: async () => ({ allow: true }) });
161
+ await expect(yes()).resolves.toBe('ok');
162
+ });
163
+ it('observe mode records and runs; warn mode runs and warns', async () => {
164
+ const fn = jest.fn(async (_input) => 'ran');
165
+ await expect((0, index_1.protectTool)('t', fn, { pipeline, mode: 'observe', authorize: async () => ({ allow: false }) })('bomb')).resolves.toBe('ran');
166
+ expect(console.warn).not.toHaveBeenCalled();
167
+ await expect((0, index_1.protectTool)('t', fn, { pipeline, mode: 'warn' })('bomb')).resolves.toBe('ran');
168
+ expect(console.warn).toHaveBeenCalled();
169
+ });
170
+ it('enforced mode with no pipeline anywhere refuses rather than running unchecked', async () => {
171
+ await expect((0, index_1.protectTool)('t', async () => 1, { mode: 'enforced' })()).rejects.toThrow(/no guard pipeline/);
172
+ });
173
+ it('uses the pipeline init() installed and the process mode by default', async () => {
174
+ config_1.default.guardPipeline = pipeline;
175
+ (0, mode_1.setProtectState)({ mode: 'enforced', wrapped: [], missing: [] });
176
+ await expect((0, index_1.protectTool)('t', async (s) => s)('bomb')).rejects.toThrow(base_1.GuardDeniedError);
177
+ });
178
+ });
179
+ describe('authorizeWithShield360', () => {
180
+ it('is a refusal when Shield360 is not configured, unreachable, or says no; allow only on allow', async () => {
181
+ await expect((0, index_1.authorizeWithShield360)({ kind: 'destination', host: 'api.example' }, { agentToken: '', url: '' })).resolves.toMatchObject({ allow: false, reason: 'shield360_not_configured' });
182
+ const fetchImpl = jest.fn(async () => ({ ok: true, json: async () => ({ outcome: 'deny', reason: 'destination_not_approved' }) }));
183
+ await expect((0, index_1.authorizeWithShield360)({ kind: 'destination', host: 'api.example' }, { agentToken: 't', url: 'https://s360.example/', fetchImpl })).resolves.toMatchObject({ allow: false, reason: 'destination_not_approved' });
184
+ const [url, init] = fetchImpl.mock.calls[0];
185
+ expect(url).toBe('https://s360.example/api/agent-authorization/check');
186
+ expect(init.headers.Authorization).toBe('Bearer t');
187
+ const down = jest.fn(async () => { throw new Error('ECONNREFUSED'); });
188
+ await expect((0, index_1.authorizeWithShield360)({ kind: 'model', model: 'gpt-4o' }, { agentToken: 't', url: 'https://s360.example', fetchImpl: down })).resolves.toMatchObject({ allow: false, reason: expect.stringMatching(/check_unreachable/) });
189
+ const yes = jest.fn(async () => ({ ok: true, json: async () => ({ outcome: 'allow', reason: 'destination_approved', decisionId: 'd1' }) }));
190
+ await expect((0, index_1.authorizeWithShield360)({ kind: 'destination', host: 'api.example' }, { agentToken: 't', url: 'https://s360.example', fetchImpl: yes })).resolves.toMatchObject({ allow: true, decisionId: 'd1' });
191
+ });
192
+ });
193
+ describe('the MCP pre-execution check', () => {
194
+ it('refuses a tools/call whose arguments a guard denies, in enforced mode only', () => {
195
+ config_1.default.guardPipeline = new pipeline_1.Pipeline({ guards: [new DenyWord('bomb')], failOpen: false });
196
+ (0, mode_1.setProtectState)({ mode: 'enforced', wrapped: [], missing: [] });
197
+ expect(() => (0, mcp_1.checkMcpToolCall)('search', { q: 'a bomb' })).toThrow(base_1.GuardDeniedError);
198
+ expect(() => (0, mcp_1.checkMcpToolCall)('search', { q: 'weather' })).not.toThrow();
199
+ (0, mode_1.setProtectState)({ mode: 'warn', wrapped: [], missing: [] });
200
+ expect(() => (0, mcp_1.checkMcpToolCall)('search', { q: 'a bomb' })).not.toThrow();
201
+ expect(console.warn).toHaveBeenCalled();
202
+ (0, mode_1.resetProtectState)();
203
+ expect(() => (0, mcp_1.checkMcpToolCall)('search', { q: 'a bomb' })).not.toThrow();
204
+ });
205
+ });
206
+ //# sourceMappingURL=protect.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protect.test.js","sourceRoot":"","sources":["../../../src/protect/__tests__/protect.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Shield Protect -- enforcement APIs, kept apart from the tracing APIs.
3
+ *
4
+ * protectTool(name, fn, options) wrap a function the agent may call: its
5
+ * arguments are checked before it runs,
6
+ * an optional authorize step is asked,
7
+ * and its result is checked before it is
8
+ * returned. In enforced mode every failure
9
+ * refuses the call.
10
+ * authorizeWithShield360(target) ask Shield360's decision service about a
11
+ * model or a destination, as the agent
12
+ * (SHIELD360_AGENT_TOKEN).
13
+ * protectReadiness() what this process can claim.
14
+ *
15
+ * `trace`, `startTrace` and the instrumentations record; these refuse.
16
+ *
17
+ * Must stay in sync with: sdk/python/src/shield360/protect/__init__.py
18
+ */
19
+ import { Pipeline } from '../guard/pipeline';
20
+ import { ProtectMode } from './mode';
21
+ export { ProtectDeniedError, ProtectError, ProtectReadinessError, protectReadiness, resolveProtectMode, resolveProtect, PROTECT_MODES, } from './mode';
22
+ export type { ProtectMode, ProtectConfig, ProtectReadiness } from './mode';
23
+ export type ProtectToolOptions<A extends unknown[]> = {
24
+ /** The pipeline to check with; defaults to the one init() installed. */
25
+ pipeline?: Pipeline;
26
+ /** The mode; defaults to the process's. With none set anywhere, deny findings refuse (as a guard's own action says). */
27
+ mode?: ProtectMode;
28
+ /** How the arguments are turned into text for the guards. Default: canonical JSON of every argument. */
29
+ describeArgs?: (...args: A) => string;
30
+ /** How the result is turned into text for postflight guards. Default: canonical JSON. */
31
+ describeResult?: (result: unknown) => string;
32
+ /**
33
+ * An authorization step asked after the guards and before the call: a
34
+ * grant lookup, a Shield360 decision (authorizeWithShield360), a budget.
35
+ * A refusal, a throw or a non-boolean answer refuses the call in enforced
36
+ * mode; the call never runs on an answer it did not get.
37
+ */
38
+ authorize?: (...args: A) => Promise<{
39
+ allow: boolean;
40
+ reason?: string;
41
+ }> | {
42
+ allow: boolean;
43
+ reason?: string;
44
+ };
45
+ };
46
+ export type ProtectDecision = {
47
+ tool: string;
48
+ phase: 'preflight' | 'authorize' | 'postflight';
49
+ outcome: 'allow' | 'deny' | 'observed';
50
+ reason: string;
51
+ };
52
+ /** Canonical JSON: keys sorted, undefined dropped, so the same call reads the same. */
53
+ export declare function canonicalJson(value: unknown, depth?: number): string;
54
+ /**
55
+ * Whether a pipeline result stops the call under a mode. With no mode
56
+ * (legacy), a DENY stops it as before. In observe and warn it is recorded,
57
+ * and in warn also logged, and the call goes on. In enforced it stops.
58
+ */
59
+ export declare function findingStops(mode: ProtectMode | undefined, denied: boolean): boolean;
60
+ /**
61
+ * Wraps a function as a protected tool. Returns a function with the same
62
+ * signature. Nothing about tracing: the call is recorded as a decision
63
+ * event on the active span, if any, and that is all.
64
+ */
65
+ export declare function protectTool<A extends unknown[], R>(name: string, fn: (...args: A) => Promise<R> | R, options?: ProtectToolOptions<A>): (...args: A) => Promise<R>;
66
+ export type AuthorizeTarget = {
67
+ kind: 'model';
68
+ model: string;
69
+ provider?: string;
70
+ inputTokens?: number;
71
+ maxOutputTokens?: number;
72
+ estimatedCostUsd?: number;
73
+ } | {
74
+ kind: 'destination';
75
+ host: string;
76
+ method?: string;
77
+ };
78
+ export type AuthorizeOptions = {
79
+ /** The agent's token; defaults to SHIELD360_AGENT_TOKEN. */
80
+ agentToken?: string;
81
+ /** Shield360's URL; defaults to init()'s shield360Url, then SHIELD360_URL. */
82
+ url?: string;
83
+ onBehalfOf?: string;
84
+ environment?: string;
85
+ timeoutMs?: number;
86
+ fetchImpl?: typeof fetch;
87
+ };
88
+ export type AuthorizeAnswer = {
89
+ allow: boolean;
90
+ reason: string;
91
+ outcome?: string;
92
+ message?: string;
93
+ policyVersion?: string;
94
+ decisionId?: string | null;
95
+ };
96
+ /**
97
+ * Asks Shield360 whether this agent may make a model call or reach a host
98
+ * (POST /api/agent-authorization/check). The agent's token decides the agent
99
+ * and its environment. An answer that did not arrive is `allow: false` with
100
+ * the reason: a caller in enforced mode treats it as a refusal, never a
101
+ * verdict in the agent's favour.
102
+ */
103
+ export declare function authorizeWithShield360(target: AuthorizeTarget, options?: AuthorizeOptions): Promise<AuthorizeAnswer>;
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ /**
3
+ * Shield Protect -- enforcement APIs, kept apart from the tracing APIs.
4
+ *
5
+ * protectTool(name, fn, options) wrap a function the agent may call: its
6
+ * arguments are checked before it runs,
7
+ * an optional authorize step is asked,
8
+ * and its result is checked before it is
9
+ * returned. In enforced mode every failure
10
+ * refuses the call.
11
+ * authorizeWithShield360(target) ask Shield360's decision service about a
12
+ * model or a destination, as the agent
13
+ * (SHIELD360_AGENT_TOKEN).
14
+ * protectReadiness() what this process can claim.
15
+ *
16
+ * `trace`, `startTrace` and the instrumentations record; these refuse.
17
+ *
18
+ * Must stay in sync with: sdk/python/src/shield360/protect/__init__.py
19
+ */
20
+ var __importDefault = (this && this.__importDefault) || function (mod) {
21
+ return (mod && mod.__esModule) ? mod : { "default": mod };
22
+ };
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.PROTECT_MODES = exports.resolveProtect = exports.resolveProtectMode = exports.protectReadiness = exports.ProtectReadinessError = exports.ProtectError = exports.ProtectDeniedError = void 0;
25
+ exports.canonicalJson = canonicalJson;
26
+ exports.findingStops = findingStops;
27
+ exports.protectTool = protectTool;
28
+ exports.authorizeWithShield360 = authorizeWithShield360;
29
+ const api_1 = require("@opentelemetry/api");
30
+ const config_1 = __importDefault(require("../config"));
31
+ const base_1 = require("../guard/base");
32
+ const mode_1 = require("./mode");
33
+ var mode_2 = require("./mode");
34
+ Object.defineProperty(exports, "ProtectDeniedError", { enumerable: true, get: function () { return mode_2.ProtectDeniedError; } });
35
+ Object.defineProperty(exports, "ProtectError", { enumerable: true, get: function () { return mode_2.ProtectError; } });
36
+ Object.defineProperty(exports, "ProtectReadinessError", { enumerable: true, get: function () { return mode_2.ProtectReadinessError; } });
37
+ Object.defineProperty(exports, "protectReadiness", { enumerable: true, get: function () { return mode_2.protectReadiness; } });
38
+ Object.defineProperty(exports, "resolveProtectMode", { enumerable: true, get: function () { return mode_2.resolveProtectMode; } });
39
+ Object.defineProperty(exports, "resolveProtect", { enumerable: true, get: function () { return mode_2.resolveProtect; } });
40
+ Object.defineProperty(exports, "PROTECT_MODES", { enumerable: true, get: function () { return mode_2.PROTECT_MODES; } });
41
+ const MAX_DESCRIBED = 1000000;
42
+ /** Canonical JSON: keys sorted, undefined dropped, so the same call reads the same. */
43
+ function canonicalJson(value, depth = 0) {
44
+ if (depth > 32)
45
+ return '"…"';
46
+ if (Array.isArray(value))
47
+ return `[${value.map((v) => canonicalJson(v === undefined ? null : v, depth + 1)).join(',')}]`;
48
+ if (value && typeof value === 'object') {
49
+ const entries = Object.entries(value)
50
+ .filter(([, v]) => v !== undefined && typeof v !== 'function')
51
+ .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
52
+ return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${canonicalJson(v, depth + 1)}`).join(',')}}`;
53
+ }
54
+ if (typeof value === 'bigint')
55
+ return JSON.stringify(String(value));
56
+ if (typeof value === 'function' || typeof value === 'symbol')
57
+ return 'null';
58
+ return JSON.stringify(value ?? null);
59
+ }
60
+ function record(decision) {
61
+ try {
62
+ const span = api_1.trace.getActiveSpan();
63
+ span?.addEvent('shield360.protect.decision', {
64
+ 'shield360.protect.tool': decision.tool,
65
+ 'shield360.protect.phase': decision.phase,
66
+ 'shield360.protect.outcome': decision.outcome,
67
+ 'shield360.protect.reason': decision.reason.slice(0, 500),
68
+ });
69
+ }
70
+ catch {
71
+ // recording never changes a decision
72
+ }
73
+ }
74
+ /**
75
+ * Whether a pipeline result stops the call under a mode. With no mode
76
+ * (legacy), a DENY stops it as before. In observe and warn it is recorded,
77
+ * and in warn also logged, and the call goes on. In enforced it stops.
78
+ */
79
+ function findingStops(mode, denied) {
80
+ if (!denied)
81
+ return false;
82
+ if (mode === undefined)
83
+ return true;
84
+ return (0, mode_1.refuses)(mode);
85
+ }
86
+ function evaluateText(pipeline, text, phase, tool, mode) {
87
+ if (!text)
88
+ return;
89
+ const bound = pipeline.scanBound();
90
+ if ((0, mode_1.refuses)(mode) && bound > 0 && text.length > bound) {
91
+ record({ tool, phase, outcome: 'deny', reason: `input of ${text.length} characters is over the ${bound}-character scan bound` });
92
+ throw new mode_1.ProtectDeniedError('oversized', `Shield360 Protect refused ${tool}: ${text.length} characters is more than its guards scan (${bound}); send less.`);
93
+ }
94
+ let result;
95
+ try {
96
+ result = pipeline.evaluate(text, phase);
97
+ }
98
+ catch (e) {
99
+ if ((0, mode_1.refuses)(mode)) {
100
+ record({ tool, phase, outcome: 'deny', reason: `guard failed: ${e?.message ?? String(e)}` });
101
+ throw new mode_1.ProtectDeniedError('guard_failed', `Shield360 Protect refused ${tool}: a guard failed and enforced mode does not run unchecked calls.`);
102
+ }
103
+ throw e;
104
+ }
105
+ const denied = result.action === base_1.GuardAction.DENY;
106
+ if (!denied) {
107
+ record({ tool, phase, outcome: 'allow', reason: result.action });
108
+ return;
109
+ }
110
+ if (findingStops(mode, true)) {
111
+ record({ tool, phase, outcome: 'deny', reason: result.explanation });
112
+ throw new base_1.GuardDeniedError(result);
113
+ }
114
+ record({ tool, phase, outcome: 'observed', reason: result.explanation });
115
+ if (mode === 'warn')
116
+ console.warn(`[shield360] Protect (warn mode): ${tool} would have been refused at ${phase}: ${result.explanation}`);
117
+ }
118
+ /**
119
+ * Wraps a function as a protected tool. Returns a function with the same
120
+ * signature. Nothing about tracing: the call is recorded as a decision
121
+ * event on the active span, if any, and that is all.
122
+ */
123
+ function protectTool(name, fn, options = {}) {
124
+ const describeArgs = options.describeArgs ?? ((...args) => canonicalJson(args).slice(0, MAX_DESCRIBED));
125
+ const describeResult = options.describeResult ?? ((result) => canonicalJson(result).slice(0, MAX_DESCRIBED));
126
+ return async (...args) => {
127
+ const mode = options.mode ?? (0, mode_1.currentProtectMode)();
128
+ const pipeline = options.pipeline ?? config_1.default.guardPipeline;
129
+ if (!pipeline && (0, mode_1.refuses)(mode)) {
130
+ throw new mode_1.ProtectDeniedError('guard_failed', `Shield360 Protect refused ${name}: enforced mode has no guard pipeline; pass guards to init() or to protectTool().`);
131
+ }
132
+ if (pipeline)
133
+ evaluateText(pipeline, describeArgs(...args), base_1.GuardPhase.PREFLIGHT, name, mode);
134
+ if (options.authorize) {
135
+ let verdict;
136
+ try {
137
+ verdict = await options.authorize(...args);
138
+ }
139
+ catch (e) {
140
+ record({ tool: name, phase: 'authorize', outcome: (0, mode_1.refuses)(mode) ? 'deny' : 'observed', reason: `authorize failed: ${e?.message ?? String(e)}` });
141
+ if ((0, mode_1.refuses)(mode))
142
+ throw new mode_1.ProtectDeniedError('authorize_failed', `Shield360 Protect refused ${name}: the authorization check failed and enforced mode does not run unchecked calls.`);
143
+ }
144
+ if (verdict !== undefined) {
145
+ const allowed = verdict && verdict.allow === true;
146
+ record({ tool: name, phase: 'authorize', outcome: allowed ? 'allow' : findingStops(mode, true) ? 'deny' : 'observed', reason: verdict?.reason ?? '' });
147
+ if (!allowed && findingStops(mode, true))
148
+ throw new mode_1.ProtectDeniedError('not_authorized', `Shield360 Protect refused ${name}: ${verdict?.reason || 'not authorized'}.`);
149
+ }
150
+ }
151
+ const result = await fn(...args);
152
+ if (pipeline)
153
+ evaluateText(pipeline, describeResult(result), base_1.GuardPhase.POSTFLIGHT, name, mode);
154
+ return result;
155
+ };
156
+ }
157
+ /**
158
+ * Asks Shield360 whether this agent may make a model call or reach a host
159
+ * (POST /api/agent-authorization/check). The agent's token decides the agent
160
+ * and its environment. An answer that did not arrive is `allow: false` with
161
+ * the reason: a caller in enforced mode treats it as a refusal, never a
162
+ * verdict in the agent's favour.
163
+ */
164
+ async function authorizeWithShield360(target, options = {}) {
165
+ const token = options.agentToken ?? process.env.SHIELD360_AGENT_TOKEN ?? '';
166
+ const base = (options.url ?? config_1.default.shield360Url ?? process.env.SHIELD360_URL ?? '').replace(/\/+$/, '');
167
+ if (!token || !base)
168
+ return { allow: false, reason: 'shield360_not_configured' };
169
+ const doFetch = options.fetchImpl ?? fetch;
170
+ const controller = new AbortController();
171
+ const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? 5000);
172
+ try {
173
+ const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` };
174
+ if (options.onBehalfOf)
175
+ headers['X-Shield360-On-Behalf-Of'] = options.onBehalfOf;
176
+ if (options.environment)
177
+ headers['X-Shield360-Environment'] = options.environment;
178
+ const res = await doFetch(`${base}/api/agent-authorization/check`, { method: 'POST', headers, body: JSON.stringify(target), signal: controller.signal });
179
+ if (!res.ok)
180
+ return { allow: false, reason: `check_http_${res.status}` };
181
+ const body = (await res.json());
182
+ return { allow: body.outcome === 'allow', reason: body.reason ?? 'unknown', outcome: body.outcome, message: body.message, policyVersion: body.policyVersion, decisionId: body.decisionId ?? null };
183
+ }
184
+ catch (e) {
185
+ return { allow: false, reason: `check_unreachable: ${e?.message ?? String(e)}` };
186
+ }
187
+ finally {
188
+ clearTimeout(timer);
189
+ }
190
+ }
191
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/protect/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Shield Protect -- the pre-execution check on an MCP client's tools/call.
3
+ *
4
+ * The MCP instrumentation records every call; this is the one place it can
5
+ * refuse one. The tool's arguments, as canonical JSON, go through the
6
+ * preflight guards init() installed, under the process's Protect mode:
7
+ * observe records, warn records and logs, enforced refuses (and refuses when
8
+ * a guard fails, or when the arguments are past the scan bound). With no
9
+ * pipeline or no mode, nothing changes: the call is recorded as before.
10
+ *
11
+ * Must stay in sync with: sdk/python/src/shield360/protect/_mcp.py
12
+ */
13
+ export declare function checkMcpToolCall(toolName: string, toolArguments: unknown): void;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ /**
3
+ * Shield Protect -- the pre-execution check on an MCP client's tools/call.
4
+ *
5
+ * The MCP instrumentation records every call; this is the one place it can
6
+ * refuse one. The tool's arguments, as canonical JSON, go through the
7
+ * preflight guards init() installed, under the process's Protect mode:
8
+ * observe records, warn records and logs, enforced refuses (and refuses when
9
+ * a guard fails, or when the arguments are past the scan bound). With no
10
+ * pipeline or no mode, nothing changes: the call is recorded as before.
11
+ *
12
+ * Must stay in sync with: sdk/python/src/shield360/protect/_mcp.py
13
+ */
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.checkMcpToolCall = checkMcpToolCall;
19
+ const config_1 = __importDefault(require("../config"));
20
+ const base_1 = require("../guard/base");
21
+ const index_1 = require("./index");
22
+ const mode_1 = require("./mode");
23
+ function checkMcpToolCall(toolName, toolArguments) {
24
+ const mode = (0, mode_1.currentProtectMode)();
25
+ const pipeline = config_1.default.guardPipeline;
26
+ if (!pipeline || mode === undefined)
27
+ return;
28
+ const text = (0, index_1.canonicalJson)(toolArguments ?? {});
29
+ const bound = pipeline.scanBound();
30
+ if ((0, mode_1.refuses)(mode) && bound > 0 && text.length > bound) {
31
+ throw new mode_1.ProtectDeniedError('oversized', `Shield360 Protect refused MCP tool ${toolName}: ${text.length} characters of arguments is more than its guards scan (${bound}).`);
32
+ }
33
+ let result;
34
+ try {
35
+ result = pipeline.evaluate(text, base_1.GuardPhase.PREFLIGHT);
36
+ }
37
+ catch (e) {
38
+ if ((0, mode_1.refuses)(mode))
39
+ throw new mode_1.ProtectDeniedError('guard_failed', `Shield360 Protect refused MCP tool ${toolName}: a guard failed and enforced mode does not run unchecked calls.`);
40
+ throw e;
41
+ }
42
+ if (result.action !== base_1.GuardAction.DENY)
43
+ return;
44
+ if ((0, mode_1.refuses)(mode))
45
+ throw new base_1.GuardDeniedError(result);
46
+ if (mode === 'warn')
47
+ console.warn(`[shield360] Protect (warn mode): MCP tool ${toolName} would have been refused: ${result.explanation}`);
48
+ }
49
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/protect/mcp.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;;;AAOH,4CAmBC;AAxBD,uDAAwC;AACxC,wCAA0E;AAC1E,mCAAwC;AACxC,iCAAyE;AAEzE,SAAgB,gBAAgB,CAAC,QAAgB,EAAE,aAAsB;IACvE,MAAM,IAAI,GAAG,IAAA,yBAAkB,GAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,gBAAe,CAAC,aAAa,CAAC;IAC/C,IAAI,CAAC,QAAQ,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO;IAC5C,MAAM,IAAI,GAAG,IAAA,qBAAa,EAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC;IACnC,IAAI,IAAA,cAAO,EAAC,IAAI,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,KAAK,EAAE,CAAC;QACtD,MAAM,IAAI,yBAAkB,CAAC,WAAW,EAAE,sCAAsC,QAAQ,KAAK,IAAI,CAAC,MAAM,0DAA0D,KAAK,IAAI,CAAC,CAAC;IAC/K,CAAC;IACD,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,iBAAU,CAAC,SAAS,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,IAAA,cAAO,EAAC,IAAI,CAAC;YAAE,MAAM,IAAI,yBAAkB,CAAC,cAAc,EAAE,sCAAsC,QAAQ,kEAAkE,CAAC,CAAC;QAClL,MAAM,CAAC,CAAC;IACV,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,kBAAW,CAAC,IAAI;QAAE,OAAO;IAC/C,IAAI,IAAA,cAAO,EAAC,IAAI,CAAC;QAAE,MAAM,IAAI,uBAAgB,CAAC,MAAM,CAAC,CAAC;IACtD,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,CAAC,IAAI,CAAC,6CAA6C,QAAQ,6BAA6B,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;AAC5I,CAAC"}