@yadsh/dsh-prompt-firewall 0.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.
- package/LICENSE +21 -0
- package/README.md +165 -0
- package/cordis.patch.yml +4 -0
- package/lib/audit.js +121 -0
- package/lib/audit.js.map +1 -0
- package/lib/client/index.js +155 -0
- package/lib/client/index.js.map +1 -0
- package/lib/client/styles.js +7 -0
- package/lib/client/styles.js.map +1 -0
- package/lib/client.js +5857 -0
- package/lib/client.js.map +1 -0
- package/lib/config.js +100 -0
- package/lib/config.js.map +1 -0
- package/lib/firewall.js +88 -0
- package/lib/firewall.js.map +1 -0
- package/lib/index.js +166 -0
- package/lib/index.js.map +1 -0
- package/lib/metrics.js +38 -0
- package/lib/metrics.js.map +1 -0
- package/lib/presets.js +23 -0
- package/lib/presets.js.map +1 -0
- package/lib/rules.js +103 -0
- package/lib/rules.js.map +1 -0
- package/lib/typert.host.d.ts +3 -0
- package/lib/typert.host.js +258 -0
- package/lib/typert.remote-client.d.ts +24 -0
- package/lib/typert.remote-client.js +141 -0
- package/lib/types/audit.d.ts +17 -0
- package/lib/types/client/index.d.ts +4 -0
- package/lib/types/client/styles.d.ts +1 -0
- package/lib/types/config.d.ts +8 -0
- package/lib/types/firewall.d.ts +17 -0
- package/lib/types/index.d.ts +46 -0
- package/lib/types/metrics.d.ts +16 -0
- package/lib/types/presets.d.ts +4 -0
- package/lib/types/rules.d.ts +25 -0
- package/lib/types/types.d.ts +125 -0
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -0
- package/package.json +124 -0
package/lib/config.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import z from '@deepseek-ai/schemastery';
|
|
2
|
+
import { getPreset } from './presets.js';
|
|
3
|
+
export const DEFAULT_AUDIT_CONFIG = Object.freeze({
|
|
4
|
+
enabled: true,
|
|
5
|
+
logAllowed: false,
|
|
6
|
+
logBlocked: true,
|
|
7
|
+
includePreview: false,
|
|
8
|
+
previewChars: 160,
|
|
9
|
+
historySize: 100,
|
|
10
|
+
highlightNewSections: true,
|
|
11
|
+
});
|
|
12
|
+
export const DEFAULT_METRICS_CONFIG = Object.freeze({
|
|
13
|
+
enabled: true,
|
|
14
|
+
});
|
|
15
|
+
export const DEFAULT_CONFIG = Object.freeze({
|
|
16
|
+
enabled: true,
|
|
17
|
+
mode: 'blocklist',
|
|
18
|
+
blockedSections: Object.freeze([]),
|
|
19
|
+
allowedSections: Object.freeze([]),
|
|
20
|
+
blockedPrefixes: Object.freeze([]),
|
|
21
|
+
allowedPrefixes: Object.freeze([]),
|
|
22
|
+
blockedPatterns: Object.freeze([]),
|
|
23
|
+
allowedPatterns: Object.freeze([]),
|
|
24
|
+
protectedSections: Object.freeze([]),
|
|
25
|
+
protectCoreSections: true,
|
|
26
|
+
unknownPluginPolicy: 'allow',
|
|
27
|
+
audit: DEFAULT_AUDIT_CONFIG,
|
|
28
|
+
metrics: DEFAULT_METRICS_CONFIG,
|
|
29
|
+
});
|
|
30
|
+
const nonEmptyString = z.string().min(1);
|
|
31
|
+
const stringList = z.array(nonEmptyString);
|
|
32
|
+
/** Runtime schema consumed by the Cordis loader. */
|
|
33
|
+
export const ConfigSchema = z.object({
|
|
34
|
+
enabled: z.boolean().default(true),
|
|
35
|
+
// Keep preset-owned fields absent until resolveConfig(). Applying schema
|
|
36
|
+
// defaults here would make `preset: strict` look explicitly overridden.
|
|
37
|
+
mode: z.union(['off', 'audit', 'blocklist', 'allowlist']),
|
|
38
|
+
preset: z.union(['clean', 'strict', 'audit-only']),
|
|
39
|
+
blockedSections: stringList.default([]),
|
|
40
|
+
allowedSections: stringList.default([]),
|
|
41
|
+
blockedPrefixes: stringList.default([]),
|
|
42
|
+
allowedPrefixes: stringList.default([]),
|
|
43
|
+
blockedPatterns: stringList.default([]),
|
|
44
|
+
allowedPatterns: stringList.default([]),
|
|
45
|
+
protectedSections: stringList.default([]),
|
|
46
|
+
protectCoreSections: z.boolean().default(true),
|
|
47
|
+
unknownPluginPolicy: z.union(['allow', 'block']),
|
|
48
|
+
audit: z.object({
|
|
49
|
+
enabled: z.boolean().default(true),
|
|
50
|
+
logAllowed: z.boolean().default(false),
|
|
51
|
+
logBlocked: z.boolean().default(true),
|
|
52
|
+
includePreview: z.boolean().default(false),
|
|
53
|
+
previewChars: z.number().step(1).min(0).default(160),
|
|
54
|
+
historySize: z.number().step(1).min(0).default(100),
|
|
55
|
+
highlightNewSections: z.boolean().default(true),
|
|
56
|
+
}).default(DEFAULT_AUDIT_CONFIG),
|
|
57
|
+
metrics: z.object({
|
|
58
|
+
enabled: z.boolean().default(true),
|
|
59
|
+
}).default(DEFAULT_METRICS_CONFIG),
|
|
60
|
+
});
|
|
61
|
+
function mergeList(preset, configured) {
|
|
62
|
+
const result = [...new Set([...(preset ?? []), ...(configured ?? [])])];
|
|
63
|
+
if (result.some(value => value.length === 0)) {
|
|
64
|
+
throw new TypeError('firewall rules must not contain empty strings');
|
|
65
|
+
}
|
|
66
|
+
return Object.freeze(result);
|
|
67
|
+
}
|
|
68
|
+
export function resolveConfig(config = {}) {
|
|
69
|
+
const preset = getPreset(config.preset);
|
|
70
|
+
const resolved = {
|
|
71
|
+
enabled: config.enabled ?? DEFAULT_CONFIG.enabled,
|
|
72
|
+
mode: (config.mode ?? preset.mode ?? DEFAULT_CONFIG.mode),
|
|
73
|
+
...(config.preset === undefined ? {} : { preset: config.preset }),
|
|
74
|
+
blockedSections: mergeList(preset.blockedSections, config.blockedSections),
|
|
75
|
+
allowedSections: mergeList(preset.allowedSections, config.allowedSections),
|
|
76
|
+
blockedPrefixes: mergeList(preset.blockedPrefixes, config.blockedPrefixes),
|
|
77
|
+
allowedPrefixes: mergeList(preset.allowedPrefixes, config.allowedPrefixes),
|
|
78
|
+
blockedPatterns: mergeList(preset.blockedPatterns, config.blockedPatterns),
|
|
79
|
+
allowedPatterns: mergeList(preset.allowedPatterns, config.allowedPatterns),
|
|
80
|
+
protectedSections: mergeList(preset.protectedSections, config.protectedSections),
|
|
81
|
+
protectCoreSections: config.protectCoreSections
|
|
82
|
+
?? preset.protectCoreSections
|
|
83
|
+
?? DEFAULT_CONFIG.protectCoreSections,
|
|
84
|
+
unknownPluginPolicy: (config.unknownPluginPolicy
|
|
85
|
+
?? preset.unknownPluginPolicy
|
|
86
|
+
?? DEFAULT_CONFIG.unknownPluginPolicy),
|
|
87
|
+
audit: Object.freeze({
|
|
88
|
+
...DEFAULT_AUDIT_CONFIG,
|
|
89
|
+
...preset.audit,
|
|
90
|
+
...config.audit,
|
|
91
|
+
}),
|
|
92
|
+
metrics: Object.freeze({
|
|
93
|
+
...DEFAULT_METRICS_CONFIG,
|
|
94
|
+
...preset.metrics,
|
|
95
|
+
...config.metrics,
|
|
96
|
+
}),
|
|
97
|
+
};
|
|
98
|
+
return Object.freeze(resolved);
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/lib/firewall.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { AuditStore, createAuditResult } from './audit.js';
|
|
2
|
+
import { compileRules, evaluateSection } from './rules.js';
|
|
3
|
+
function errorMessage(error) {
|
|
4
|
+
return error instanceof Error ? error.message : String(error);
|
|
5
|
+
}
|
|
6
|
+
function validateAssembly(assembly) {
|
|
7
|
+
if (!Array.isArray(assembly.sections))
|
|
8
|
+
throw new TypeError('prompt assembly sections must be an array');
|
|
9
|
+
for (const section of assembly.sections) {
|
|
10
|
+
if (typeof section.name !== 'string' || section.name.length === 0) {
|
|
11
|
+
throw new TypeError('prompt section name must be a non-empty string');
|
|
12
|
+
}
|
|
13
|
+
if (typeof section.text !== 'string') {
|
|
14
|
+
throw new TypeError(`prompt section "${section.name}" text must be a string`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function logAudit(audit, config, logger) {
|
|
19
|
+
if (logger === undefined || !config.audit.enabled)
|
|
20
|
+
return;
|
|
21
|
+
const safeLog = (level, message) => {
|
|
22
|
+
try {
|
|
23
|
+
logger[level](message);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// Observability failures must not affect prompt policy.
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
safeLog('info', `[prompt-firewall] assembled prompt: ${audit.totalSections} sections, `
|
|
30
|
+
+ `${audit.charsBefore} chars, ~${audit.estimatedTokensBefore} estimated tokens`);
|
|
31
|
+
for (const section of audit.sections) {
|
|
32
|
+
if (section.decision === 'blocked' && config.audit.logBlocked) {
|
|
33
|
+
safeLog('warn', `[prompt-firewall] BLOCK ${section.name}: ${section.reason}, `
|
|
34
|
+
+ `${section.chars} chars, ~${section.estimatedTokens} estimated tokens`
|
|
35
|
+
+ (section.preview === undefined ? '' : `, preview=${JSON.stringify(section.preview)}`));
|
|
36
|
+
}
|
|
37
|
+
else if (section.decision !== 'blocked' && config.audit.logAllowed) {
|
|
38
|
+
safeLog('info', `[prompt-firewall] ${section.decision.toUpperCase()} ${section.name}: ${section.reason}, `
|
|
39
|
+
+ `${section.chars} chars, ~${section.estimatedTokens} estimated tokens`
|
|
40
|
+
+ (section.preview === undefined ? '' : `, preview=${JSON.stringify(section.preview)}`));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (audit.blockedSections > 0) {
|
|
44
|
+
safeLog('info', `[prompt-firewall] result: removed ${audit.blockedSections} sections, `
|
|
45
|
+
+ `${audit.charsRemoved} chars, ~${audit.estimatedTokensRemoved} estimated tokens`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Filter an already assembled DSH prompt. Any internal error is contained and
|
|
50
|
+
* returns the exact original object (fail-open).
|
|
51
|
+
*/
|
|
52
|
+
export function applyFirewall(assembly, options) {
|
|
53
|
+
try {
|
|
54
|
+
validateAssembly(assembly);
|
|
55
|
+
const { config } = options;
|
|
56
|
+
const rules = options.evaluate === undefined ? compileRules(config) : undefined;
|
|
57
|
+
const evaluator = options.evaluate ?? (section => evaluateSection(section, rules));
|
|
58
|
+
const sections = assembly.sections;
|
|
59
|
+
const complete = sections.some(section => section.complete === true);
|
|
60
|
+
const decisions = sections.map(section => (complete
|
|
61
|
+
? { action: 'allow', reason: 'complete-prompt-bypass' }
|
|
62
|
+
: evaluator(section)));
|
|
63
|
+
const audit = createAuditResult(sections, decisions, config.audit, complete ? 'complete prompt detected' : undefined);
|
|
64
|
+
if (config.audit.enabled)
|
|
65
|
+
options.auditStore?.record(audit);
|
|
66
|
+
if (config.metrics.enabled)
|
|
67
|
+
options.metrics?.record(audit);
|
|
68
|
+
logAudit(audit, config, options.logger);
|
|
69
|
+
if (!config.enabled || config.mode === 'off' || config.mode === 'audit' || complete)
|
|
70
|
+
return assembly;
|
|
71
|
+
if (!decisions.some(decision => decision.action === 'block'))
|
|
72
|
+
return assembly;
|
|
73
|
+
return {
|
|
74
|
+
...assembly,
|
|
75
|
+
sections: assembly.sections.filter((_, index) => decisions[index]?.action !== 'block'),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
try {
|
|
80
|
+
options.logger?.error(`[prompt-firewall] internal error; allowing original prompt: ${errorMessage(error)}`);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// Logging must never turn fail-open into a request failure.
|
|
84
|
+
}
|
|
85
|
+
return assembly;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=firewall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"firewall.js","sourceRoot":"","sources":["../src/firewall.ts"],"names":[],"mappings":"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"}
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
2
|
+
var useValue = arguments.length > 2;
|
|
3
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
4
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
5
|
+
}
|
|
6
|
+
return useValue ? value : void 0;
|
|
7
|
+
};
|
|
8
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
9
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
10
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
11
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
12
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
13
|
+
var _, done = false;
|
|
14
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
15
|
+
var context = {};
|
|
16
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
17
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
18
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
19
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
20
|
+
if (kind === "accessor") {
|
|
21
|
+
if (result === void 0) continue;
|
|
22
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
23
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
24
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
25
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
26
|
+
}
|
|
27
|
+
else if (_ = accept(result)) {
|
|
28
|
+
if (kind === "field") initializers.unshift(_);
|
|
29
|
+
else descriptor[key] = _;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
33
|
+
done = true;
|
|
34
|
+
};
|
|
35
|
+
import { Context } from '@deepseek-ai/cordis';
|
|
36
|
+
import { installSettingsSection, settingsNamespace } from '@deepseek-ai/dsh-settings';
|
|
37
|
+
import { Remote, TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
38
|
+
import { AuditStore } from './audit.js';
|
|
39
|
+
import { ConfigSchema, resolveConfig } from './config.js';
|
|
40
|
+
import { applyFirewall } from './firewall.js';
|
|
41
|
+
import { FirewallMetrics } from './metrics.js';
|
|
42
|
+
import { compileRules, evaluateSection } from './rules.js';
|
|
43
|
+
export * from './audit.js';
|
|
44
|
+
export * from './config.js';
|
|
45
|
+
export * from './firewall.js';
|
|
46
|
+
export * from './metrics.js';
|
|
47
|
+
export * from './presets.js';
|
|
48
|
+
export * from './rules.js';
|
|
49
|
+
export * from './types.js';
|
|
50
|
+
/** Cordis plugin ID. */
|
|
51
|
+
export const name = 'prompt-firewall';
|
|
52
|
+
export const inject = ['systemPrompt'];
|
|
53
|
+
export const PROMPT_FIREWALL_SETTINGS_NAMESPACE = settingsNamespace('prompt-firewall');
|
|
54
|
+
export const Config = ConfigSchema;
|
|
55
|
+
/** DSH Host plugin, public firewall service, and browser Remote owner. */
|
|
56
|
+
let PromptFirewall = (() => {
|
|
57
|
+
let _classSuper = TypertRemoteService;
|
|
58
|
+
let _instanceExtraInitializers = [];
|
|
59
|
+
let _inspect_decorators;
|
|
60
|
+
let _setSectionPolicy_decorators;
|
|
61
|
+
return class PromptFirewall extends _classSuper {
|
|
62
|
+
static {
|
|
63
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
64
|
+
_inspect_decorators = [Remote('inspect')];
|
|
65
|
+
_setSectionPolicy_decorators = [Remote('setSectionPolicy')];
|
|
66
|
+
__esDecorate(this, null, _inspect_decorators, { kind: "method", name: "inspect", static: false, private: false, access: { has: obj => "inspect" in obj, get: obj => obj.inspect }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
67
|
+
__esDecorate(this, null, _setSectionPolicy_decorators, { kind: "method", name: "setSectionPolicy", static: false, private: false, access: { has: obj => "setSectionPolicy" in obj, get: obj => obj.setSectionPolicy }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
68
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
69
|
+
}
|
|
70
|
+
static inject = inject;
|
|
71
|
+
static Config = ConfigSchema;
|
|
72
|
+
entryConfig = __runInitializers(this, _instanceExtraInitializers);
|
|
73
|
+
configSource;
|
|
74
|
+
resolvedConfig;
|
|
75
|
+
compiledRules;
|
|
76
|
+
audits;
|
|
77
|
+
metrics = new FirewallMetrics();
|
|
78
|
+
constructor(ctx, config = {}) {
|
|
79
|
+
super(ctx, 'promptFirewall', { namespace: 'promptFirewall' });
|
|
80
|
+
this.entryConfig = structuredClone(config);
|
|
81
|
+
this.configSource = () => this.entryConfig;
|
|
82
|
+
this.resolvedConfig = resolveConfig(config);
|
|
83
|
+
this.compiledRules = compileRules(this.resolvedConfig);
|
|
84
|
+
this.audits = new AuditStore(this.resolvedConfig.audit.historySize, this.resolvedConfig.audit.highlightNewSections);
|
|
85
|
+
installSettingsSection(ctx, PROMPT_FIREWALL_SETTINGS_NAMESPACE, ConfigSchema, this.entryConfig, {
|
|
86
|
+
setSource: current => { this.configSource = current; },
|
|
87
|
+
onChange: () => { this.reloadRules(); },
|
|
88
|
+
});
|
|
89
|
+
// Cordis has registration order plus `prepend`, not numeric priorities.
|
|
90
|
+
// Prepending makes this wrapper call downstream contributors first and
|
|
91
|
+
// apply policy while their final result unwinds back through this listener.
|
|
92
|
+
ctx.on('system-prompt/assemble', async (_assembly, _context, next) => {
|
|
93
|
+
const result = await next();
|
|
94
|
+
return applyFirewall(result, {
|
|
95
|
+
config: this.resolvedConfig,
|
|
96
|
+
auditStore: this.audits,
|
|
97
|
+
metrics: this.metrics,
|
|
98
|
+
logger: ctx.logger,
|
|
99
|
+
evaluate: section => evaluateSection(section, this.compiledRules),
|
|
100
|
+
});
|
|
101
|
+
}, { prepend: true });
|
|
102
|
+
}
|
|
103
|
+
inspectLast() {
|
|
104
|
+
return this.audits.last();
|
|
105
|
+
}
|
|
106
|
+
inspectHistory() {
|
|
107
|
+
return this.audits.entries();
|
|
108
|
+
}
|
|
109
|
+
getKnownSections() {
|
|
110
|
+
return this.audits.knownSections();
|
|
111
|
+
}
|
|
112
|
+
getMetrics() {
|
|
113
|
+
return this.metrics.snapshot();
|
|
114
|
+
}
|
|
115
|
+
getConfig() {
|
|
116
|
+
return structuredClone(this.resolvedConfig);
|
|
117
|
+
}
|
|
118
|
+
/** Return one consistent, content-safe browser inspector projection. */
|
|
119
|
+
inspect() {
|
|
120
|
+
return {
|
|
121
|
+
config: this.getConfig(),
|
|
122
|
+
last: this.inspectLast(),
|
|
123
|
+
knownSections: this.getKnownSections(),
|
|
124
|
+
metrics: this.getMetrics(),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
evaluateSection(section) {
|
|
128
|
+
return evaluateSection(section, this.compiledRules);
|
|
129
|
+
}
|
|
130
|
+
async setSectionPolicy(name, policy, expectedRevision) {
|
|
131
|
+
if (name.length === 0)
|
|
132
|
+
throw new TypeError('section name must be non-empty');
|
|
133
|
+
const settings = this.ctx.get('settings');
|
|
134
|
+
if (settings === undefined) {
|
|
135
|
+
throw new Error('prompt-firewall settings are unavailable; mount a DSH settings provider');
|
|
136
|
+
}
|
|
137
|
+
const current = this.configSource();
|
|
138
|
+
const without = (values) => ((values ?? []).filter(value => value !== name));
|
|
139
|
+
const allowedSections = without(current.allowedSections);
|
|
140
|
+
const blockedSections = without(current.blockedSections);
|
|
141
|
+
const protectedSections = without(current.protectedSections);
|
|
142
|
+
if (policy === 'allow')
|
|
143
|
+
allowedSections.push(name);
|
|
144
|
+
else if (policy === 'block')
|
|
145
|
+
blockedSections.push(name);
|
|
146
|
+
else if (policy === 'protect')
|
|
147
|
+
protectedSections.push(name);
|
|
148
|
+
await settings.update(PROMPT_FIREWALL_SETTINGS_NAMESPACE, {
|
|
149
|
+
allowedSections,
|
|
150
|
+
blockedSections,
|
|
151
|
+
protectedSections,
|
|
152
|
+
}, expectedRevision);
|
|
153
|
+
// The settings scope has committed synchronously by this point; refresh
|
|
154
|
+
// before the asynchronous watch callback so Remote callers observe their write.
|
|
155
|
+
this.reloadRules();
|
|
156
|
+
}
|
|
157
|
+
reloadRules() {
|
|
158
|
+
this.resolvedConfig = resolveConfig(this.configSource());
|
|
159
|
+
this.compiledRules = compileRules(this.resolvedConfig);
|
|
160
|
+
this.audits.configure(this.resolvedConfig.audit.historySize, this.resolvedConfig.audit.highlightNewSections);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
})();
|
|
164
|
+
export { PromptFirewall };
|
|
165
|
+
export default PromptFirewall;
|
|
166
|
+
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/metrics.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export const METRIC_NAMES = Object.freeze({
|
|
2
|
+
requestsTotal: 'dsh_prompt_firewall_requests_total',
|
|
3
|
+
sectionsTotal: 'dsh_prompt_firewall_sections_total',
|
|
4
|
+
sectionsBlockedTotal: 'dsh_prompt_firewall_sections_blocked_total',
|
|
5
|
+
charsRemovedTotal: 'dsh_prompt_firewall_chars_removed_total',
|
|
6
|
+
estimatedTokensRemovedTotal: 'dsh_prompt_firewall_estimated_tokens_removed_total',
|
|
7
|
+
});
|
|
8
|
+
const ZERO_SNAPSHOT = Object.freeze({
|
|
9
|
+
requestsTotal: 0,
|
|
10
|
+
sectionsTotal: 0,
|
|
11
|
+
sectionsBlockedTotal: 0,
|
|
12
|
+
charsRemovedTotal: 0,
|
|
13
|
+
estimatedTokensRemovedTotal: 0,
|
|
14
|
+
});
|
|
15
|
+
/** Backend-neutral, label-free counters suitable for UI or an OTel adapter. */
|
|
16
|
+
export class FirewallMetrics {
|
|
17
|
+
counters = { ...ZERO_SNAPSHOT };
|
|
18
|
+
record(result) {
|
|
19
|
+
this.counters.requestsTotal += 1;
|
|
20
|
+
this.counters.sectionsTotal += result.totalSections;
|
|
21
|
+
this.counters.sectionsBlockedTotal += result.blockedSections;
|
|
22
|
+
this.counters.charsRemovedTotal += result.charsRemoved;
|
|
23
|
+
this.counters.estimatedTokensRemovedTotal += result.estimatedTokensRemoved;
|
|
24
|
+
}
|
|
25
|
+
snapshot() {
|
|
26
|
+
return { ...this.counters };
|
|
27
|
+
}
|
|
28
|
+
namedSnapshot() {
|
|
29
|
+
return Object.freeze({
|
|
30
|
+
[METRIC_NAMES.requestsTotal]: this.counters.requestsTotal,
|
|
31
|
+
[METRIC_NAMES.sectionsTotal]: this.counters.sectionsTotal,
|
|
32
|
+
[METRIC_NAMES.sectionsBlockedTotal]: this.counters.sectionsBlockedTotal,
|
|
33
|
+
[METRIC_NAMES.charsRemovedTotal]: this.counters.charsRemovedTotal,
|
|
34
|
+
[METRIC_NAMES.estimatedTokensRemovedTotal]: this.counters.estimatedTokensRemovedTotal,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;IACxC,aAAa,EAAE,oCAAoC;IACnD,aAAa,EAAE,oCAAoC;IACnD,oBAAoB,EAAE,4CAA4C;IAClE,iBAAiB,EAAE,yCAAyC;IAC5D,2BAA2B,EAAE,oDAAoD;CACzE,CAAC,CAAA;AAIX,MAAM,aAAa,GAA4C,MAAM,CAAC,MAAM,CAAC;IAC3E,aAAa,EAAE,CAAC;IAChB,aAAa,EAAE,CAAC;IAChB,oBAAoB,EAAE,CAAC;IACvB,iBAAiB,EAAE,CAAC;IACpB,2BAA2B,EAAE,CAAC;CAC/B,CAAC,CAAA;AAEF,+EAA+E;AAC/E,MAAM,OAAO,eAAe;IAClB,QAAQ,GAAkC,EAAE,GAAG,aAAa,EAAE,CAAA;IAEtE,MAAM,CAAC,MAAyB;QAC9B,IAAI,CAAC,QAAQ,CAAC,aAAa,IAAI,CAAC,CAAA;QAChC,IAAI,CAAC,QAAQ,CAAC,aAAa,IAAI,MAAM,CAAC,aAAa,CAAA;QACnD,IAAI,CAAC,QAAQ,CAAC,oBAAoB,IAAI,MAAM,CAAC,eAAe,CAAA;QAC5D,IAAI,CAAC,QAAQ,CAAC,iBAAiB,IAAI,MAAM,CAAC,YAAY,CAAA;QACtD,IAAI,CAAC,QAAQ,CAAC,2BAA2B,IAAI,MAAM,CAAC,sBAAsB,CAAA;IAC5E,CAAC;IAED,QAAQ;QACN,OAAO,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAA;IAC7B,CAAC;IAED,aAAa;QACX,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,aAAa;YACzD,CAAC,YAAY,CAAC,aAAa,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,aAAa;YACzD,CAAC,YAAY,CAAC,oBAAoB,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,oBAAoB;YACvE,CAAC,YAAY,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,iBAAiB;YACjE,CAAC,YAAY,CAAC,2BAA2B,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,2BAA2B;SACtF,CAAC,CAAA;IACJ,CAAC;CACF"}
|
package/lib/presets.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const CLEAN_BLOCKED_SECTIONS = Object.freeze([
|
|
2
|
+
'plugin:dsh-liangshen',
|
|
3
|
+
'plugin:dsh-ssh',
|
|
4
|
+
'plugin:task-board',
|
|
5
|
+
'plugin:dsh-desktop-launcher',
|
|
6
|
+
]);
|
|
7
|
+
export const PRESETS = Object.freeze({
|
|
8
|
+
clean: Object.freeze({
|
|
9
|
+
mode: 'blocklist',
|
|
10
|
+
blockedSections: [...CLEAN_BLOCKED_SECTIONS],
|
|
11
|
+
}),
|
|
12
|
+
strict: Object.freeze({
|
|
13
|
+
mode: 'allowlist',
|
|
14
|
+
unknownPluginPolicy: 'block',
|
|
15
|
+
}),
|
|
16
|
+
'audit-only': Object.freeze({
|
|
17
|
+
mode: 'audit',
|
|
18
|
+
}),
|
|
19
|
+
});
|
|
20
|
+
export function getPreset(name) {
|
|
21
|
+
return name === undefined ? {} : PRESETS[name];
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=presets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.js","sourceRoot":"","sources":["../src/presets.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC;IAClD,sBAAsB;IACtB,gBAAgB;IAChB,mBAAmB;IACnB,6BAA6B;CACrB,CAAC,CAAA;AAEX,MAAM,CAAC,MAAM,OAAO,GAAqE,MAAM,CAAC,MAAM,CAAC;IACrG,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC;QACnB,IAAI,EAAE,WAAW;QACjB,eAAe,EAAE,CAAC,GAAG,sBAAsB,CAAC;KAC7C,CAAC;IACF,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC;QACpB,IAAI,EAAE,WAAW;QACjB,mBAAmB,EAAE,OAAO;KAC7B,CAAC;IACF,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC;QAC1B,IAAI,EAAE,OAAO;KACd,CAAC;CACH,CAAC,CAAA;AAEF,MAAM,UAAU,SAAS,CAAC,IAAgC;IACxD,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AAChD,CAAC"}
|
package/lib/rules.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verified against the upstream DSH registry. `harness:` and `deployment:` are
|
|
3
|
+
* emitted by dsh-system-prompt; `tool:` and `tools:` are used for tool guidance.
|
|
4
|
+
* The remaining conservative namespaces are retained for compatible hosts.
|
|
5
|
+
*/
|
|
6
|
+
export const CORE_SECTION_PREFIXES = Object.freeze([
|
|
7
|
+
'harness:',
|
|
8
|
+
'deployment:',
|
|
9
|
+
'tool:',
|
|
10
|
+
'tools:',
|
|
11
|
+
'runtime:',
|
|
12
|
+
'system:',
|
|
13
|
+
]);
|
|
14
|
+
function escapeRegExp(value) {
|
|
15
|
+
return value.replace(/[|\\{}()[\]^$+?.]/g, '\\$&');
|
|
16
|
+
}
|
|
17
|
+
export function globToRegExp(glob) {
|
|
18
|
+
let source = '';
|
|
19
|
+
for (const character of glob) {
|
|
20
|
+
if (character === '*')
|
|
21
|
+
source += '.*';
|
|
22
|
+
else if (character === '?')
|
|
23
|
+
source += '.';
|
|
24
|
+
else
|
|
25
|
+
source += escapeRegExp(character);
|
|
26
|
+
}
|
|
27
|
+
return new RegExp(`^${source}$`, 'u');
|
|
28
|
+
}
|
|
29
|
+
function compilePatterns(patterns) {
|
|
30
|
+
return Object.freeze(patterns.map(source => Object.freeze({
|
|
31
|
+
source,
|
|
32
|
+
expression: globToRegExp(source),
|
|
33
|
+
})));
|
|
34
|
+
}
|
|
35
|
+
export function compileRules(config) {
|
|
36
|
+
return Object.freeze({
|
|
37
|
+
config,
|
|
38
|
+
protectedSections: new Set(config.protectedSections),
|
|
39
|
+
allowedSections: new Set(config.allowedSections),
|
|
40
|
+
blockedSections: new Set(config.blockedSections),
|
|
41
|
+
allowedPrefixes: Object.freeze([...config.allowedPrefixes]),
|
|
42
|
+
blockedPrefixes: Object.freeze([...config.blockedPrefixes]),
|
|
43
|
+
allowedPatterns: compilePatterns(config.allowedPatterns),
|
|
44
|
+
blockedPatterns: compilePatterns(config.blockedPatterns),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
function prefixMatch(name, prefixes) {
|
|
48
|
+
return prefixes.find(prefix => name.startsWith(prefix));
|
|
49
|
+
}
|
|
50
|
+
function patternMatch(name, patterns) {
|
|
51
|
+
return patterns.find(pattern => pattern.expression.test(name))?.source;
|
|
52
|
+
}
|
|
53
|
+
export function evaluateSection(section, rules) {
|
|
54
|
+
const { name } = section;
|
|
55
|
+
if (typeof name !== 'string' || name.length === 0) {
|
|
56
|
+
throw new TypeError('prompt section name must be a non-empty string');
|
|
57
|
+
}
|
|
58
|
+
if (rules.protectedSections.has(name)) {
|
|
59
|
+
return { action: 'protect', reason: 'exact-protect', rule: name };
|
|
60
|
+
}
|
|
61
|
+
if (rules.config.protectCoreSections) {
|
|
62
|
+
const corePrefix = prefixMatch(name, CORE_SECTION_PREFIXES);
|
|
63
|
+
if (corePrefix !== undefined) {
|
|
64
|
+
return { action: 'protect', reason: 'core-protect', rule: corePrefix };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (!rules.config.enabled || rules.config.mode === 'off') {
|
|
68
|
+
return { action: 'allow', reason: 'mode-off' };
|
|
69
|
+
}
|
|
70
|
+
if (rules.config.mode === 'audit') {
|
|
71
|
+
return { action: 'allow', reason: 'mode-audit' };
|
|
72
|
+
}
|
|
73
|
+
if (rules.allowedSections.has(name)) {
|
|
74
|
+
return { action: 'allow', reason: 'exact-allow', rule: name };
|
|
75
|
+
}
|
|
76
|
+
if (rules.blockedSections.has(name)) {
|
|
77
|
+
return { action: 'block', reason: 'exact-block', rule: name };
|
|
78
|
+
}
|
|
79
|
+
const allowedPrefix = prefixMatch(name, rules.allowedPrefixes);
|
|
80
|
+
if (allowedPrefix !== undefined) {
|
|
81
|
+
return { action: 'allow', reason: 'prefix-allow', rule: allowedPrefix };
|
|
82
|
+
}
|
|
83
|
+
const blockedPrefix = prefixMatch(name, rules.blockedPrefixes);
|
|
84
|
+
if (blockedPrefix !== undefined) {
|
|
85
|
+
return { action: 'block', reason: 'prefix-block', rule: blockedPrefix };
|
|
86
|
+
}
|
|
87
|
+
const allowedPattern = patternMatch(name, rules.allowedPatterns);
|
|
88
|
+
if (allowedPattern !== undefined) {
|
|
89
|
+
return { action: 'allow', reason: 'pattern-allow', rule: allowedPattern };
|
|
90
|
+
}
|
|
91
|
+
const blockedPattern = patternMatch(name, rules.blockedPatterns);
|
|
92
|
+
if (blockedPattern !== undefined) {
|
|
93
|
+
return { action: 'block', reason: 'pattern-block', rule: blockedPattern };
|
|
94
|
+
}
|
|
95
|
+
if (rules.config.mode === 'allowlist') {
|
|
96
|
+
return { action: 'block', reason: 'allowlist-default' };
|
|
97
|
+
}
|
|
98
|
+
if (rules.config.unknownPluginPolicy === 'block' && name.startsWith('plugin:')) {
|
|
99
|
+
return { action: 'block', reason: 'unknown-plugin-policy' };
|
|
100
|
+
}
|
|
101
|
+
return { action: 'allow', reason: 'blocklist-default' };
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=rules.js.map
|
package/lib/rules.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"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"}
|