@orygn/opa-mcp 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +66 -0
- package/dist/constants.d.ts +1 -1
- package/dist/constants.js +1 -1
- package/dist/tools/evaluation/_shared.d.ts.map +1 -1
- package/dist/tools/evaluation/_shared.js +10 -1
- package/dist/tools/evaluation/_shared.js.map +1 -1
- package/dist/tools/helpers/explain-decision.d.ts +9 -7
- package/dist/tools/helpers/explain-decision.d.ts.map +1 -1
- package/dist/tools/helpers/explain-decision.js +15 -9
- package/dist/tools/helpers/explain-decision.js.map +1 -1
- package/dist/tools/server-management/_shared.d.ts +12 -0
- package/dist/tools/server-management/_shared.d.ts.map +1 -1
- package/dist/tools/server-management/_shared.js +20 -0
- package/dist/tools/server-management/_shared.js.map +1 -1
- package/dist/tools/server-management/data.d.ts.map +1 -1
- package/dist/tools/server-management/data.js +13 -10
- package/dist/tools/server-management/data.js.map +1 -1
- package/dist/tools/server-management/decisions.d.ts.map +1 -1
- package/dist/tools/server-management/decisions.js +5 -6
- package/dist/tools/server-management/decisions.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,72 @@ not part of the public surface and may change in minor releases.
|
|
|
17
17
|
|
|
18
18
|
## [Unreleased]
|
|
19
19
|
|
|
20
|
+
## [0.1.7] - 2026-05-21
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- **`rego_explain_decision` always returned empty `rulesFired` and zero
|
|
25
|
+
summary counts.** OPA's `--explain=full` trace uses capitalized field
|
|
26
|
+
names (`Op`, `Message`, `Node`) but the `summarizeTrace` helper was
|
|
27
|
+
reading lowercase `op`, `message`, `node`. No events ever matched, so
|
|
28
|
+
`enterEvents`, `exitEvents`, `failEvents`, `rulesFired`, and
|
|
29
|
+
`rulesEvaluated` were always zero or empty regardless of what the trace
|
|
30
|
+
contained. Fixed by reading the correct capitalized fields. Rule names
|
|
31
|
+
are now extracted from `Node.head.name`, which is where OPA actually
|
|
32
|
+
puts them, rather than from a regex match on a message string that is
|
|
33
|
+
empty in real OPA output. Unit test mocks updated to use the real OPA
|
|
34
|
+
trace format.
|
|
35
|
+
|
|
36
|
+
- **Eval tools returned wrong decisions when `input` was passed as a JSON
|
|
37
|
+
string.** LLMs frequently serialize the input document as a string
|
|
38
|
+
(`'{"user":"alice"}'`) rather than passing it as a native object. The
|
|
39
|
+
eval tools then called `JSON.stringify` on that string, double-encoding
|
|
40
|
+
it. OPA received `'"{\\"user\\":\\"alice\\"}"'` as the input document,
|
|
41
|
+
parsed it as a plain string, `input.user` was undefined, and decisions
|
|
42
|
+
that should have been `true` came back `false`. The shared eval handler
|
|
43
|
+
now detects a string `input`, attempts `JSON.parse`, and passes the
|
|
44
|
+
parsed object forward. Non-JSON strings are forwarded as-is.
|
|
45
|
+
|
|
46
|
+
### Security
|
|
47
|
+
|
|
48
|
+
- **Percent-encoded path traversal in OPA REST data tools.** `opa_get_data`,
|
|
49
|
+
`opa_put_data`, `opa_patch_data`, and `opa_query_decision` constructed
|
|
50
|
+
OPA REST API paths from user-supplied strings. Literal dots (`..`) in the
|
|
51
|
+
input are converted to slashes by the `dataPath` function and are not a
|
|
52
|
+
traversal risk. However, percent-encoded dots (`%2e%2e`) bypass that
|
|
53
|
+
replacement -- `new URL()` normalizes `%2e%2e` as a real `..` segment,
|
|
54
|
+
allowing requests to escape `/v1/data/` and reach arbitrary OPA endpoints.
|
|
55
|
+
Worst-case impact: `GET %2e%2e/v1/config` reaches OPA's config endpoint
|
|
56
|
+
(which can expose bundle credentials and plugin settings); `PUT` to a
|
|
57
|
+
traversed path could overwrite the entire OPA data document.
|
|
58
|
+
|
|
59
|
+
Fixed by normalizing the candidate path through `URL` parsing and
|
|
60
|
+
verifying the resulting pathname still starts with `/v1/data/`. Both
|
|
61
|
+
`%2e` (lowercase) and `%2E` (uppercase) variants are caught. The
|
|
62
|
+
duplicate `dataPath()` functions in `data.ts` and `decisions.ts` are
|
|
63
|
+
replaced by a single `parseOpaDataPath()` in `_shared.ts` that returns
|
|
64
|
+
a structured `ok/error` result.
|
|
65
|
+
|
|
66
|
+
### Tests
|
|
67
|
+
|
|
68
|
+
- `rego_explain_decision` mock traces updated to match real OPA capitalized
|
|
69
|
+
field names (`Op`, `Node`, `Message`). Test description for the
|
|
70
|
+
"no recognizable rule message" case updated to reflect that the actual
|
|
71
|
+
condition is a query-level event where `Node` is an array of terms rather
|
|
72
|
+
than a rule object with `head.name`.
|
|
73
|
+
|
|
74
|
+
- Two new `rego_eval` tests: string `input` that is valid JSON is parsed and
|
|
75
|
+
forwarded as an object; string `input` that is not JSON is forwarded as-is.
|
|
76
|
+
|
|
77
|
+
- `parseOpaDataPath` unit tests covering: dotted form, slash form, `data.`
|
|
78
|
+
prefix stripping, root path, `%2e%2e` rejected, `%2E%2E` rejected, and
|
|
79
|
+
double traversal rejected.
|
|
80
|
+
|
|
81
|
+
- Tool-level traversal rejection tests added for `opa_get_data`,
|
|
82
|
+
`opa_put_data`, `opa_patch_data`, and `opa_query_decision` -- each
|
|
83
|
+
verifies that a `%2e%2e` path returns `INVALID_INPUT` with no fetch
|
|
84
|
+
issued.
|
|
85
|
+
|
|
20
86
|
## [0.1.6] - 2026-05-21
|
|
21
87
|
|
|
22
88
|
### Added
|
package/dist/constants.d.ts
CHANGED
package/dist/constants.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../../src/tools/evaluation/_shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,KAAK,EAAE,MAAM,EAAa,MAAM,sBAAsB,CAAC;AAE9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,oEAAoE;AACpE,eAAO,MAAM,eAAe;;;;;;;;;CAwB3B,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,UAAU,QAAQ;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,UAAU,SAAS;IACjB,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../../src/tools/evaluation/_shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAE9C,OAAO,KAAK,EAAE,MAAM,EAAa,MAAM,sBAAsB,CAAC;AAE9D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,oEAAoE;AACpE,eAAO,MAAM,eAAe;;;;;;;;;CAwB3B,CAAC;AAEF,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,OAAO,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,UAAU,QAAQ;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,UAAU,SAAS;IACjB,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,SAAS,GACf,OAAO,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC,CAmEvC"}
|
|
@@ -57,7 +57,16 @@ export async function runEval(opa, config, args, flags) {
|
|
|
57
57
|
evalInput.paths = validation.resolved;
|
|
58
58
|
}
|
|
59
59
|
if (args.input !== undefined) {
|
|
60
|
-
|
|
60
|
+
let resolvedInput = args.input;
|
|
61
|
+
if (typeof resolvedInput === 'string') {
|
|
62
|
+
try {
|
|
63
|
+
resolvedInput = JSON.parse(resolvedInput);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// Not a JSON string -- pass as-is (intentional string input).
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
evalInput.input = resolvedInput;
|
|
61
70
|
}
|
|
62
71
|
else if (args.inputPath) {
|
|
63
72
|
const inputPathValidation = validatePaths([args.inputPath], config, { mustExist: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_shared.js","sourceRoot":"","sources":["../../../src/tools/evaluation/_shared.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAG9F,oEAAoE;AACpE,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,oDAAoD,CAAC;IACvF,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,6DAA6D,CAAC;IAC1E,KAAK,EAAE,CAAC;SACL,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CAAC,6EAA6E,CAAC;IAC1F,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;IAChE,SAAS,EAAE,CAAC;SACT,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,6DAA6D,CAAC;IAC1E,QAAQ,EAAE,CAAC;SACR,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;SACjB,QAAQ,EAAE;SACV,QAAQ,CAAC,qDAAqD,CAAC;IAClE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,qDAAqD,CAAC;IAC/F,mBAAmB,EAAE,CAAC;SACnB,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CAAC,+DAA+D,CAAC;CAC7E,CAAC;AA6BF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,GAAW,EACX,MAAc,EACd,IAAc,EACd,KAAgB;IAEhB,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QACxC,OAAO,GAAG,CACR,eAAe,EACf,sEAAsE,CACvE,CAAC;IACJ,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QAC/C,OAAO,GAAG,CAAC,eAAe,EAAE,4DAA4D,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,SAAS,GAAc,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;IACnD,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS;QAAE,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAE9D,IAAI,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1E,IAAI,CAAC,UAAU,CAAC,EAAE;YAAE,OAAO,UAAU,CAAC,KAAK,CAAC;QAC5C,SAAS,CAAC,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC;IACxC,CAAC;IAED,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC7B,
|
|
1
|
+
{"version":3,"file":"_shared.js","sourceRoot":"","sources":["../../../src/tools/evaluation/_shared.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,17 +11,19 @@
|
|
|
11
11
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
12
12
|
import type { Config } from '../../config.js';
|
|
13
13
|
interface TraceEvent {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
parent_id?: number;
|
|
18
|
-
message?: string;
|
|
19
|
-
location?: {
|
|
14
|
+
Op?: string;
|
|
15
|
+
Node?: unknown;
|
|
16
|
+
Location?: {
|
|
20
17
|
file?: string;
|
|
21
18
|
row?: number;
|
|
22
19
|
col?: number;
|
|
23
20
|
};
|
|
24
|
-
|
|
21
|
+
QueryID?: number;
|
|
22
|
+
ParentID?: number;
|
|
23
|
+
Message?: string;
|
|
24
|
+
Locals?: unknown;
|
|
25
|
+
LocalMetadata?: unknown;
|
|
26
|
+
Ref?: unknown;
|
|
25
27
|
}
|
|
26
28
|
export interface RegoExplainDecisionOutput {
|
|
27
29
|
result: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explain-decision.d.ts","sourceRoot":"","sources":["../../../src/tools/helpers/explain-decision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAM9C,UAAU,UAAU;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"explain-decision.d.ts","sourceRoot":"","sources":["../../../src/tools/helpers/explain-decision.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAM9C,UAAU,UAAU;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,OAAO,EAAE;QACP,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAwCD,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CA8CnF"}
|
|
@@ -2,6 +2,11 @@ import { OpaCli } from '../../lib/opa-cli.js';
|
|
|
2
2
|
import { err, ok } from '../../lib/errors.js';
|
|
3
3
|
import { withToolEnvelope } from '../../lib/tool-helpers.js';
|
|
4
4
|
import { runEval, SharedEvalInput } from '../evaluation/_shared.js';
|
|
5
|
+
function extractRuleName(node) {
|
|
6
|
+
if (!node || typeof node !== 'object' || Array.isArray(node))
|
|
7
|
+
return undefined;
|
|
8
|
+
return node.head?.name;
|
|
9
|
+
}
|
|
5
10
|
function summarizeTrace(trace) {
|
|
6
11
|
const rulesEvaluated = new Set();
|
|
7
12
|
const rulesFired = new Set();
|
|
@@ -9,19 +14,20 @@ function summarizeTrace(trace) {
|
|
|
9
14
|
let exitEvents = 0;
|
|
10
15
|
let failEvents = 0;
|
|
11
16
|
for (const event of trace ?? []) {
|
|
12
|
-
|
|
17
|
+
const op = event.Op?.toLowerCase();
|
|
18
|
+
if (op === 'enter') {
|
|
13
19
|
enterEvents += 1;
|
|
14
|
-
const
|
|
15
|
-
if (
|
|
16
|
-
rulesEvaluated.add(
|
|
20
|
+
const name = extractRuleName(event.Node);
|
|
21
|
+
if (name)
|
|
22
|
+
rulesEvaluated.add(name);
|
|
17
23
|
}
|
|
18
|
-
else if (
|
|
24
|
+
else if (op === 'exit') {
|
|
19
25
|
exitEvents += 1;
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
22
|
-
rulesFired.add(
|
|
26
|
+
const name = extractRuleName(event.Node);
|
|
27
|
+
if (name)
|
|
28
|
+
rulesFired.add(name);
|
|
23
29
|
}
|
|
24
|
-
else if (
|
|
30
|
+
else if (op === 'fail') {
|
|
25
31
|
failEvents += 1;
|
|
26
32
|
}
|
|
27
33
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explain-decision.js","sourceRoot":"","sources":["../../../src/tools/helpers/explain-decision.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,eAAe,EAAuB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"explain-decision.js","sourceRoot":"","sources":["../../../src/tools/helpers/explain-decision.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import type { ToolEnvelope, ToolErrorCode } from '../../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Convert a user-supplied OPA data path (dotted or slash form) to the
|
|
4
|
+
* `/v1/data/...` REST API path. Rejects `..` segments so a crafted input
|
|
5
|
+
* cannot traverse to unrelated OPA endpoints (e.g. `/v1/config`).
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseOpaDataPath(path: string): {
|
|
8
|
+
ok: true;
|
|
9
|
+
apiPath: string;
|
|
10
|
+
} | {
|
|
11
|
+
ok: false;
|
|
12
|
+
error: ToolEnvelope<never>;
|
|
13
|
+
};
|
|
2
14
|
/**
|
|
3
15
|
* Translate an exception thrown by OpaClient into a structured error
|
|
4
16
|
* envelope. `notFoundCode` lets a tool override the default 404
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../../src/tools/server-management/_shared.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAElE;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,OAAO,EACV,YAAY,GAAE,aAA+B,GAC5C,YAAY,CAAC,KAAK,CAAC,CA0BrB"}
|
|
1
|
+
{"version":3,"file":"_shared.d.ts","sourceRoot":"","sources":["../../../src/tools/server-management/_shared.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAElE;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,GACX;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,CAAA;CAAE,CAe3E;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,CAAC,EAAE,OAAO,EACV,YAAY,GAAE,aAA+B,GAC5C,YAAY,CAAC,KAAK,CAAC,CA0BrB"}
|
|
@@ -5,6 +5,26 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { err } from '../../lib/errors.js';
|
|
7
7
|
import { OpaAuthError, OpaHttpError, OpaUnreachableError } from '../../lib/opa-client.js';
|
|
8
|
+
/**
|
|
9
|
+
* Convert a user-supplied OPA data path (dotted or slash form) to the
|
|
10
|
+
* `/v1/data/...` REST API path. Rejects `..` segments so a crafted input
|
|
11
|
+
* cannot traverse to unrelated OPA endpoints (e.g. `/v1/config`).
|
|
12
|
+
*/
|
|
13
|
+
export function parseOpaDataPath(path) {
|
|
14
|
+
const stripped = path.replace(/^data\./, '').replace(/^\/+/, '');
|
|
15
|
+
const apiPath = `/v1/data/${stripped.replace(/\./g, '/')}`;
|
|
16
|
+
// Normalize through URL parsing to catch both literal `..` segments and
|
|
17
|
+
// percent-encoded variants (%2e%2e). If the resolved pathname no longer
|
|
18
|
+
// starts with /v1/data/, a traversal escaped the intended prefix.
|
|
19
|
+
const normalized = new URL(`http://h${apiPath}`).pathname;
|
|
20
|
+
if (!normalized.startsWith('/v1/data/')) {
|
|
21
|
+
return {
|
|
22
|
+
ok: false,
|
|
23
|
+
error: err('INVALID_INPUT', `Path traversal not allowed: ${path}`),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return { ok: true, apiPath };
|
|
27
|
+
}
|
|
8
28
|
/**
|
|
9
29
|
* Translate an exception thrown by OpaClient into a structured error
|
|
10
30
|
* envelope. `notFoundCode` lets a tool override the default 404
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_shared.js","sourceRoot":"","sources":["../../../src/tools/server-management/_shared.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAG1F;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,CAAU,EACV,eAA8B,eAAe;IAE7C,IAAI,CAAC,YAAY,mBAAmB,EAAE,CAAC;QACrC,OAAO,GAAG,CAAC,iBAAiB,EAAE,6BAA6B,CAAC,CAAC,GAAG,EAAE,EAAE;YAClE,IAAI,EAAE,+EAA+E;YACrF,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE;SACxB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,YAAY,YAAY,EAAE,CAAC;QAC9B,OAAO,GAAG,CAAC,iBAAiB,EAAE,iDAAiD,EAAE;YAC/E,IAAI,EAAE,0FAA0F;SACjG,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,YAAY,YAAY,EAAE,CAAC;QAC9B,IAAI,CAAC,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACrB,OAAO,GAAG,CAAC,YAAY,EAAE,6BAA6B,EAAE;gBACtD,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;aAC5C,CAAC,CAAC;QACL,CAAC;QACD,OAAO,GAAG,CAAC,eAAe,EAAE,qBAAqB,CAAC,CAAC,MAAM,GAAG,EAAE;YAC5D,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;SAC5C,CAAC,CAAC;IACL,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;IACjE,OAAO,GAAG,CAAC,eAAe,EAAE,OAAO,EAAE;QACnC,OAAO,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;KAChE,CAAC,CAAC;AACL,CAAC"}
|
|
1
|
+
{"version":3,"file":"_shared.js","sourceRoot":"","sources":["../../../src/tools/server-management/_shared.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAG1F;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAY;IAEZ,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACjE,MAAM,OAAO,GAAG,YAAY,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC;IAE3D,wEAAwE;IACxE,wEAAwE;IACxE,kEAAkE;IAClE,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,WAAW,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC;IAC1D,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QACxC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,GAAG,CAAC,eAAe,EAAE,+BAA+B,IAAI,EAAE,CAAC;SACnE,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC/B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,CAAU,EACV,eAA8B,eAAe;IAE7C,IAAI,CAAC,YAAY,mBAAmB,EAAE,CAAC;QACrC,OAAO,GAAG,CAAC,iBAAiB,EAAE,6BAA6B,CAAC,CAAC,GAAG,EAAE,EAAE;YAClE,IAAI,EAAE,+EAA+E;YACrF,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE;SACxB,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,YAAY,YAAY,EAAE,CAAC;QAC9B,OAAO,GAAG,CAAC,iBAAiB,EAAE,iDAAiD,EAAE;YAC/E,IAAI,EAAE,0FAA0F;SACjG,CAAC,CAAC;IACL,CAAC;IACD,IAAI,CAAC,YAAY,YAAY,EAAE,CAAC;QAC9B,IAAI,CAAC,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACrB,OAAO,GAAG,CAAC,YAAY,EAAE,6BAA6B,EAAE;gBACtD,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;aAC5C,CAAC,CAAC;QACL,CAAC;QACD,OAAO,GAAG,CAAC,eAAe,EAAE,qBAAqB,CAAC,CAAC,MAAM,GAAG,EAAE;YAC5D,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;SAC5C,CAAC,CAAC;IACL,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;IACjE,OAAO,GAAG,CAAC,eAAe,EAAE,OAAO,EAAE;QACnC,OAAO,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;KAChE,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../src/tools/server-management/data.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"data.d.ts","sourceRoot":"","sources":["../../../src/tools/server-management/data.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAM9C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAgGzE"}
|
|
@@ -5,13 +5,7 @@ import { z } from 'zod';
|
|
|
5
5
|
import { OpaClient } from '../../lib/opa-client.js';
|
|
6
6
|
import { ok } from '../../lib/errors.js';
|
|
7
7
|
import { withToolEnvelope } from '../../lib/tool-helpers.js';
|
|
8
|
-
import { mapOpaClientError } from './_shared.js';
|
|
9
|
-
function dataPath(path) {
|
|
10
|
-
// Strip leading "data." or "/" -- server always prepends /v1/data/.
|
|
11
|
-
const stripped = path.replace(/^data\./, '').replace(/^\/+/, '');
|
|
12
|
-
// Convert dotted form to slash form: "users.alice" -> "users/alice".
|
|
13
|
-
return `/v1/data/${stripped.replace(/\./g, '/')}`;
|
|
14
|
-
}
|
|
8
|
+
import { mapOpaClientError, parseOpaDataPath } from './_shared.js';
|
|
15
9
|
export function registerDataTools(server, config) {
|
|
16
10
|
const opa = new OpaClient(config);
|
|
17
11
|
server.registerTool('opa_get_data', {
|
|
@@ -22,10 +16,13 @@ export function registerDataTools(server, config) {
|
|
|
22
16
|
},
|
|
23
17
|
}, async ({ path }) => {
|
|
24
18
|
return withToolEnvelope(config, async () => {
|
|
19
|
+
const parsed = parseOpaDataPath(path);
|
|
20
|
+
if (!parsed.ok)
|
|
21
|
+
return parsed.error;
|
|
25
22
|
try {
|
|
26
23
|
const data = await opa.request({
|
|
27
24
|
method: 'GET',
|
|
28
|
-
path:
|
|
25
|
+
path: parsed.apiPath,
|
|
29
26
|
});
|
|
30
27
|
return ok({ result: data.result });
|
|
31
28
|
}
|
|
@@ -43,10 +40,13 @@ export function registerDataTools(server, config) {
|
|
|
43
40
|
},
|
|
44
41
|
}, async ({ path, value }) => {
|
|
45
42
|
return withToolEnvelope(config, async () => {
|
|
43
|
+
const parsed = parseOpaDataPath(path);
|
|
44
|
+
if (!parsed.ok)
|
|
45
|
+
return parsed.error;
|
|
46
46
|
try {
|
|
47
47
|
await opa.request({
|
|
48
48
|
method: 'PUT',
|
|
49
|
-
path:
|
|
49
|
+
path: parsed.apiPath,
|
|
50
50
|
body: value,
|
|
51
51
|
});
|
|
52
52
|
return ok({ path, written: true });
|
|
@@ -72,10 +72,13 @@ export function registerDataTools(server, config) {
|
|
|
72
72
|
},
|
|
73
73
|
}, async ({ path, operations }) => {
|
|
74
74
|
return withToolEnvelope(config, async () => {
|
|
75
|
+
const parsed = parseOpaDataPath(path);
|
|
76
|
+
if (!parsed.ok)
|
|
77
|
+
return parsed.error;
|
|
75
78
|
try {
|
|
76
79
|
await opa.request({
|
|
77
80
|
method: 'PATCH',
|
|
78
|
-
path:
|
|
81
|
+
path: parsed.apiPath,
|
|
79
82
|
body: operations,
|
|
80
83
|
headers: { 'Content-Type': 'application/json-patch+json' },
|
|
81
84
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../../src/tools/server-management/data.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../../src/tools/server-management/data.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decisions.d.ts","sourceRoot":"","sources":["../../../src/tools/server-management/decisions.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"decisions.d.ts","sourceRoot":"","sources":["../../../src/tools/server-management/decisions.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAM9C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAwF7E"}
|
|
@@ -6,11 +6,7 @@ import { z } from 'zod';
|
|
|
6
6
|
import { OpaClient } from '../../lib/opa-client.js';
|
|
7
7
|
import { ok } from '../../lib/errors.js';
|
|
8
8
|
import { withToolEnvelope } from '../../lib/tool-helpers.js';
|
|
9
|
-
import { mapOpaClientError } from './_shared.js';
|
|
10
|
-
function dataPath(path) {
|
|
11
|
-
const stripped = path.replace(/^data\./, '').replace(/^\/+/, '');
|
|
12
|
-
return `/v1/data/${stripped.replace(/\./g, '/')}`;
|
|
13
|
-
}
|
|
9
|
+
import { mapOpaClientError, parseOpaDataPath } from './_shared.js';
|
|
14
10
|
export function registerDecisionTools(server, config) {
|
|
15
11
|
const opa = new OpaClient(config);
|
|
16
12
|
server.registerTool('opa_query_decision', {
|
|
@@ -30,6 +26,9 @@ export function registerDecisionTools(server, config) {
|
|
|
30
26
|
},
|
|
31
27
|
}, async ({ path, input, explain, metrics }) => {
|
|
32
28
|
return withToolEnvelope(config, async () => {
|
|
29
|
+
const parsed = parseOpaDataPath(path);
|
|
30
|
+
if (!parsed.ok)
|
|
31
|
+
return parsed.error;
|
|
33
32
|
try {
|
|
34
33
|
const query = {};
|
|
35
34
|
if (explain)
|
|
@@ -38,7 +37,7 @@ export function registerDecisionTools(server, config) {
|
|
|
38
37
|
query['metrics'] = true;
|
|
39
38
|
const data = await opa.request({
|
|
40
39
|
method: 'POST',
|
|
41
|
-
path:
|
|
40
|
+
path: parsed.apiPath,
|
|
42
41
|
body: input !== undefined ? { input } : {},
|
|
43
42
|
query,
|
|
44
43
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decisions.js","sourceRoot":"","sources":["../../../src/tools/server-management/decisions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"decisions.js","sourceRoot":"","sources":["../../../src/tools/server-management/decisions.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orygn/opa-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"mcpName": "io.github.OrygnsCode/opa-mcp",
|
|
5
5
|
"description": "Model Context Protocol server for Open Policy Agent (OPA). Author, validate, debug, and explain Rego policies through any MCP-compatible client.",
|
|
6
6
|
"type": "module",
|