@guardbee/guard-core 0.2.0 → 0.3.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/README.md +4 -1
- package/TR.md +37 -0
- package/ZH.md +37 -0
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +8 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/policy.d.ts +242 -0
- package/dist/cjs/policy.d.ts.map +1 -0
- package/dist/cjs/policy.js +80 -0
- package/dist/cjs/policy.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/policy.d.ts +242 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +76 -0
- package/dist/policy.js.map +1 -0
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# @guardbee/guard-core
|
|
2
2
|
|
|
3
|
+
**🇬🇧 English** | [🇹🇷 Türkçe](TR.md) | [🇨🇳 中文](ZH.md)
|
|
4
|
+
|
|
3
5
|
Shared detectors used by other GuardBee MCP packages. Not an MCP server on its own, just a library — you don't need to install this package directly.
|
|
4
6
|
|
|
5
7
|
It exists so the same rule runs everywhere: a static scanner flagging a pattern and the runtime proxy blocking it use one implementation.
|
|
@@ -13,6 +15,7 @@ It exists so the same rule runs everywhere: a static scanner flagging a pattern
|
|
|
13
15
|
| `isValidTcKimlik`, `isValidVkn`, `isValidIban`, `isValidLuhn`, `isValidTrPhone` | security-proxy, prompt-leak-scanner | Validation after a regex match |
|
|
14
16
|
| `INJECTION_RULES`, `findInjections` | prompt-injection-scanner, security-proxy | 27 injection rules in English and Turkish, with base64-decoding; the scanner uses the 17 precise ones |
|
|
15
17
|
| `scanForPromptInjection`, `scanToolResult` | security-proxy | Block on a precise high/critical rule, warn on anything else |
|
|
18
|
+
| `gatewayPolicySchema`, `validatePolicy`, `policyShape` | security-proxy, app.guardbee.ai | The gateway policy document (labels, rules, taint, approval, defaults, interceptors). The dashboard validates an edit with it before saving, so a policy that saves is one the proxy accepts |
|
|
16
19
|
| `classifyTool`, `CAPABILITY_RULES` | toxic-flow-auditor, security-proxy | Label a tool as untrusted-content / sensitive-data / exfiltration / destructive (lethal trifecta) |
|
|
17
20
|
|
|
18
21
|
## Checksum-validated masking
|
|
@@ -25,7 +28,7 @@ A regex alone masks any 11-digit number as a TC Kimlik No and any 16-digit numbe
|
|
|
25
28
|
| VKN (tax number) | Gelir İdaresi check digit, and a `VKN` / `Vergi No` label before the number |
|
|
26
29
|
| IBAN | ISO 7064 MOD97-10 |
|
|
27
30
|
| Card number | Luhn |
|
|
28
|
-
| Phone (TR) | Mobile (5xx), landline (2xx–4xx) or 850 code
|
|
31
|
+
| Phone (TR) | Mobile (5xx), landline (2xx–4xx) or 850 code; written with a +90 / 0 prefix or grouped with spaces/dashes, and not part of a URL or id |
|
|
29
32
|
|
|
30
33
|
A match that fails its check (an order number, a tracking code) is left unchanged.
|
|
31
34
|
|
package/TR.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @guardbee/guard-core
|
|
2
|
+
|
|
3
|
+
[🇬🇧 English](README.md) | **🇹🇷 Türkçe** | [🇨🇳 中文](ZH.md)
|
|
4
|
+
|
|
5
|
+
Diğer GuardBee MCP paketlerinin kullandığı ortak dedektörler. Kendi başına bir MCP server değil, sadece bir kütüphane — bu paketi doğrudan kurmanız gerekmez.
|
|
6
|
+
|
|
7
|
+
Amacı, aynı kuralın her yerde çalışması: bir kalıbı raporlayan statik tarayıcı ile onu çalışma anında engelleyen proxy tek bir uygulamayı kullanır.
|
|
8
|
+
|
|
9
|
+
## İçinde neler var
|
|
10
|
+
|
|
11
|
+
| Export | Kullanan | Amaç |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| `maskPiiInText`, `maskPiiInValue`, `PII_PATTERNS` | security-proxy | Tool sonuçlarında TC Kimlik No, VKN, IBAN, kart, telefon, e-posta, sağlayıcı API key'leri, özel anahtarlar, bağlantı dizeleri ve JWT'leri maskeler; isteğe bağlı bir replacer eşleşmeleri token'a çevirir |
|
|
14
|
+
| `SECRET_RULES` | secret-scanner, security-proxy | 38 secret kuralı (sağlayıcı anahtar ve token'ları, özel anahtarlar, bağlantı dizeleri, JWT). Tarayıcı hepsini raporlar; proxy `broad` işaretli olmayan 32'sini maskeler |
|
|
15
|
+
| `isValidTcKimlik`, `isValidVkn`, `isValidIban`, `isValidLuhn`, `isValidTrPhone` | security-proxy, prompt-leak-scanner | Regex eşleşmesinden sonra doğrulama |
|
|
16
|
+
| `INJECTION_RULES`, `findInjections` | prompt-injection-scanner, security-proxy | İngilizce ve Türkçe 27 injection kuralı, base64 çözme dahil; tarayıcı 17 kesin kuralı kullanır |
|
|
17
|
+
| `scanForPromptInjection`, `scanToolResult` | security-proxy | Kesin bir high/critical kuralda engeller, geri kalan her şeyde uyarır |
|
|
18
|
+
| `gatewayPolicySchema`, `validatePolicy`, `policyShape` | security-proxy, app.guardbee.ai | Gateway politika belgesi (etiketler, kurallar, taint, onay, varsayılanlar, interceptor'lar). Dashboard bir düzenlemeyi kaydetmeden önce bununla doğrular; kaydedilen politika proxy'nin kabul ettiği politikadır |
|
|
19
|
+
| `classifyTool`, `CAPABILITY_RULES` | toxic-flow-auditor, security-proxy | Bir tool'u untrusted-content / sensitive-data / exfiltration / destructive olarak etiketler (lethal trifecta) |
|
|
20
|
+
|
|
21
|
+
## Checksum doğrulamalı maskeleme
|
|
22
|
+
|
|
23
|
+
Tek başına regex, 11 haneli her sayıyı TC Kimlik No, 16 haneli her sayıyı kart numarası sanar. Artık her eşleşme maskelenmeden önce kontrol edilir:
|
|
24
|
+
|
|
25
|
+
| Kalıp | Kontrol |
|
|
26
|
+
|---|---|
|
|
27
|
+
| TC Kimlik No | Resmi 10. ve 11. hane algoritması |
|
|
28
|
+
| VKN (vergi kimlik no) | Gelir İdaresi kontrol hanesi ve sayıdan önce bir `VKN` / `Vergi No` etiketi |
|
|
29
|
+
| IBAN | ISO 7064 MOD97-10 |
|
|
30
|
+
| Kart numarası | Luhn |
|
|
31
|
+
| Telefon (TR) | Cep (5xx), sabit hat (2xx–4xx) veya 850 kodu; +90 / 0 önekiyle ya da boşluk/tire ile gruplanmış yazılmış olmalı, bir URL'nin veya kimliğin parçası olmamalı |
|
|
32
|
+
|
|
33
|
+
Kontrolden geçemeyen eşleşme (sipariş no, takip kodu) olduğu gibi bırakılır.
|
|
34
|
+
|
|
35
|
+
## Kesin ve genel kurallar
|
|
36
|
+
|
|
37
|
+
Injection ve secret kuralları, sıradan metinde de eşleşen kalıplar için bir `broad` bayrağı taşır: "act as", "developer mode", 40 karakterlik herhangi bir base64 dizisi, yayınlanabilir (publishable) bir Stripe anahtarı. Bulguyu bir kişiye gösteren statik tarayıcılar genel injection kurallarını atlar; çalışma anındaki proxy ise genel bir kurala dayanarak asla engelleme veya maskeleme yapmaz, çünkü oradaki yanlış bir eşleşme oturumu hassas veri tutuyor diye de işaretler ya da meşru bir çağrıyı durdurur.
|
package/ZH.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @guardbee/guard-core
|
|
2
|
+
|
|
3
|
+
[🇬🇧 English](README.md) | [🇹🇷 Türkçe](TR.md) | **🇨🇳 中文**
|
|
4
|
+
|
|
5
|
+
其他 GuardBee MCP 包共用的检测规则库。它本身不是 MCP 服务器,只是一个库——你不需要直接安装这个包。
|
|
6
|
+
|
|
7
|
+
它存在的目的是让同一条规则在所有地方运行:报告某个模式的静态扫描器,和在运行时拦截它的代理,使用的是同一份实现。
|
|
8
|
+
|
|
9
|
+
## 包含内容
|
|
10
|
+
|
|
11
|
+
| 导出 | 使用方 | 用途 |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| `maskPiiInText`、`maskPiiInValue`、`PII_PATTERNS` | security-proxy | 对工具结果中的土耳其身份证号(TC Kimlik No)、税号(VKN)、IBAN、银行卡、电话、电子邮件、服务商 API 密钥、私钥、数据库连接串和 JWT 进行脱敏;可选的 replacer 可以把匹配项转换为令牌 |
|
|
14
|
+
| `SECRET_RULES` | secret-scanner、security-proxy | 38 条密钥规则(服务商密钥和令牌、私钥、数据库连接串、JWT)。扫描器会报告全部规则;代理只对未标记 `broad` 的 32 条进行脱敏 |
|
|
15
|
+
| `isValidTcKimlik`、`isValidVkn`、`isValidIban`、`isValidLuhn`、`isValidTrPhone` | security-proxy、prompt-leak-scanner | 正则匹配之后的校验 |
|
|
16
|
+
| `INJECTION_RULES`、`findInjections` | prompt-injection-scanner、security-proxy | 27 条英文和土耳其语注入规则,包含 base64 解码;扫描器使用其中 17 条精确规则 |
|
|
17
|
+
| `scanForPromptInjection`、`scanToolResult` | security-proxy | 命中精确的 high/critical 规则时拦截,其余情况只警告 |
|
|
18
|
+
| `gatewayPolicySchema`、`validatePolicy`、`policyShape` | security-proxy、app.guardbee.ai | 网关策略文档(标签、规则、污点、审批、默认值、拦截器)。仪表盘在保存编辑前用它校验,因此能保存的策略就是代理会接受的策略 |
|
|
19
|
+
| `classifyTool`、`CAPABILITY_RULES` | toxic-flow-auditor、security-proxy | 把工具标记为 untrusted-content / sensitive-data / exfiltration / destructive(lethal trifecta) |
|
|
20
|
+
|
|
21
|
+
## 经校验和验证的脱敏
|
|
22
|
+
|
|
23
|
+
单靠正则,会把任何 11 位数字当成 TC Kimlik No,把任何 16 位数字当成银行卡号。现在每个匹配在脱敏前都会先经过检查:
|
|
24
|
+
|
|
25
|
+
| 模式 | 检查 |
|
|
26
|
+
|---|---|
|
|
27
|
+
| TC Kimlik No | 官方的第 10、11 位校验算法 |
|
|
28
|
+
| VKN(税号) | 土耳其税务局(Gelir İdaresi)校验位,且数字前需有 `VKN` / `Vergi No` 标签 |
|
|
29
|
+
| IBAN | ISO 7064 MOD97-10 |
|
|
30
|
+
| 银行卡号 | Luhn |
|
|
31
|
+
| 电话(土耳其) | 手机(5xx)、座机(2xx–4xx)或 850 号段;需带 +90 / 0 前缀,或用空格/短横线分组书写,且不能是 URL 或 ID 的一部分 |
|
|
32
|
+
|
|
33
|
+
未通过检查的匹配(订单号、快递单号)保持原样。
|
|
34
|
+
|
|
35
|
+
## 精确规则与通用规则
|
|
36
|
+
|
|
37
|
+
注入规则和密钥规则都带有一个 `broad` 标记,用于那些在普通文本中也会匹配的模式:"act as"、"developer mode"、任意 40 个字符的 base64 串、可公开的 Stripe publishable key。把结果展示给人看的静态扫描器会跳过通用注入规则;运行时代理则从不基于通用规则进行拦截或脱敏,因为在那里一次误匹配还会把会话标记为持有敏感数据,或拦下一次正常调用。
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -7,4 +7,6 @@ export { INJECTION_RULES, INJECTION_PATTERNS, findInjections, scanForPromptInjec
|
|
|
7
7
|
export type { ScanResult, InjectionRule, InjectionCategory, InjectionFinding } from "./injection.js";
|
|
8
8
|
export { CAPABILITY_RULES, classifyTool, textOf } from "./classify.js";
|
|
9
9
|
export type { Capability, FlowCategory, ToolRecord } from "./classify.js";
|
|
10
|
+
export { POLICY_LABELS, POLICY_ACTIONS, policyRuleSchema, policyShape, gatewayPolicySchema, validatePolicy } from "./policy.js";
|
|
11
|
+
export type { GatewayPolicy, PolicyValidation } from "./policy.js";
|
|
10
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAChI,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.textOf = exports.classifyTool = exports.CAPABILITY_RULES = exports.scanToolResult = exports.scanForPromptInjection = exports.findInjections = exports.INJECTION_PATTERNS = exports.INJECTION_RULES = exports.SECRET_RULES = exports.maskPiiInValue = exports.maskPiiInText = exports.PII_PATTERNS = exports.isValidTrPhone = exports.isValidVkn = exports.isValidIban = exports.isValidLuhn = exports.isValidTcKimlik = void 0;
|
|
3
|
+
exports.validatePolicy = exports.gatewayPolicySchema = exports.policyShape = exports.policyRuleSchema = exports.POLICY_ACTIONS = exports.POLICY_LABELS = exports.textOf = exports.classifyTool = exports.CAPABILITY_RULES = exports.scanToolResult = exports.scanForPromptInjection = exports.findInjections = exports.INJECTION_PATTERNS = exports.INJECTION_RULES = exports.SECRET_RULES = exports.maskPiiInValue = exports.maskPiiInText = exports.PII_PATTERNS = exports.isValidTrPhone = exports.isValidVkn = exports.isValidIban = exports.isValidLuhn = exports.isValidTcKimlik = void 0;
|
|
4
4
|
var validators_js_1 = require("./validators.js");
|
|
5
5
|
Object.defineProperty(exports, "isValidTcKimlik", { enumerable: true, get: function () { return validators_js_1.isValidTcKimlik; } });
|
|
6
6
|
Object.defineProperty(exports, "isValidLuhn", { enumerable: true, get: function () { return validators_js_1.isValidLuhn; } });
|
|
@@ -23,4 +23,11 @@ var classify_js_1 = require("./classify.js");
|
|
|
23
23
|
Object.defineProperty(exports, "CAPABILITY_RULES", { enumerable: true, get: function () { return classify_js_1.CAPABILITY_RULES; } });
|
|
24
24
|
Object.defineProperty(exports, "classifyTool", { enumerable: true, get: function () { return classify_js_1.classifyTool; } });
|
|
25
25
|
Object.defineProperty(exports, "textOf", { enumerable: true, get: function () { return classify_js_1.textOf; } });
|
|
26
|
+
var policy_js_1 = require("./policy.js");
|
|
27
|
+
Object.defineProperty(exports, "POLICY_LABELS", { enumerable: true, get: function () { return policy_js_1.POLICY_LABELS; } });
|
|
28
|
+
Object.defineProperty(exports, "POLICY_ACTIONS", { enumerable: true, get: function () { return policy_js_1.POLICY_ACTIONS; } });
|
|
29
|
+
Object.defineProperty(exports, "policyRuleSchema", { enumerable: true, get: function () { return policy_js_1.policyRuleSchema; } });
|
|
30
|
+
Object.defineProperty(exports, "policyShape", { enumerable: true, get: function () { return policy_js_1.policyShape; } });
|
|
31
|
+
Object.defineProperty(exports, "gatewayPolicySchema", { enumerable: true, get: function () { return policy_js_1.gatewayPolicySchema; } });
|
|
32
|
+
Object.defineProperty(exports, "validatePolicy", { enumerable: true, get: function () { return policy_js_1.validatePolicy; } });
|
|
26
33
|
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,iDAAwG;AAA/F,gHAAA,eAAe,OAAA;AAAE,4GAAA,WAAW,OAAA;AAAE,4GAAA,WAAW,OAAA;AAAE,2GAAA,UAAU,OAAA;AAAE,+GAAA,cAAc,OAAA;AAC9E,mCAAuE;AAA9D,sGAAA,YAAY,OAAA;AAAE,uGAAA,aAAa,OAAA;AAAE,wGAAA,cAAc,OAAA;AAEpD,2CAA4C;AAAnC,0GAAA,YAAY,OAAA;AAErB,+CAMwB;AALtB,+GAAA,eAAe,OAAA;AACf,kHAAA,kBAAkB,OAAA;AAClB,8GAAA,cAAc,OAAA;AACd,sHAAA,sBAAsB,OAAA;AACtB,8GAAA,cAAc,OAAA;AAGhB,6CAAuE;AAA9D,+GAAA,gBAAgB,OAAA;AAAE,2GAAA,YAAY,OAAA;AAAE,qGAAA,MAAM,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,iDAAwG;AAA/F,gHAAA,eAAe,OAAA;AAAE,4GAAA,WAAW,OAAA;AAAE,4GAAA,WAAW,OAAA;AAAE,2GAAA,UAAU,OAAA;AAAE,+GAAA,cAAc,OAAA;AAC9E,mCAAuE;AAA9D,sGAAA,YAAY,OAAA;AAAE,uGAAA,aAAa,OAAA;AAAE,wGAAA,cAAc,OAAA;AAEpD,2CAA4C;AAAnC,0GAAA,YAAY,OAAA;AAErB,+CAMwB;AALtB,+GAAA,eAAe,OAAA;AACf,kHAAA,kBAAkB,OAAA;AAClB,8GAAA,cAAc,OAAA;AACd,sHAAA,sBAAsB,OAAA;AACtB,8GAAA,cAAc,OAAA;AAGhB,6CAAuE;AAA9D,+GAAA,gBAAgB,OAAA;AAAE,2GAAA,YAAY,OAAA;AAAE,qGAAA,MAAM,OAAA;AAE/C,yCAAgI;AAAvH,0GAAA,aAAa,OAAA;AAAE,2GAAA,cAAc,OAAA;AAAE,6GAAA,gBAAgB,OAAA;AAAE,wGAAA,WAAW,OAAA;AAAE,gHAAA,mBAAmB,OAAA;AAAE,2GAAA,cAAc,OAAA"}
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* The policy part of a GuardBee MCP gateway config: what may run and how.
|
|
4
|
+
* security-proxy reads it from guardbee-proxy.yaml or from the dashboard; the
|
|
5
|
+
* dashboard validates an edit with the same schema before it saves it, so a
|
|
6
|
+
* policy that saves is a policy the proxy accepts. Deployment settings
|
|
7
|
+
* (upstreams, listen, audit) stay out: they hold commands and secrets.
|
|
8
|
+
*/
|
|
9
|
+
export declare const POLICY_LABELS: readonly ["untrusted", "sensitive", "egress", "destructive"];
|
|
10
|
+
export declare const POLICY_ACTIONS: readonly ["allow", "deny", "mask", "warn", "approve"];
|
|
11
|
+
export declare const policyRuleSchema: z.ZodObject<{
|
|
12
|
+
id: z.ZodOptional<z.ZodString>;
|
|
13
|
+
match: z.ZodObject<{
|
|
14
|
+
tool: z.ZodOptional<z.ZodString>;
|
|
15
|
+
upstream: z.ZodOptional<z.ZodString>;
|
|
16
|
+
label: z.ZodOptional<z.ZodEnum<{
|
|
17
|
+
destructive: "destructive";
|
|
18
|
+
untrusted: "untrusted";
|
|
19
|
+
sensitive: "sensitive";
|
|
20
|
+
egress: "egress";
|
|
21
|
+
}>>;
|
|
22
|
+
session: z.ZodOptional<z.ZodEnum<{
|
|
23
|
+
clean: "clean";
|
|
24
|
+
tainted: "tainted";
|
|
25
|
+
}>>;
|
|
26
|
+
args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
27
|
+
}, z.core.$strict>;
|
|
28
|
+
action: z.ZodEnum<{
|
|
29
|
+
allow: "allow";
|
|
30
|
+
warn: "warn";
|
|
31
|
+
deny: "deny";
|
|
32
|
+
mask: "mask";
|
|
33
|
+
approve: "approve";
|
|
34
|
+
}>;
|
|
35
|
+
mask: z.ZodOptional<z.ZodObject<{
|
|
36
|
+
fields: z.ZodArray<z.ZodString>;
|
|
37
|
+
}, z.core.$strict>>;
|
|
38
|
+
}, z.core.$strict>;
|
|
39
|
+
/** Every field has a default, so `{}` is a valid (allow-all, strict-taint) policy. */
|
|
40
|
+
export declare const policyShape: {
|
|
41
|
+
labels: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodEnum<{
|
|
42
|
+
destructive: "destructive";
|
|
43
|
+
untrusted: "untrusted";
|
|
44
|
+
sensitive: "sensitive";
|
|
45
|
+
egress: "egress";
|
|
46
|
+
}>>>>;
|
|
47
|
+
rules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
48
|
+
id: z.ZodOptional<z.ZodString>;
|
|
49
|
+
match: z.ZodObject<{
|
|
50
|
+
tool: z.ZodOptional<z.ZodString>;
|
|
51
|
+
upstream: z.ZodOptional<z.ZodString>;
|
|
52
|
+
label: z.ZodOptional<z.ZodEnum<{
|
|
53
|
+
destructive: "destructive";
|
|
54
|
+
untrusted: "untrusted";
|
|
55
|
+
sensitive: "sensitive";
|
|
56
|
+
egress: "egress";
|
|
57
|
+
}>>;
|
|
58
|
+
session: z.ZodOptional<z.ZodEnum<{
|
|
59
|
+
clean: "clean";
|
|
60
|
+
tainted: "tainted";
|
|
61
|
+
}>>;
|
|
62
|
+
args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
63
|
+
}, z.core.$strict>;
|
|
64
|
+
action: z.ZodEnum<{
|
|
65
|
+
allow: "allow";
|
|
66
|
+
warn: "warn";
|
|
67
|
+
deny: "deny";
|
|
68
|
+
mask: "mask";
|
|
69
|
+
approve: "approve";
|
|
70
|
+
}>;
|
|
71
|
+
mask: z.ZodOptional<z.ZodObject<{
|
|
72
|
+
fields: z.ZodArray<z.ZodString>;
|
|
73
|
+
}, z.core.$strict>>;
|
|
74
|
+
}, z.core.$strict>>>;
|
|
75
|
+
taint: z.ZodDefault<z.ZodObject<{
|
|
76
|
+
mode: z.ZodDefault<z.ZodEnum<{
|
|
77
|
+
warn: "warn";
|
|
78
|
+
approve: "approve";
|
|
79
|
+
strict: "strict";
|
|
80
|
+
off: "off";
|
|
81
|
+
}>>;
|
|
82
|
+
}, z.core.$strict>>;
|
|
83
|
+
approval: z.ZodDefault<z.ZodObject<{
|
|
84
|
+
timeoutSeconds: z.ZodDefault<z.ZodNumber>;
|
|
85
|
+
channels: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
86
|
+
elicitation: "elicitation";
|
|
87
|
+
dashboard: "dashboard";
|
|
88
|
+
}>>>;
|
|
89
|
+
}, z.core.$strict>>;
|
|
90
|
+
defaults: z.ZodDefault<z.ZodObject<{
|
|
91
|
+
action: z.ZodDefault<z.ZodEnum<{
|
|
92
|
+
allow: "allow";
|
|
93
|
+
warn: "warn";
|
|
94
|
+
deny: "deny";
|
|
95
|
+
mask: "mask";
|
|
96
|
+
approve: "approve";
|
|
97
|
+
}>>;
|
|
98
|
+
}, z.core.$strict>>;
|
|
99
|
+
interceptors: z.ZodDefault<z.ZodObject<{
|
|
100
|
+
promptInjection: z.ZodOptional<z.ZodObject<{
|
|
101
|
+
enabled: z.ZodBoolean;
|
|
102
|
+
action: z.ZodEnum<{
|
|
103
|
+
block: "block";
|
|
104
|
+
warn: "warn";
|
|
105
|
+
}>;
|
|
106
|
+
}, z.core.$strict>>;
|
|
107
|
+
toolResultInjection: z.ZodOptional<z.ZodObject<{
|
|
108
|
+
enabled: z.ZodBoolean;
|
|
109
|
+
action: z.ZodEnum<{
|
|
110
|
+
block: "block";
|
|
111
|
+
warn: "warn";
|
|
112
|
+
}>;
|
|
113
|
+
}, z.core.$strict>>;
|
|
114
|
+
definitionDrift: z.ZodOptional<z.ZodObject<{
|
|
115
|
+
enabled: z.ZodBoolean;
|
|
116
|
+
action: z.ZodEnum<{
|
|
117
|
+
block: "block";
|
|
118
|
+
warn: "warn";
|
|
119
|
+
}>;
|
|
120
|
+
recheck: z.ZodOptional<z.ZodEnum<{
|
|
121
|
+
"every-call": "every-call";
|
|
122
|
+
"on-change": "on-change";
|
|
123
|
+
}>>;
|
|
124
|
+
}, z.core.$strict>>;
|
|
125
|
+
piiMasking: z.ZodOptional<z.ZodObject<{
|
|
126
|
+
enabled: z.ZodBoolean;
|
|
127
|
+
patterns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
128
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
129
|
+
redact: "redact";
|
|
130
|
+
tokenize: "tokenize";
|
|
131
|
+
}>>;
|
|
132
|
+
detokenizeForEgress: z.ZodOptional<z.ZodBoolean>;
|
|
133
|
+
}, z.core.$strict>>;
|
|
134
|
+
}, z.core.$strict>>;
|
|
135
|
+
};
|
|
136
|
+
export declare const gatewayPolicySchema: z.ZodObject<{
|
|
137
|
+
labels: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodEnum<{
|
|
138
|
+
destructive: "destructive";
|
|
139
|
+
untrusted: "untrusted";
|
|
140
|
+
sensitive: "sensitive";
|
|
141
|
+
egress: "egress";
|
|
142
|
+
}>>>>;
|
|
143
|
+
rules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
144
|
+
id: z.ZodOptional<z.ZodString>;
|
|
145
|
+
match: z.ZodObject<{
|
|
146
|
+
tool: z.ZodOptional<z.ZodString>;
|
|
147
|
+
upstream: z.ZodOptional<z.ZodString>;
|
|
148
|
+
label: z.ZodOptional<z.ZodEnum<{
|
|
149
|
+
destructive: "destructive";
|
|
150
|
+
untrusted: "untrusted";
|
|
151
|
+
sensitive: "sensitive";
|
|
152
|
+
egress: "egress";
|
|
153
|
+
}>>;
|
|
154
|
+
session: z.ZodOptional<z.ZodEnum<{
|
|
155
|
+
clean: "clean";
|
|
156
|
+
tainted: "tainted";
|
|
157
|
+
}>>;
|
|
158
|
+
args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
159
|
+
}, z.core.$strict>;
|
|
160
|
+
action: z.ZodEnum<{
|
|
161
|
+
allow: "allow";
|
|
162
|
+
warn: "warn";
|
|
163
|
+
deny: "deny";
|
|
164
|
+
mask: "mask";
|
|
165
|
+
approve: "approve";
|
|
166
|
+
}>;
|
|
167
|
+
mask: z.ZodOptional<z.ZodObject<{
|
|
168
|
+
fields: z.ZodArray<z.ZodString>;
|
|
169
|
+
}, z.core.$strict>>;
|
|
170
|
+
}, z.core.$strict>>>;
|
|
171
|
+
taint: z.ZodDefault<z.ZodObject<{
|
|
172
|
+
mode: z.ZodDefault<z.ZodEnum<{
|
|
173
|
+
warn: "warn";
|
|
174
|
+
approve: "approve";
|
|
175
|
+
strict: "strict";
|
|
176
|
+
off: "off";
|
|
177
|
+
}>>;
|
|
178
|
+
}, z.core.$strict>>;
|
|
179
|
+
approval: z.ZodDefault<z.ZodObject<{
|
|
180
|
+
timeoutSeconds: z.ZodDefault<z.ZodNumber>;
|
|
181
|
+
channels: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
182
|
+
elicitation: "elicitation";
|
|
183
|
+
dashboard: "dashboard";
|
|
184
|
+
}>>>;
|
|
185
|
+
}, z.core.$strict>>;
|
|
186
|
+
defaults: z.ZodDefault<z.ZodObject<{
|
|
187
|
+
action: z.ZodDefault<z.ZodEnum<{
|
|
188
|
+
allow: "allow";
|
|
189
|
+
warn: "warn";
|
|
190
|
+
deny: "deny";
|
|
191
|
+
mask: "mask";
|
|
192
|
+
approve: "approve";
|
|
193
|
+
}>>;
|
|
194
|
+
}, z.core.$strict>>;
|
|
195
|
+
interceptors: z.ZodDefault<z.ZodObject<{
|
|
196
|
+
promptInjection: z.ZodOptional<z.ZodObject<{
|
|
197
|
+
enabled: z.ZodBoolean;
|
|
198
|
+
action: z.ZodEnum<{
|
|
199
|
+
block: "block";
|
|
200
|
+
warn: "warn";
|
|
201
|
+
}>;
|
|
202
|
+
}, z.core.$strict>>;
|
|
203
|
+
toolResultInjection: z.ZodOptional<z.ZodObject<{
|
|
204
|
+
enabled: z.ZodBoolean;
|
|
205
|
+
action: z.ZodEnum<{
|
|
206
|
+
block: "block";
|
|
207
|
+
warn: "warn";
|
|
208
|
+
}>;
|
|
209
|
+
}, z.core.$strict>>;
|
|
210
|
+
definitionDrift: z.ZodOptional<z.ZodObject<{
|
|
211
|
+
enabled: z.ZodBoolean;
|
|
212
|
+
action: z.ZodEnum<{
|
|
213
|
+
block: "block";
|
|
214
|
+
warn: "warn";
|
|
215
|
+
}>;
|
|
216
|
+
recheck: z.ZodOptional<z.ZodEnum<{
|
|
217
|
+
"every-call": "every-call";
|
|
218
|
+
"on-change": "on-change";
|
|
219
|
+
}>>;
|
|
220
|
+
}, z.core.$strict>>;
|
|
221
|
+
piiMasking: z.ZodOptional<z.ZodObject<{
|
|
222
|
+
enabled: z.ZodBoolean;
|
|
223
|
+
patterns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
224
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
225
|
+
redact: "redact";
|
|
226
|
+
tokenize: "tokenize";
|
|
227
|
+
}>>;
|
|
228
|
+
detokenizeForEgress: z.ZodOptional<z.ZodBoolean>;
|
|
229
|
+
}, z.core.$strict>>;
|
|
230
|
+
}, z.core.$strict>>;
|
|
231
|
+
}, z.core.$strict>;
|
|
232
|
+
export type GatewayPolicy = z.infer<typeof gatewayPolicySchema>;
|
|
233
|
+
export type PolicyValidation = {
|
|
234
|
+
ok: true;
|
|
235
|
+
policy: GatewayPolicy;
|
|
236
|
+
} | {
|
|
237
|
+
ok: false;
|
|
238
|
+
issues: string[];
|
|
239
|
+
};
|
|
240
|
+
/** Validate an already-parsed policy document; issues read `path: message`. */
|
|
241
|
+
export declare function validatePolicy(value: unknown): PolicyValidation;
|
|
242
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../../src/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;GAMG;AAEH,eAAO,MAAM,aAAa,8DAA+D,CAAC;AAC1F,eAAO,MAAM,cAAc,uDAAwD,CAAC;AAMpF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmBzB,CAAC;AAEL,sFAAsF;AACtF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BvB,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAiC,CAAC;AAElE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,MAAM,MAAM,gBAAgB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAErG,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAO/D"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.gatewayPolicySchema = exports.policyShape = exports.policyRuleSchema = exports.POLICY_ACTIONS = exports.POLICY_LABELS = void 0;
|
|
4
|
+
exports.validatePolicy = validatePolicy;
|
|
5
|
+
const zod_1 = require("zod");
|
|
6
|
+
/**
|
|
7
|
+
* The policy part of a GuardBee MCP gateway config: what may run and how.
|
|
8
|
+
* security-proxy reads it from guardbee-proxy.yaml or from the dashboard; the
|
|
9
|
+
* dashboard validates an edit with the same schema before it saves it, so a
|
|
10
|
+
* policy that saves is a policy the proxy accepts. Deployment settings
|
|
11
|
+
* (upstreams, listen, audit) stay out: they hold commands and secrets.
|
|
12
|
+
*/
|
|
13
|
+
exports.POLICY_LABELS = ["untrusted", "sensitive", "egress", "destructive"];
|
|
14
|
+
exports.POLICY_ACTIONS = ["allow", "deny", "mask", "warn", "approve"];
|
|
15
|
+
const labelSchema = zod_1.z.enum(exports.POLICY_LABELS);
|
|
16
|
+
const actionSchema = zod_1.z.enum(exports.POLICY_ACTIONS);
|
|
17
|
+
const interceptorSchema = zod_1.z.object({ enabled: zod_1.z.boolean(), action: zod_1.z.enum(["block", "warn"]) }).strict();
|
|
18
|
+
exports.policyRuleSchema = zod_1.z
|
|
19
|
+
.object({
|
|
20
|
+
id: zod_1.z.string().optional(),
|
|
21
|
+
match: zod_1.z
|
|
22
|
+
.object({
|
|
23
|
+
tool: zod_1.z.string().optional(),
|
|
24
|
+
upstream: zod_1.z.string().optional(),
|
|
25
|
+
label: labelSchema.optional(),
|
|
26
|
+
session: zod_1.z.enum(["clean", "tainted"]).optional(),
|
|
27
|
+
args: zod_1.z.record(zod_1.z.string(), zod_1.z.union([zod_1.z.string(), zod_1.z.number(), zod_1.z.boolean()])).optional(),
|
|
28
|
+
})
|
|
29
|
+
.strict(),
|
|
30
|
+
action: actionSchema,
|
|
31
|
+
mask: zod_1.z.object({ fields: zod_1.z.array(zod_1.z.string()).min(1) }).strict().optional(),
|
|
32
|
+
})
|
|
33
|
+
.strict()
|
|
34
|
+
.refine((rule) => rule.mask === undefined || rule.action === "mask", {
|
|
35
|
+
message: "mask.fields only applies to action: mask",
|
|
36
|
+
path: ["mask"],
|
|
37
|
+
});
|
|
38
|
+
/** Every field has a default, so `{}` is a valid (allow-all, strict-taint) policy. */
|
|
39
|
+
exports.policyShape = {
|
|
40
|
+
labels: zod_1.z.record(zod_1.z.string(), zod_1.z.array(labelSchema)).default({}),
|
|
41
|
+
rules: zod_1.z.array(exports.policyRuleSchema).default([]),
|
|
42
|
+
taint: zod_1.z.object({ mode: zod_1.z.enum(["strict", "approve", "warn", "off"]).default("strict") }).strict().default({ mode: "strict" }),
|
|
43
|
+
approval: zod_1.z
|
|
44
|
+
.object({
|
|
45
|
+
timeoutSeconds: zod_1.z.number().int().positive().default(120),
|
|
46
|
+
channels: zod_1.z.array(zod_1.z.enum(["elicitation", "dashboard"])).min(1).default(["elicitation"]),
|
|
47
|
+
})
|
|
48
|
+
.strict()
|
|
49
|
+
.default({ timeoutSeconds: 120, channels: ["elicitation"] }),
|
|
50
|
+
defaults: zod_1.z.object({ action: actionSchema.default("allow") }).strict().default({ action: "allow" }),
|
|
51
|
+
interceptors: zod_1.z
|
|
52
|
+
.object({
|
|
53
|
+
promptInjection: interceptorSchema.optional(),
|
|
54
|
+
toolResultInjection: interceptorSchema.optional(),
|
|
55
|
+
definitionDrift: interceptorSchema.extend({ recheck: zod_1.z.enum(["every-call", "on-change"]).optional() }).optional(),
|
|
56
|
+
piiMasking: zod_1.z
|
|
57
|
+
.object({
|
|
58
|
+
enabled: zod_1.z.boolean(),
|
|
59
|
+
patterns: zod_1.z.array(zod_1.z.string()).optional(),
|
|
60
|
+
mode: zod_1.z.enum(["redact", "tokenize"]).optional(),
|
|
61
|
+
detokenizeForEgress: zod_1.z.boolean().optional(),
|
|
62
|
+
})
|
|
63
|
+
.strict()
|
|
64
|
+
.optional(),
|
|
65
|
+
})
|
|
66
|
+
.strict()
|
|
67
|
+
.default({}),
|
|
68
|
+
};
|
|
69
|
+
exports.gatewayPolicySchema = zod_1.z.object(exports.policyShape).strict();
|
|
70
|
+
/** Validate an already-parsed policy document; issues read `path: message`. */
|
|
71
|
+
function validatePolicy(value) {
|
|
72
|
+
const parsed = exports.gatewayPolicySchema.safeParse(value ?? {});
|
|
73
|
+
if (parsed.success)
|
|
74
|
+
return { ok: true, policy: parsed.data };
|
|
75
|
+
return {
|
|
76
|
+
ok: false,
|
|
77
|
+
issues: parsed.error.issues.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../../src/policy.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,4 +7,6 @@ export { INJECTION_RULES, INJECTION_PATTERNS, findInjections, scanForPromptInjec
|
|
|
7
7
|
export type { ScanResult, InjectionRule, InjectionCategory, InjectionFinding } from "./injection.js";
|
|
8
8
|
export { CAPABILITY_RULES, classifyTool, textOf } from "./classify.js";
|
|
9
9
|
export type { Capability, FlowCategory, ToolRecord } from "./classify.js";
|
|
10
|
+
export { POLICY_LABELS, POLICY_ACTIONS, policyRuleSchema, policyShape, gatewayPolicySchema, validatePolicy } from "./policy.js";
|
|
11
|
+
export type { GatewayPolicy, PolicyValidation } from "./policy.js";
|
|
10
12
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,cAAc,GACf,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACrG,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAChI,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -3,4 +3,5 @@ export { PII_PATTERNS, maskPiiInText, maskPiiInValue } from "./pii.js";
|
|
|
3
3
|
export { SECRET_RULES } from "./secrets.js";
|
|
4
4
|
export { INJECTION_RULES, INJECTION_PATTERNS, findInjections, scanForPromptInjection, scanToolResult, } from "./injection.js";
|
|
5
5
|
export { CAPABILITY_RULES, classifyTool, textOf } from "./classify.js";
|
|
6
|
+
export { POLICY_LABELS, POLICY_ACTIONS, policyRuleSchema, policyShape, gatewayPolicySchema, validatePolicy } from "./policy.js";
|
|
6
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEvE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAEvE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,cAAc,GACf,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/policy.d.ts
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* The policy part of a GuardBee MCP gateway config: what may run and how.
|
|
4
|
+
* security-proxy reads it from guardbee-proxy.yaml or from the dashboard; the
|
|
5
|
+
* dashboard validates an edit with the same schema before it saves it, so a
|
|
6
|
+
* policy that saves is a policy the proxy accepts. Deployment settings
|
|
7
|
+
* (upstreams, listen, audit) stay out: they hold commands and secrets.
|
|
8
|
+
*/
|
|
9
|
+
export declare const POLICY_LABELS: readonly ["untrusted", "sensitive", "egress", "destructive"];
|
|
10
|
+
export declare const POLICY_ACTIONS: readonly ["allow", "deny", "mask", "warn", "approve"];
|
|
11
|
+
export declare const policyRuleSchema: z.ZodObject<{
|
|
12
|
+
id: z.ZodOptional<z.ZodString>;
|
|
13
|
+
match: z.ZodObject<{
|
|
14
|
+
tool: z.ZodOptional<z.ZodString>;
|
|
15
|
+
upstream: z.ZodOptional<z.ZodString>;
|
|
16
|
+
label: z.ZodOptional<z.ZodEnum<{
|
|
17
|
+
destructive: "destructive";
|
|
18
|
+
untrusted: "untrusted";
|
|
19
|
+
sensitive: "sensitive";
|
|
20
|
+
egress: "egress";
|
|
21
|
+
}>>;
|
|
22
|
+
session: z.ZodOptional<z.ZodEnum<{
|
|
23
|
+
clean: "clean";
|
|
24
|
+
tainted: "tainted";
|
|
25
|
+
}>>;
|
|
26
|
+
args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
27
|
+
}, z.core.$strict>;
|
|
28
|
+
action: z.ZodEnum<{
|
|
29
|
+
allow: "allow";
|
|
30
|
+
warn: "warn";
|
|
31
|
+
deny: "deny";
|
|
32
|
+
mask: "mask";
|
|
33
|
+
approve: "approve";
|
|
34
|
+
}>;
|
|
35
|
+
mask: z.ZodOptional<z.ZodObject<{
|
|
36
|
+
fields: z.ZodArray<z.ZodString>;
|
|
37
|
+
}, z.core.$strict>>;
|
|
38
|
+
}, z.core.$strict>;
|
|
39
|
+
/** Every field has a default, so `{}` is a valid (allow-all, strict-taint) policy. */
|
|
40
|
+
export declare const policyShape: {
|
|
41
|
+
labels: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodEnum<{
|
|
42
|
+
destructive: "destructive";
|
|
43
|
+
untrusted: "untrusted";
|
|
44
|
+
sensitive: "sensitive";
|
|
45
|
+
egress: "egress";
|
|
46
|
+
}>>>>;
|
|
47
|
+
rules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
48
|
+
id: z.ZodOptional<z.ZodString>;
|
|
49
|
+
match: z.ZodObject<{
|
|
50
|
+
tool: z.ZodOptional<z.ZodString>;
|
|
51
|
+
upstream: z.ZodOptional<z.ZodString>;
|
|
52
|
+
label: z.ZodOptional<z.ZodEnum<{
|
|
53
|
+
destructive: "destructive";
|
|
54
|
+
untrusted: "untrusted";
|
|
55
|
+
sensitive: "sensitive";
|
|
56
|
+
egress: "egress";
|
|
57
|
+
}>>;
|
|
58
|
+
session: z.ZodOptional<z.ZodEnum<{
|
|
59
|
+
clean: "clean";
|
|
60
|
+
tainted: "tainted";
|
|
61
|
+
}>>;
|
|
62
|
+
args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
63
|
+
}, z.core.$strict>;
|
|
64
|
+
action: z.ZodEnum<{
|
|
65
|
+
allow: "allow";
|
|
66
|
+
warn: "warn";
|
|
67
|
+
deny: "deny";
|
|
68
|
+
mask: "mask";
|
|
69
|
+
approve: "approve";
|
|
70
|
+
}>;
|
|
71
|
+
mask: z.ZodOptional<z.ZodObject<{
|
|
72
|
+
fields: z.ZodArray<z.ZodString>;
|
|
73
|
+
}, z.core.$strict>>;
|
|
74
|
+
}, z.core.$strict>>>;
|
|
75
|
+
taint: z.ZodDefault<z.ZodObject<{
|
|
76
|
+
mode: z.ZodDefault<z.ZodEnum<{
|
|
77
|
+
warn: "warn";
|
|
78
|
+
approve: "approve";
|
|
79
|
+
strict: "strict";
|
|
80
|
+
off: "off";
|
|
81
|
+
}>>;
|
|
82
|
+
}, z.core.$strict>>;
|
|
83
|
+
approval: z.ZodDefault<z.ZodObject<{
|
|
84
|
+
timeoutSeconds: z.ZodDefault<z.ZodNumber>;
|
|
85
|
+
channels: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
86
|
+
elicitation: "elicitation";
|
|
87
|
+
dashboard: "dashboard";
|
|
88
|
+
}>>>;
|
|
89
|
+
}, z.core.$strict>>;
|
|
90
|
+
defaults: z.ZodDefault<z.ZodObject<{
|
|
91
|
+
action: z.ZodDefault<z.ZodEnum<{
|
|
92
|
+
allow: "allow";
|
|
93
|
+
warn: "warn";
|
|
94
|
+
deny: "deny";
|
|
95
|
+
mask: "mask";
|
|
96
|
+
approve: "approve";
|
|
97
|
+
}>>;
|
|
98
|
+
}, z.core.$strict>>;
|
|
99
|
+
interceptors: z.ZodDefault<z.ZodObject<{
|
|
100
|
+
promptInjection: z.ZodOptional<z.ZodObject<{
|
|
101
|
+
enabled: z.ZodBoolean;
|
|
102
|
+
action: z.ZodEnum<{
|
|
103
|
+
block: "block";
|
|
104
|
+
warn: "warn";
|
|
105
|
+
}>;
|
|
106
|
+
}, z.core.$strict>>;
|
|
107
|
+
toolResultInjection: z.ZodOptional<z.ZodObject<{
|
|
108
|
+
enabled: z.ZodBoolean;
|
|
109
|
+
action: z.ZodEnum<{
|
|
110
|
+
block: "block";
|
|
111
|
+
warn: "warn";
|
|
112
|
+
}>;
|
|
113
|
+
}, z.core.$strict>>;
|
|
114
|
+
definitionDrift: z.ZodOptional<z.ZodObject<{
|
|
115
|
+
enabled: z.ZodBoolean;
|
|
116
|
+
action: z.ZodEnum<{
|
|
117
|
+
block: "block";
|
|
118
|
+
warn: "warn";
|
|
119
|
+
}>;
|
|
120
|
+
recheck: z.ZodOptional<z.ZodEnum<{
|
|
121
|
+
"every-call": "every-call";
|
|
122
|
+
"on-change": "on-change";
|
|
123
|
+
}>>;
|
|
124
|
+
}, z.core.$strict>>;
|
|
125
|
+
piiMasking: z.ZodOptional<z.ZodObject<{
|
|
126
|
+
enabled: z.ZodBoolean;
|
|
127
|
+
patterns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
128
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
129
|
+
redact: "redact";
|
|
130
|
+
tokenize: "tokenize";
|
|
131
|
+
}>>;
|
|
132
|
+
detokenizeForEgress: z.ZodOptional<z.ZodBoolean>;
|
|
133
|
+
}, z.core.$strict>>;
|
|
134
|
+
}, z.core.$strict>>;
|
|
135
|
+
};
|
|
136
|
+
export declare const gatewayPolicySchema: z.ZodObject<{
|
|
137
|
+
labels: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodEnum<{
|
|
138
|
+
destructive: "destructive";
|
|
139
|
+
untrusted: "untrusted";
|
|
140
|
+
sensitive: "sensitive";
|
|
141
|
+
egress: "egress";
|
|
142
|
+
}>>>>;
|
|
143
|
+
rules: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
144
|
+
id: z.ZodOptional<z.ZodString>;
|
|
145
|
+
match: z.ZodObject<{
|
|
146
|
+
tool: z.ZodOptional<z.ZodString>;
|
|
147
|
+
upstream: z.ZodOptional<z.ZodString>;
|
|
148
|
+
label: z.ZodOptional<z.ZodEnum<{
|
|
149
|
+
destructive: "destructive";
|
|
150
|
+
untrusted: "untrusted";
|
|
151
|
+
sensitive: "sensitive";
|
|
152
|
+
egress: "egress";
|
|
153
|
+
}>>;
|
|
154
|
+
session: z.ZodOptional<z.ZodEnum<{
|
|
155
|
+
clean: "clean";
|
|
156
|
+
tainted: "tainted";
|
|
157
|
+
}>>;
|
|
158
|
+
args: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>>;
|
|
159
|
+
}, z.core.$strict>;
|
|
160
|
+
action: z.ZodEnum<{
|
|
161
|
+
allow: "allow";
|
|
162
|
+
warn: "warn";
|
|
163
|
+
deny: "deny";
|
|
164
|
+
mask: "mask";
|
|
165
|
+
approve: "approve";
|
|
166
|
+
}>;
|
|
167
|
+
mask: z.ZodOptional<z.ZodObject<{
|
|
168
|
+
fields: z.ZodArray<z.ZodString>;
|
|
169
|
+
}, z.core.$strict>>;
|
|
170
|
+
}, z.core.$strict>>>;
|
|
171
|
+
taint: z.ZodDefault<z.ZodObject<{
|
|
172
|
+
mode: z.ZodDefault<z.ZodEnum<{
|
|
173
|
+
warn: "warn";
|
|
174
|
+
approve: "approve";
|
|
175
|
+
strict: "strict";
|
|
176
|
+
off: "off";
|
|
177
|
+
}>>;
|
|
178
|
+
}, z.core.$strict>>;
|
|
179
|
+
approval: z.ZodDefault<z.ZodObject<{
|
|
180
|
+
timeoutSeconds: z.ZodDefault<z.ZodNumber>;
|
|
181
|
+
channels: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
182
|
+
elicitation: "elicitation";
|
|
183
|
+
dashboard: "dashboard";
|
|
184
|
+
}>>>;
|
|
185
|
+
}, z.core.$strict>>;
|
|
186
|
+
defaults: z.ZodDefault<z.ZodObject<{
|
|
187
|
+
action: z.ZodDefault<z.ZodEnum<{
|
|
188
|
+
allow: "allow";
|
|
189
|
+
warn: "warn";
|
|
190
|
+
deny: "deny";
|
|
191
|
+
mask: "mask";
|
|
192
|
+
approve: "approve";
|
|
193
|
+
}>>;
|
|
194
|
+
}, z.core.$strict>>;
|
|
195
|
+
interceptors: z.ZodDefault<z.ZodObject<{
|
|
196
|
+
promptInjection: z.ZodOptional<z.ZodObject<{
|
|
197
|
+
enabled: z.ZodBoolean;
|
|
198
|
+
action: z.ZodEnum<{
|
|
199
|
+
block: "block";
|
|
200
|
+
warn: "warn";
|
|
201
|
+
}>;
|
|
202
|
+
}, z.core.$strict>>;
|
|
203
|
+
toolResultInjection: z.ZodOptional<z.ZodObject<{
|
|
204
|
+
enabled: z.ZodBoolean;
|
|
205
|
+
action: z.ZodEnum<{
|
|
206
|
+
block: "block";
|
|
207
|
+
warn: "warn";
|
|
208
|
+
}>;
|
|
209
|
+
}, z.core.$strict>>;
|
|
210
|
+
definitionDrift: z.ZodOptional<z.ZodObject<{
|
|
211
|
+
enabled: z.ZodBoolean;
|
|
212
|
+
action: z.ZodEnum<{
|
|
213
|
+
block: "block";
|
|
214
|
+
warn: "warn";
|
|
215
|
+
}>;
|
|
216
|
+
recheck: z.ZodOptional<z.ZodEnum<{
|
|
217
|
+
"every-call": "every-call";
|
|
218
|
+
"on-change": "on-change";
|
|
219
|
+
}>>;
|
|
220
|
+
}, z.core.$strict>>;
|
|
221
|
+
piiMasking: z.ZodOptional<z.ZodObject<{
|
|
222
|
+
enabled: z.ZodBoolean;
|
|
223
|
+
patterns: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
224
|
+
mode: z.ZodOptional<z.ZodEnum<{
|
|
225
|
+
redact: "redact";
|
|
226
|
+
tokenize: "tokenize";
|
|
227
|
+
}>>;
|
|
228
|
+
detokenizeForEgress: z.ZodOptional<z.ZodBoolean>;
|
|
229
|
+
}, z.core.$strict>>;
|
|
230
|
+
}, z.core.$strict>>;
|
|
231
|
+
}, z.core.$strict>;
|
|
232
|
+
export type GatewayPolicy = z.infer<typeof gatewayPolicySchema>;
|
|
233
|
+
export type PolicyValidation = {
|
|
234
|
+
ok: true;
|
|
235
|
+
policy: GatewayPolicy;
|
|
236
|
+
} | {
|
|
237
|
+
ok: false;
|
|
238
|
+
issues: string[];
|
|
239
|
+
};
|
|
240
|
+
/** Validate an already-parsed policy document; issues read `path: message`. */
|
|
241
|
+
export declare function validatePolicy(value: unknown): PolicyValidation;
|
|
242
|
+
//# sourceMappingURL=policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;GAMG;AAEH,eAAO,MAAM,aAAa,8DAA+D,CAAC;AAC1F,eAAO,MAAM,cAAc,uDAAwD,CAAC;AAMpF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmBzB,CAAC;AAEL,sFAAsF;AACtF,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BvB,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAAiC,CAAC;AAElE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,MAAM,MAAM,gBAAgB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAErG,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,CAO/D"}
|
package/dist/policy.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* The policy part of a GuardBee MCP gateway config: what may run and how.
|
|
4
|
+
* security-proxy reads it from guardbee-proxy.yaml or from the dashboard; the
|
|
5
|
+
* dashboard validates an edit with the same schema before it saves it, so a
|
|
6
|
+
* policy that saves is a policy the proxy accepts. Deployment settings
|
|
7
|
+
* (upstreams, listen, audit) stay out: they hold commands and secrets.
|
|
8
|
+
*/
|
|
9
|
+
export const POLICY_LABELS = ["untrusted", "sensitive", "egress", "destructive"];
|
|
10
|
+
export const POLICY_ACTIONS = ["allow", "deny", "mask", "warn", "approve"];
|
|
11
|
+
const labelSchema = z.enum(POLICY_LABELS);
|
|
12
|
+
const actionSchema = z.enum(POLICY_ACTIONS);
|
|
13
|
+
const interceptorSchema = z.object({ enabled: z.boolean(), action: z.enum(["block", "warn"]) }).strict();
|
|
14
|
+
export const policyRuleSchema = z
|
|
15
|
+
.object({
|
|
16
|
+
id: z.string().optional(),
|
|
17
|
+
match: z
|
|
18
|
+
.object({
|
|
19
|
+
tool: z.string().optional(),
|
|
20
|
+
upstream: z.string().optional(),
|
|
21
|
+
label: labelSchema.optional(),
|
|
22
|
+
session: z.enum(["clean", "tainted"]).optional(),
|
|
23
|
+
args: z.record(z.string(), z.union([z.string(), z.number(), z.boolean()])).optional(),
|
|
24
|
+
})
|
|
25
|
+
.strict(),
|
|
26
|
+
action: actionSchema,
|
|
27
|
+
mask: z.object({ fields: z.array(z.string()).min(1) }).strict().optional(),
|
|
28
|
+
})
|
|
29
|
+
.strict()
|
|
30
|
+
.refine((rule) => rule.mask === undefined || rule.action === "mask", {
|
|
31
|
+
message: "mask.fields only applies to action: mask",
|
|
32
|
+
path: ["mask"],
|
|
33
|
+
});
|
|
34
|
+
/** Every field has a default, so `{}` is a valid (allow-all, strict-taint) policy. */
|
|
35
|
+
export const policyShape = {
|
|
36
|
+
labels: z.record(z.string(), z.array(labelSchema)).default({}),
|
|
37
|
+
rules: z.array(policyRuleSchema).default([]),
|
|
38
|
+
taint: z.object({ mode: z.enum(["strict", "approve", "warn", "off"]).default("strict") }).strict().default({ mode: "strict" }),
|
|
39
|
+
approval: z
|
|
40
|
+
.object({
|
|
41
|
+
timeoutSeconds: z.number().int().positive().default(120),
|
|
42
|
+
channels: z.array(z.enum(["elicitation", "dashboard"])).min(1).default(["elicitation"]),
|
|
43
|
+
})
|
|
44
|
+
.strict()
|
|
45
|
+
.default({ timeoutSeconds: 120, channels: ["elicitation"] }),
|
|
46
|
+
defaults: z.object({ action: actionSchema.default("allow") }).strict().default({ action: "allow" }),
|
|
47
|
+
interceptors: z
|
|
48
|
+
.object({
|
|
49
|
+
promptInjection: interceptorSchema.optional(),
|
|
50
|
+
toolResultInjection: interceptorSchema.optional(),
|
|
51
|
+
definitionDrift: interceptorSchema.extend({ recheck: z.enum(["every-call", "on-change"]).optional() }).optional(),
|
|
52
|
+
piiMasking: z
|
|
53
|
+
.object({
|
|
54
|
+
enabled: z.boolean(),
|
|
55
|
+
patterns: z.array(z.string()).optional(),
|
|
56
|
+
mode: z.enum(["redact", "tokenize"]).optional(),
|
|
57
|
+
detokenizeForEgress: z.boolean().optional(),
|
|
58
|
+
})
|
|
59
|
+
.strict()
|
|
60
|
+
.optional(),
|
|
61
|
+
})
|
|
62
|
+
.strict()
|
|
63
|
+
.default({}),
|
|
64
|
+
};
|
|
65
|
+
export const gatewayPolicySchema = z.object(policyShape).strict();
|
|
66
|
+
/** Validate an already-parsed policy document; issues read `path: message`. */
|
|
67
|
+
export function validatePolicy(value) {
|
|
68
|
+
const parsed = gatewayPolicySchema.safeParse(value ?? {});
|
|
69
|
+
if (parsed.success)
|
|
70
|
+
return { ok: true, policy: parsed.data };
|
|
71
|
+
return {
|
|
72
|
+
ok: false,
|
|
73
|
+
issues: parsed.error.issues.map((issue) => `${issue.path.join(".") || "(root)"}: ${issue.message}`),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guardbee/guard-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Shared detectors for GuardBee MCP packages — checksum-validated PII masking, prompt injection patterns, and lethal-trifecta tool classification",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
21
|
"dist",
|
|
22
|
-
"README.md"
|
|
22
|
+
"README.md",
|
|
23
|
+
"TR.md",
|
|
24
|
+
"ZH.md"
|
|
23
25
|
],
|
|
24
26
|
"keywords": [
|
|
25
27
|
"mcp",
|
|
@@ -43,6 +45,9 @@
|
|
|
43
45
|
"bugs": {
|
|
44
46
|
"url": "https://github.com/GuardBee/guardbee-mcp/issues"
|
|
45
47
|
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"zod": "^4.5.4"
|
|
50
|
+
},
|
|
46
51
|
"scripts": {
|
|
47
52
|
"build": "tsc && tsc -p tsconfig.cjs.json && node -e \"require('fs').mkdirSync('dist/cjs',{recursive:true});require('fs').writeFileSync('dist/cjs/package.json','{\\\"type\\\":\\\"commonjs\\\"}\\n')\"",
|
|
48
53
|
"dev": "tsc --watch",
|