@orygn/opa-mcp 0.4.0 → 0.6.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/CHANGELOG.md +583 -4
- package/README.md +144 -98
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +9 -3
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +14 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +91 -19
- package/dist/config.js.map +1 -1
- package/dist/constants.d.ts +1 -6
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +17 -3
- package/dist/constants.js.map +1 -1
- package/dist/lib/bundle-signatures.d.ts +23 -0
- package/dist/lib/bundle-signatures.d.ts.map +1 -0
- package/dist/lib/bundle-signatures.js +152 -0
- package/dist/lib/bundle-signatures.js.map +1 -0
- package/dist/lib/child-env.d.ts +9 -2
- package/dist/lib/child-env.d.ts.map +1 -1
- package/dist/lib/child-env.js +38 -6
- package/dist/lib/child-env.js.map +1 -1
- package/dist/lib/conftest-cli.d.ts +25 -10
- package/dist/lib/conftest-cli.d.ts.map +1 -1
- package/dist/lib/conftest-cli.js +233 -50
- package/dist/lib/conftest-cli.js.map +1 -1
- package/dist/lib/errors.d.ts +4 -5
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +15 -3
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/inline-paths.d.ts +37 -0
- package/dist/lib/inline-paths.d.ts.map +1 -0
- package/dist/lib/inline-paths.js +162 -0
- package/dist/lib/inline-paths.js.map +1 -0
- package/dist/lib/install-id.d.ts.map +1 -1
- package/dist/lib/install-id.js +18 -3
- package/dist/lib/install-id.js.map +1 -1
- package/dist/lib/json-stream.d.ts +26 -0
- package/dist/lib/json-stream.d.ts.map +1 -0
- package/dist/lib/json-stream.js +69 -0
- package/dist/lib/json-stream.js.map +1 -0
- package/dist/lib/opa-cli.d.ts +74 -16
- package/dist/lib/opa-cli.d.ts.map +1 -1
- package/dist/lib/opa-cli.js +107 -30
- package/dist/lib/opa-cli.js.map +1 -1
- package/dist/lib/opa-client.d.ts +27 -1
- package/dist/lib/opa-client.d.ts.map +1 -1
- package/dist/lib/opa-client.js +98 -14
- package/dist/lib/opa-client.js.map +1 -1
- package/dist/lib/opa-paths.d.ts +34 -0
- package/dist/lib/opa-paths.d.ts.map +1 -0
- package/dist/lib/opa-paths.js +101 -0
- package/dist/lib/opa-paths.js.map +1 -0
- package/dist/lib/output.d.ts.map +1 -1
- package/dist/lib/output.js +83 -10
- package/dist/lib/output.js.map +1 -1
- package/dist/lib/regal-cli.d.ts +16 -1
- package/dist/lib/regal-cli.d.ts.map +1 -1
- package/dist/lib/regal-cli.js +40 -6
- package/dist/lib/regal-cli.js.map +1 -1
- package/dist/lib/rego-ast-walker.d.ts +0 -6
- package/dist/lib/rego-ast-walker.d.ts.map +1 -1
- package/dist/lib/rego-ast-walker.js +181 -55
- package/dist/lib/rego-ast-walker.js.map +1 -1
- package/dist/lib/rego-counterexample.d.ts +15 -2
- package/dist/lib/rego-counterexample.d.ts.map +1 -1
- package/dist/lib/rego-counterexample.js +63 -15
- package/dist/lib/rego-counterexample.js.map +1 -1
- package/dist/lib/rego-input-path.d.ts +20 -0
- package/dist/lib/rego-input-path.d.ts.map +1 -0
- package/dist/lib/rego-input-path.js +70 -0
- package/dist/lib/rego-input-path.js.map +1 -0
- package/dist/lib/rego-ir.d.ts +34 -3
- package/dist/lib/rego-ir.d.ts.map +1 -1
- package/dist/lib/rego-smt-encoder.d.ts +88 -5
- package/dist/lib/rego-smt-encoder.d.ts.map +1 -1
- package/dist/lib/rego-smt-encoder.js +270 -31
- package/dist/lib/rego-smt-encoder.js.map +1 -1
- package/dist/lib/rego-type-inferencer.d.ts +27 -2
- package/dist/lib/rego-type-inferencer.d.ts.map +1 -1
- package/dist/lib/rego-type-inferencer.js +71 -3
- package/dist/lib/rego-type-inferencer.js.map +1 -1
- package/dist/lib/rego-verify-engine.d.ts.map +1 -1
- package/dist/lib/rego-verify-engine.js +203 -90
- package/dist/lib/rego-verify-engine.js.map +1 -1
- package/dist/lib/rego-z3.d.ts +66 -0
- package/dist/lib/rego-z3.d.ts.map +1 -1
- package/dist/lib/rego-z3.js +312 -5
- package/dist/lib/rego-z3.js.map +1 -1
- package/dist/lib/security.d.ts +8 -0
- package/dist/lib/security.d.ts.map +1 -1
- package/dist/lib/security.js +130 -54
- package/dist/lib/security.js.map +1 -1
- package/dist/lib/subprocess.d.ts +13 -0
- package/dist/lib/subprocess.d.ts.map +1 -1
- package/dist/lib/subprocess.js +153 -18
- package/dist/lib/subprocess.js.map +1 -1
- package/dist/lib/tool-helpers.d.ts +12 -25
- package/dist/lib/tool-helpers.d.ts.map +1 -1
- package/dist/lib/tool-helpers.js +66 -40
- package/dist/lib/tool-helpers.js.map +1 -1
- package/dist/prompts/index.js +2 -2
- package/dist/resources/index.js +1 -1
- package/dist/resources/index.js.map +1 -1
- package/dist/resources/patterns.d.ts +1 -1
- package/dist/resources/patterns.d.ts.map +1 -1
- package/dist/resources/patterns.js +42 -15
- package/dist/resources/patterns.js.map +1 -1
- package/dist/server.d.ts +2 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +50 -7
- package/dist/server.js.map +1 -1
- package/dist/tools/authoring/capabilities.d.ts +4 -0
- package/dist/tools/authoring/capabilities.d.ts.map +1 -1
- package/dist/tools/authoring/capabilities.js +41 -4
- package/dist/tools/authoring/capabilities.js.map +1 -1
- package/dist/tools/authoring/check-schema.d.ts +6 -0
- package/dist/tools/authoring/check-schema.d.ts.map +1 -1
- package/dist/tools/authoring/check-schema.js +56 -3
- package/dist/tools/authoring/check-schema.js.map +1 -1
- package/dist/tools/authoring/format.d.ts.map +1 -1
- package/dist/tools/authoring/format.js +2 -2
- package/dist/tools/authoring/format.js.map +1 -1
- package/dist/tools/authoring/lint.d.ts.map +1 -1
- package/dist/tools/authoring/lint.js +8 -6
- package/dist/tools/authoring/lint.js.map +1 -1
- package/dist/tools/authoring/migrate-v1.d.ts.map +1 -1
- package/dist/tools/authoring/migrate-v1.js +20 -4
- package/dist/tools/authoring/migrate-v1.js.map +1 -1
- package/dist/tools/authoring/parse.d.ts.map +1 -1
- package/dist/tools/authoring/parse.js +3 -3
- package/dist/tools/authoring/parse.js.map +1 -1
- package/dist/tools/bundles/build.d.ts.map +1 -1
- package/dist/tools/bundles/build.js +12 -4
- package/dist/tools/bundles/build.js.map +1 -1
- package/dist/tools/bundles/sign.d.ts +9 -2
- package/dist/tools/bundles/sign.d.ts.map +1 -1
- package/dist/tools/bundles/sign.js +125 -19
- package/dist/tools/bundles/sign.js.map +1 -1
- package/dist/tools/bundles/verify.d.ts +1 -1
- package/dist/tools/bundles/verify.d.ts.map +1 -1
- package/dist/tools/bundles/verify.js +58 -19
- package/dist/tools/bundles/verify.js.map +1 -1
- package/dist/tools/conftest/index.d.ts +5 -0
- package/dist/tools/conftest/index.d.ts.map +1 -1
- package/dist/tools/conftest/index.js.map +1 -1
- package/dist/tools/conftest/pull.d.ts.map +1 -1
- package/dist/tools/conftest/pull.js +24 -10
- package/dist/tools/conftest/pull.js.map +1 -1
- package/dist/tools/conftest/push.d.ts.map +1 -1
- package/dist/tools/conftest/push.js +17 -7
- package/dist/tools/conftest/push.js.map +1 -1
- package/dist/tools/conftest/test.d.ts +10 -6
- package/dist/tools/conftest/test.d.ts.map +1 -1
- package/dist/tools/conftest/test.js +61 -39
- package/dist/tools/conftest/test.js.map +1 -1
- package/dist/tools/conftest/verify.d.ts +10 -6
- package/dist/tools/conftest/verify.d.ts.map +1 -1
- package/dist/tools/conftest/verify.js +40 -32
- package/dist/tools/conftest/verify.js.map +1 -1
- package/dist/tools/evaluation/_shared.js +9 -12
- package/dist/tools/evaluation/_shared.js.map +1 -1
- package/dist/tools/evaluation/bench.d.ts +29 -2
- package/dist/tools/evaluation/bench.d.ts.map +1 -1
- package/dist/tools/evaluation/bench.js +53 -9
- package/dist/tools/evaluation/bench.js.map +1 -1
- package/dist/tools/evaluation/compile.js +4 -4
- package/dist/tools/evaluation/compile.js.map +1 -1
- package/dist/tools/evaluation/eval.d.ts.map +1 -1
- package/dist/tools/evaluation/eval.js +12 -16
- package/dist/tools/evaluation/eval.js.map +1 -1
- package/dist/tools/evaluation/exec.d.ts +16 -0
- package/dist/tools/evaluation/exec.d.ts.map +1 -1
- package/dist/tools/evaluation/exec.js +38 -6
- package/dist/tools/evaluation/exec.js.map +1 -1
- package/dist/tools/evaluation/test-multiroot.d.ts +6 -0
- package/dist/tools/evaluation/test-multiroot.d.ts.map +1 -1
- package/dist/tools/evaluation/test-multiroot.js +35 -8
- package/dist/tools/evaluation/test-multiroot.js.map +1 -1
- package/dist/tools/evaluation/test.d.ts +45 -0
- package/dist/tools/evaluation/test.d.ts.map +1 -1
- package/dist/tools/evaluation/test.js +153 -32
- package/dist/tools/evaluation/test.js.map +1 -1
- package/dist/tools/helpers/coverage-gaps.d.ts +11 -3
- package/dist/tools/helpers/coverage-gaps.d.ts.map +1 -1
- package/dist/tools/helpers/coverage-gaps.js +7 -7
- package/dist/tools/helpers/coverage-gaps.js.map +1 -1
- package/dist/tools/helpers/describe-policy.d.ts.map +1 -1
- package/dist/tools/helpers/describe-policy.js +2 -2
- package/dist/tools/helpers/describe-policy.js.map +1 -1
- package/dist/tools/helpers/explain-decision.d.ts.map +1 -1
- package/dist/tools/helpers/explain-decision.js +3 -4
- package/dist/tools/helpers/explain-decision.js.map +1 -1
- package/dist/tools/helpers/explain-undefined.d.ts +9 -3
- package/dist/tools/helpers/explain-undefined.d.ts.map +1 -1
- package/dist/tools/helpers/explain-undefined.js +214 -73
- package/dist/tools/helpers/explain-undefined.js.map +1 -1
- package/dist/tools/helpers/fix.d.ts +11 -5
- package/dist/tools/helpers/fix.d.ts.map +1 -1
- package/dist/tools/helpers/fix.js +88 -45
- package/dist/tools/helpers/fix.js.map +1 -1
- package/dist/tools/helpers/generate-test-skeleton.d.ts.map +1 -1
- package/dist/tools/helpers/generate-test-skeleton.js +105 -21
- package/dist/tools/helpers/generate-test-skeleton.js.map +1 -1
- package/dist/tools/helpers/playground-share.d.ts +4 -2
- package/dist/tools/helpers/playground-share.d.ts.map +1 -1
- package/dist/tools/helpers/playground-share.js +13 -3
- package/dist/tools/helpers/playground-share.js.map +1 -1
- package/dist/tools/helpers/policy-diff.d.ts.map +1 -1
- package/dist/tools/helpers/policy-diff.js +3 -4
- package/dist/tools/helpers/policy-diff.js.map +1 -1
- package/dist/tools/helpers/security-audit.d.ts.map +1 -1
- package/dist/tools/helpers/security-audit.js +19 -19
- package/dist/tools/helpers/security-audit.js.map +1 -1
- package/dist/tools/helpers/verify.d.ts.map +1 -1
- package/dist/tools/helpers/verify.js +5 -1
- package/dist/tools/helpers/verify.js.map +1 -1
- package/dist/tools/meta/index.d.ts +1 -1
- package/dist/tools/server-management/_shared.d.ts +15 -4
- package/dist/tools/server-management/_shared.d.ts.map +1 -1
- package/dist/tools/server-management/_shared.js +86 -13
- 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 +88 -23
- 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 +16 -3
- package/dist/tools/server-management/decisions.js.map +1 -1
- package/dist/tools/server-management/policies.d.ts.map +1 -1
- package/dist/tools/server-management/policies.js +44 -7
- package/dist/tools/server-management/policies.js.map +1 -1
- package/dist/tools/server-management/status.d.ts.map +1 -1
- package/dist/tools/server-management/status.js +80 -13
- package/dist/tools/server-management/status.js.map +1 -1
- package/dist/types.d.ts +10 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -1
package/dist/config.js
CHANGED
|
@@ -6,10 +6,41 @@
|
|
|
6
6
|
* Cursor, VS Code) pass config via the `env` object in their JSON.
|
|
7
7
|
*/
|
|
8
8
|
import { tmpdir } from 'node:os';
|
|
9
|
-
import { join } from 'node:path';
|
|
9
|
+
import { isAbsolute, join, posix, win32 } from 'node:path';
|
|
10
10
|
import { z } from 'zod';
|
|
11
11
|
import { resolveOpaBinary } from './lib/resolve-binary.js';
|
|
12
12
|
import { DEFAULT_MAX_OUTPUT_BYTES } from './lib/subprocess.js';
|
|
13
|
+
/**
|
|
14
|
+
* Whether a `*_BINARY` value is acceptable on `platform`: a bare command
|
|
15
|
+
* name, looked up on PATH by the spawn, or an absolute path. A relative path
|
|
16
|
+
* would resolve against wherever the client happened to launch the server.
|
|
17
|
+
* On Windows a path with a leading separator and no drive counts as absolute
|
|
18
|
+
* to `isAbsolute`, yet it resolves against the current drive, the same hazard
|
|
19
|
+
* as the drive-relative `C:regal.exe`; a UNC path starts with two separators
|
|
20
|
+
* and is fine.
|
|
21
|
+
*/
|
|
22
|
+
export function isBinarySpec(value, platform = process.platform) {
|
|
23
|
+
if (value === '.' || value === '..')
|
|
24
|
+
return false;
|
|
25
|
+
if (!/[\\/]/.test(value) && !/^[A-Za-z]:/.test(value))
|
|
26
|
+
return true;
|
|
27
|
+
if (platform === 'win32' && /^[\\/](?![\\/])/.test(value))
|
|
28
|
+
return false;
|
|
29
|
+
return (platform === 'win32' ? win32 : posix).isAbsolute(value);
|
|
30
|
+
}
|
|
31
|
+
const binarySchema = (name) => z
|
|
32
|
+
.string()
|
|
33
|
+
.refine((v) => isBinarySpec(v), {
|
|
34
|
+
message: 'must be a bare command name found on PATH, or an absolute path',
|
|
35
|
+
})
|
|
36
|
+
.default(name);
|
|
37
|
+
/**
|
|
38
|
+
* Node clamps a timer of 2^31 ms or more to 1 ms, with only a process warning.
|
|
39
|
+
* A large value reads as "effectively no timeout" and produced the opposite:
|
|
40
|
+
* every subprocess and every HTTP call timed out immediately.
|
|
41
|
+
*/
|
|
42
|
+
const MAX_TIMER_MS = 2_147_483_647;
|
|
43
|
+
const TIMER_TOO_LARGE = 'Timeout must be below 2147483647 ms (about 24 days). Node clamps anything larger to 1 ms, which times out every call immediately.';
|
|
13
44
|
const ConfigSchema = z.object({
|
|
14
45
|
/** Base URL of a running OPA server (used by `opa_*` runtime tools). */
|
|
15
46
|
opaUrl: z
|
|
@@ -22,22 +53,42 @@ const ConfigSchema = z.object({
|
|
|
22
53
|
/** Optional bearer token for OPA running with `--authentication=token`. */
|
|
23
54
|
opaToken: z.string().optional(),
|
|
24
55
|
/** Path to the `opa` binary. Defaults to `opa` on PATH. */
|
|
25
|
-
opaBinary:
|
|
56
|
+
opaBinary: binarySchema('opa'),
|
|
26
57
|
/** Path to the `regal` binary. Defaults to `regal` on PATH. */
|
|
27
|
-
regalBinary:
|
|
58
|
+
regalBinary: binarySchema('regal'),
|
|
28
59
|
/** Path to the `conftest` binary. Defaults to `conftest` on PATH. */
|
|
29
|
-
conftestBinary:
|
|
60
|
+
conftestBinary: binarySchema('conftest'),
|
|
30
61
|
/** Hard timeout in ms for any spawned subprocess (opa, regal). */
|
|
31
|
-
subprocessTimeoutMs: z.coerce
|
|
62
|
+
subprocessTimeoutMs: z.coerce
|
|
63
|
+
.number()
|
|
64
|
+
.int()
|
|
65
|
+
.positive()
|
|
66
|
+
.max(MAX_TIMER_MS, TIMER_TOO_LARGE)
|
|
67
|
+
.default(30_000),
|
|
32
68
|
/** HTTP request timeout for OPA REST API calls. */
|
|
33
|
-
httpTimeoutMs: z.coerce
|
|
69
|
+
httpTimeoutMs: z.coerce
|
|
70
|
+
.number()
|
|
71
|
+
.int()
|
|
72
|
+
.positive()
|
|
73
|
+
.max(MAX_TIMER_MS, TIMER_TOO_LARGE)
|
|
74
|
+
.default(15_000),
|
|
34
75
|
/**
|
|
35
76
|
* Allow-listed root directories for file path inputs. Tools that accept
|
|
36
77
|
* filesystem paths reject anything outside these roots. Empty by
|
|
37
78
|
* default -- file-based tools refuse to read from disk until the
|
|
38
79
|
* operator explicitly opts in via `OPA_MCP_ALLOWED_PATHS`.
|
|
39
80
|
*/
|
|
40
|
-
allowedPaths: z
|
|
81
|
+
allowedPaths: z
|
|
82
|
+
.array(
|
|
83
|
+
// A relative root is resolved against the server's working directory,
|
|
84
|
+
// which for a stdio server is wherever the client happened to launch it.
|
|
85
|
+
// The same configuration would then permit different directories on
|
|
86
|
+
// different machines, so it is refused rather than guessed at, which is
|
|
87
|
+
// what the documentation has always said happens.
|
|
88
|
+
z.string().refine(isAbsolute, {
|
|
89
|
+
message: 'must be an absolute path',
|
|
90
|
+
}))
|
|
91
|
+
.default([]),
|
|
41
92
|
/** Path to the log file. Defaults to OS tmpdir + orygn-opa-mcp.log. */
|
|
42
93
|
logFile: z.string().default(join(tmpdir(), 'orygn-opa-mcp.log')),
|
|
43
94
|
/** Log level for the file logger. */
|
|
@@ -47,7 +98,13 @@ const ConfigSchema = z.object({
|
|
|
47
98
|
* Larger payloads are truncated with `truncated: true` and a hint to
|
|
48
99
|
* write to a file path the agent specifies.
|
|
49
100
|
*/
|
|
50
|
-
maxResponseBytes: z.coerce
|
|
101
|
+
maxResponseBytes: z.coerce
|
|
102
|
+
.number()
|
|
103
|
+
.int()
|
|
104
|
+
// The smallest complete envelope is under 300 bytes; a cap that cannot
|
|
105
|
+
// hold one is refused rather than exceeded.
|
|
106
|
+
.min(512, { message: 'must be at least 512' })
|
|
107
|
+
.default(100_000),
|
|
51
108
|
/**
|
|
52
109
|
* Maximum bytes captured from a subprocess's stdout and stderr, each counted
|
|
53
110
|
* separately. On overflow the stream is clamped and the child is killed.
|
|
@@ -87,21 +144,36 @@ const ENV_VAR_NAMES = {
|
|
|
87
144
|
maxResponseBytes: 'OPA_MCP_MAX_RESPONSE_BYTES',
|
|
88
145
|
maxSubprocessBytes: 'OPA_MCP_MAX_SUBPROCESS_BYTES',
|
|
89
146
|
};
|
|
147
|
+
/**
|
|
148
|
+
* Read an environment variable, treating an empty or blank value as unset.
|
|
149
|
+
*
|
|
150
|
+
* A shell that expands an unset variable leaves an empty string behind, and
|
|
151
|
+
* `OPA_BINARY=""` was taken as a real path: it is not the literal default
|
|
152
|
+
* `opa`, so binary resolution skipped the bundled build and every tool call
|
|
153
|
+
* tried to spawn nothing. Blank means "not configured" for every variable here.
|
|
154
|
+
*/
|
|
155
|
+
function env(name) {
|
|
156
|
+
const raw = process.env[name];
|
|
157
|
+
if (raw === undefined)
|
|
158
|
+
return undefined;
|
|
159
|
+
const trimmed = raw.trim();
|
|
160
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
161
|
+
}
|
|
90
162
|
export function loadConfig() {
|
|
91
163
|
const allowedPaths = parseAllowedPaths(process.env['OPA_MCP_ALLOWED_PATHS']);
|
|
92
164
|
const parsed = ConfigSchema.safeParse({
|
|
93
|
-
opaUrl:
|
|
94
|
-
opaToken:
|
|
95
|
-
opaBinary:
|
|
96
|
-
regalBinary:
|
|
97
|
-
conftestBinary:
|
|
98
|
-
subprocessTimeoutMs:
|
|
99
|
-
httpTimeoutMs:
|
|
165
|
+
opaUrl: env('OPA_URL'),
|
|
166
|
+
opaToken: env('OPA_TOKEN'),
|
|
167
|
+
opaBinary: env('OPA_BINARY'),
|
|
168
|
+
regalBinary: env('REGAL_BINARY'),
|
|
169
|
+
conftestBinary: env('CONFTEST_BINARY'),
|
|
170
|
+
subprocessTimeoutMs: env('OPA_MCP_TIMEOUT_MS'),
|
|
171
|
+
httpTimeoutMs: env('OPA_MCP_HTTP_TIMEOUT_MS'),
|
|
100
172
|
allowedPaths,
|
|
101
|
-
logFile:
|
|
102
|
-
logLevel:
|
|
103
|
-
maxResponseBytes:
|
|
104
|
-
maxSubprocessBytes:
|
|
173
|
+
logFile: env('OPA_MCP_LOG_FILE'),
|
|
174
|
+
logLevel: env('OPA_MCP_LOG_LEVEL'),
|
|
175
|
+
maxResponseBytes: env('OPA_MCP_MAX_RESPONSE_BYTES'),
|
|
176
|
+
maxSubprocessBytes: env('OPA_MCP_MAX_SUBPROCESS_BYTES'),
|
|
105
177
|
});
|
|
106
178
|
if (!parsed.success) {
|
|
107
179
|
console.error('opa-mcp: invalid configuration');
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAE3D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAE/D;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,WAA4B,OAAO,CAAC,QAAQ;IACtF,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAClD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACnE,IAAI,QAAQ,KAAK,OAAO,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACxE,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,EAAE,CACpC,CAAC;KACE,MAAM,EAAE;KACR,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE;IAC9B,OAAO,EAAE,gEAAgE;CAC1E,CAAC;KACD,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB;;;;GAIG;AACH,MAAM,YAAY,GAAG,aAAa,CAAC;AACnC,MAAM,eAAe,GACnB,mIAAmI,CAAC;AAEtI,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,wEAAwE;IACxE,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,GAAG,EAAE;SACL,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;QAClE,OAAO,EAAE,4CAA4C;KACtD,CAAC;SACD,OAAO,CAAC,uBAAuB,CAAC;IAEnC,2EAA2E;IAC3E,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAE/B,2DAA2D;IAC3D,SAAS,EAAE,YAAY,CAAC,KAAK,CAAC;IAE9B,+DAA+D;IAC/D,WAAW,EAAE,YAAY,CAAC,OAAO,CAAC;IAElC,qEAAqE;IACrE,cAAc,EAAE,YAAY,CAAC,UAAU,CAAC;IAExC,kEAAkE;IAClE,mBAAmB,EAAE,CAAC,CAAC,MAAM;SAC1B,MAAM,EAAE;SACR,GAAG,EAAE;SACL,QAAQ,EAAE;SACV,GAAG,CAAC,YAAY,EAAE,eAAe,CAAC;SAClC,OAAO,CAAC,MAAM,CAAC;IAElB,mDAAmD;IACnD,aAAa,EAAE,CAAC,CAAC,MAAM;SACpB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,QAAQ,EAAE;SACV,GAAG,CAAC,YAAY,EAAE,eAAe,CAAC;SAClC,OAAO,CAAC,MAAM,CAAC;IAElB;;;;;OAKG;IACH,YAAY,EAAE,CAAC;SACZ,KAAK;IACJ,sEAAsE;IACtE,yEAAyE;IACzE,oEAAoE;IACpE,wEAAwE;IACxE,kDAAkD;IAClD,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,EAAE;QAC5B,OAAO,EAAE,0BAA0B;KACpC,CAAC,CACH;SACA,OAAO,CAAC,EAAE,CAAC;IAEd,uEAAuE;IACvE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,mBAAmB,CAAC,CAAC;IAEhE,qCAAqC;IACrC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;IAEpE;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,CAAC,MAAM;SACvB,MAAM,EAAE;SACR,GAAG,EAAE;QACN,uEAAuE;QACvE,4CAA4C;SAC3C,GAAG,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC;SAC7C,OAAO,CAAC,OAAO,CAAC;IAEnB;;;;;;;;OAQG;IACH,kBAAkB,EAAE,CAAC,CAAC,MAAM;SACzB,MAAM,EAAE;SACR,GAAG,EAAE;SACL,QAAQ,EAAE;SACV,GAAG,CACF,wBAAwB,GAAG,CAAC,EAC5B,yFAAyF,CAC1F;SACA,OAAO,CAAC,wBAAwB,CAAC;CACrC,CAAC,CAAC;AAIH,SAAS,iBAAiB,CAAC,GAAuB;IAChD,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC3B,MAAM,KAAK,GAAG,GAAG;SACd,KAAK,CAAC,MAAM,CAAC;SACb,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC/B,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9C,CAAC;AAED,MAAM,aAAa,GAA2B;IAC5C,MAAM,EAAE,SAAS;IACjB,QAAQ,EAAE,WAAW;IACrB,SAAS,EAAE,YAAY;IACvB,WAAW,EAAE,cAAc;IAC3B,cAAc,EAAE,iBAAiB;IACjC,mBAAmB,EAAE,oBAAoB;IACzC,aAAa,EAAE,yBAAyB;IACxC,YAAY,EAAE,uBAAuB;IACrC,OAAO,EAAE,kBAAkB;IAC3B,QAAQ,EAAE,mBAAmB;IAC7B,gBAAgB,EAAE,4BAA4B;IAC9C,kBAAkB,EAAE,8BAA8B;CACnD,CAAC;AAEF;;;;;;;GAOG;AACH,SAAS,GAAG,CAAC,IAAY;IACvB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACxC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAE7E,MAAM,MAAM,GAAG,YAAY,CAAC,SAAS,CAAC;QACpC,MAAM,EAAE,GAAG,CAAC,SAAS,CAAC;QACtB,QAAQ,EAAE,GAAG,CAAC,WAAW,CAAC;QAC1B,SAAS,EAAE,GAAG,CAAC,YAAY,CAAC;QAC5B,WAAW,EAAE,GAAG,CAAC,cAAc,CAAC;QAChC,cAAc,EAAE,GAAG,CAAC,iBAAiB,CAAC;QACtC,mBAAmB,EAAE,GAAG,CAAC,oBAAoB,CAAC;QAC9C,aAAa,EAAE,GAAG,CAAC,yBAAyB,CAAC;QAC7C,YAAY;QACZ,OAAO,EAAE,GAAG,CAAC,kBAAkB,CAAC;QAChC,QAAQ,EAAE,GAAG,CAAC,mBAAmB,CAAC;QAClC,gBAAgB,EAAE,GAAG,CAAC,4BAA4B,CAAC;QACnD,kBAAkB,EAAE,GAAG,CAAC,8BAA8B,CAAC;KACxD,CAAC,CAAC;IAEH,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;QAChD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YACxC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,MAAM,GACV,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,IAAI,aAAa;gBACjD,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC;gBACtB,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,SAAS,CAAC,CAAC;YACjC,OAAO,CAAC,KAAK,CAAC,KAAK,MAAM,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC;IAC3B,oEAAoE;IACpE,uEAAuE;IACvE,kEAAkE;IAClE,MAAM,CAAC,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IACtD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Server identity constants shared between the entry point and the
|
|
3
|
-
* mcp_server_info tool. Defined here to avoid a circular import
|
|
4
|
-
* (server.ts -> tools -> meta -> server.ts).
|
|
5
|
-
*/
|
|
6
1
|
export declare const SERVER_NAME = "orygn-opa-mcp";
|
|
7
|
-
export declare const SERVER_VERSION
|
|
2
|
+
export declare const SERVER_VERSION: string;
|
|
8
3
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,WAAW,kBAAkB,CAAC;AAgB3C,eAAO,MAAM,cAAc,EAAE,MAA6B,CAAC"}
|
package/dist/constants.js
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Server identity
|
|
3
|
-
*
|
|
2
|
+
* Server identity shared between the entry point and the mcp_server_info
|
|
3
|
+
* tool. Defined here to avoid a circular import
|
|
4
4
|
* (server.ts -> tools -> meta -> server.ts).
|
|
5
5
|
*/
|
|
6
|
+
import { createRequire } from 'node:module';
|
|
6
7
|
export const SERVER_NAME = 'orygn-opa-mcp';
|
|
7
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Read from package.json, which the release flow bumps, so the server cannot
|
|
10
|
+
* report one version while carrying another. Every packaging places
|
|
11
|
+
* package.json beside dist: the npm tarball, the Docker image and the .mcpb
|
|
12
|
+
* bundle.
|
|
13
|
+
*/
|
|
14
|
+
function versionFromPackage() {
|
|
15
|
+
const pkg = createRequire(import.meta.url)('../package.json');
|
|
16
|
+
const version = typeof pkg === 'object' && pkg !== null ? pkg.version : undefined;
|
|
17
|
+
if (typeof version !== 'string')
|
|
18
|
+
throw new Error('package.json beside dist has no version');
|
|
19
|
+
return version;
|
|
20
|
+
}
|
|
21
|
+
export const SERVER_VERSION = versionFromPackage();
|
|
8
22
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAC;AAE3C;;;;;GAKG;AACH,SAAS,kBAAkB;IACzB,MAAM,GAAG,GAAY,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,iBAAiB,CAAC,CAAC;IACvE,MAAM,OAAO,GACX,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,CAAC,CAAC,CAAE,GAA6B,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/F,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC5F,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,MAAM,cAAc,GAAW,kBAAkB,EAAE,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface SignaturesSummary {
|
|
2
|
+
/** JWT `alg` header, e.g. `RS256`. */
|
|
3
|
+
algorithm: string;
|
|
4
|
+
/** Number of files the signature covers. */
|
|
5
|
+
filesSigned: number;
|
|
6
|
+
keyId?: string;
|
|
7
|
+
scope?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Read the summary of a `.signatures.json` file. Throws on any shape OPA
|
|
11
|
+
* would not have written, so a caller never reports a file it cannot read.
|
|
12
|
+
*/
|
|
13
|
+
export declare function readSignaturesSummary(path: string): Promise<SignaturesSummary>;
|
|
14
|
+
export declare function isKeyOrAlgorithmError(output: string): boolean;
|
|
15
|
+
export type VerificationFailureReason = 'key_invalid' | 'not_a_bundle' | 'signature_invalid' | 'scope_mismatch' | 'file_modified' | 'file_missing' | 'file_added' | 'unsigned' | 'signatures_malformed' | 'file_unparseable' | 'bundle_load_error' | 'unknown';
|
|
16
|
+
export interface VerificationFailure {
|
|
17
|
+
reason: VerificationFailureReason;
|
|
18
|
+
summary: string;
|
|
19
|
+
hint?: string;
|
|
20
|
+
}
|
|
21
|
+
/** Classify OPA's stdout+stderr from a failed verification. */
|
|
22
|
+
export declare function classifyVerificationFailure(output: string): VerificationFailure;
|
|
23
|
+
//# sourceMappingURL=bundle-signatures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle-signatures.d.ts","sourceRoot":"","sources":["../../src/lib/bundle-signatures.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAQD;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA0BpF;AASD,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE7D;AAED,MAAM,MAAM,yBAAyB,GACjC,aAAa,GACb,cAAc,GACd,mBAAmB,GACnB,gBAAgB,GAChB,eAAe,GACf,cAAc,GACd,YAAY,GACZ,UAAU,GACV,sBAAsB,GACtB,kBAAkB,GAClB,mBAAmB,GACnB,SAAS,CAAC;AAEd,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,yBAAyB,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAuFD,+DAA+D;AAC/D,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,CAW/E"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for OPA bundle signatures.
|
|
3
|
+
*
|
|
4
|
+
* `opa sign` writes `{ "signatures": ["<JWT>"] }` with exactly one JWT. Its
|
|
5
|
+
* header carries the algorithm and its payload lists every signed file as
|
|
6
|
+
* `{ name, hash, algorithm }`, plus whatever extra claims (`keyid`, `scope`)
|
|
7
|
+
* were supplied through a claims file. Reading that summary back is how the
|
|
8
|
+
* sign tool describes what it just produced, and it is deliberately not a
|
|
9
|
+
* verification: nothing here checks the signature, only OPA does that.
|
|
10
|
+
*/
|
|
11
|
+
import { readFile } from 'node:fs/promises';
|
|
12
|
+
function base64UrlDecode(segment) {
|
|
13
|
+
const b64 = segment.replace(/-/g, '+').replace(/_/g, '/');
|
|
14
|
+
const padded = b64 + '='.repeat((4 - (b64.length % 4)) % 4);
|
|
15
|
+
return Buffer.from(padded, 'base64').toString('utf8');
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Read the summary of a `.signatures.json` file. Throws on any shape OPA
|
|
19
|
+
* would not have written, so a caller never reports a file it cannot read.
|
|
20
|
+
*/
|
|
21
|
+
export async function readSignaturesSummary(path) {
|
|
22
|
+
const raw = await readFile(path, 'utf8');
|
|
23
|
+
const parsed = JSON.parse(raw);
|
|
24
|
+
const sigs = parsed.signatures;
|
|
25
|
+
if (!Array.isArray(sigs) || sigs.length !== 1 || typeof sigs[0] !== 'string') {
|
|
26
|
+
throw new Error('expected exactly one JWT in "signatures"');
|
|
27
|
+
}
|
|
28
|
+
const parts = sigs[0].split('.');
|
|
29
|
+
if (parts.length !== 3)
|
|
30
|
+
throw new Error('signature is not a JWT');
|
|
31
|
+
const header = JSON.parse(base64UrlDecode(parts[0]));
|
|
32
|
+
const payload = JSON.parse(base64UrlDecode(parts[1]));
|
|
33
|
+
if (typeof header.alg !== 'string')
|
|
34
|
+
throw new Error('JWT header has no alg');
|
|
35
|
+
if (!Array.isArray(payload.files))
|
|
36
|
+
throw new Error('JWT payload has no files array');
|
|
37
|
+
const summary = {
|
|
38
|
+
algorithm: header.alg,
|
|
39
|
+
filesSigned: payload.files.length,
|
|
40
|
+
};
|
|
41
|
+
if (typeof payload.keyid === 'string')
|
|
42
|
+
summary.keyId = payload.keyid;
|
|
43
|
+
if (typeof payload.scope === 'string')
|
|
44
|
+
summary.scope = payload.scope;
|
|
45
|
+
return summary;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* `opa sign` and `opa build` both print these when the key file is not a PEM
|
|
49
|
+
* key or the algorithm is not one OPA knows. They are the caller's input, not
|
|
50
|
+
* the bundle, so the tools report them as INVALID_INPUT.
|
|
51
|
+
*/
|
|
52
|
+
const KEY_OR_ALGORITHM_ERROR = /failed to parse PEM block|unknown signature algorithm/i;
|
|
53
|
+
export function isKeyOrAlgorithmError(output) {
|
|
54
|
+
return KEY_OR_ALGORITHM_ERROR.test(output);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Each pattern is text OPA 1.19 prints, on stdout, for that failure.
|
|
58
|
+
*
|
|
59
|
+
* The order follows what OPA does while loading a signed bundle: it reads the
|
|
60
|
+
* key and algorithm, checks the JWT against the key, compares the scope claim,
|
|
61
|
+
* then reads every file. A Rego file is hashed as written, so its digest is
|
|
62
|
+
* compared before it is parsed. A data file or `.manifest` is hashed by parsed
|
|
63
|
+
* value, so one that no longer parses fails BEFORE its digest is compared;
|
|
64
|
+
* that is why an unparseable data file is `file_unparseable` (possibly
|
|
65
|
+
* modified) and not a load error of signed content. Rego parse errors come
|
|
66
|
+
* last, after the signature and every digest passed. Where messages overlap,
|
|
67
|
+
* the more specific rule is listed first.
|
|
68
|
+
*/
|
|
69
|
+
const FAILURE_RULES = [
|
|
70
|
+
{
|
|
71
|
+
reason: 'key_invalid',
|
|
72
|
+
pattern: KEY_OR_ALGORITHM_ERROR,
|
|
73
|
+
summary: 'the verification key or algorithm could not be used',
|
|
74
|
+
hint: 'verificationKey must be a PEM public key, and signingAlg one OPA supports. For an HMAC-signed bundle pass signingAlg (HS256, HS384 or HS512) so the file is read as the secret rather than as PEM.',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
reason: 'not_a_bundle',
|
|
78
|
+
pattern: /archive read failed|bundle read failed/i,
|
|
79
|
+
summary: 'the path is not a bundle directory or a .tar.gz archive',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
reason: 'signature_invalid',
|
|
83
|
+
pattern: /failed to verify JWT signature|verification error/i,
|
|
84
|
+
summary: 'the signature does not verify with this key',
|
|
85
|
+
hint: 'Check the key and pass signingAlg matching how the bundle was signed. OPA verifies against the single key given regardless of the signature keyid claim, so this is the key or the algorithm, not the key id.',
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
reason: 'scope_mismatch',
|
|
89
|
+
pattern: /scope mismatch/i,
|
|
90
|
+
summary: 'the scope given does not match the scope claim in the signature',
|
|
91
|
+
hint: 'Pass scope with exactly the value the bundle was signed with, and no scope if it was signed without one.',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
reason: 'file_modified',
|
|
95
|
+
pattern: /digest mismatch/i,
|
|
96
|
+
summary: 'a signed file was modified after signing',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
reason: 'file_missing',
|
|
100
|
+
pattern: /specified in bundle signatures but not found/i,
|
|
101
|
+
summary: 'a file the signature covers is missing from the bundle',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
reason: 'file_added',
|
|
105
|
+
pattern: /not included in bundle signature/i,
|
|
106
|
+
summary: 'the bundle contains a file the signature does not cover',
|
|
107
|
+
hint: 'A directory signature names files under the directory name given to opa, so this is also what a directory reports when verified under a different name than it was signed with. Moving it elsewhere under the same name is fine; renaming it is not. For an artifact that survives renaming, build a signed archive with opa_bundle_build.',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
reason: 'unsigned',
|
|
111
|
+
pattern: /missing \.signatures\.json/i,
|
|
112
|
+
summary: 'the bundle has no .signatures.json',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
reason: 'signatures_malformed',
|
|
116
|
+
pattern: /signatures decode|missing JWT|base64 decode JWT|split compact JWT|unexpected end of JSON input|\.signatures\.json/i,
|
|
117
|
+
summary: '.signatures.json is not a valid signature file',
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
reason: 'file_unparseable',
|
|
121
|
+
pattern: /yaml:/i,
|
|
122
|
+
summary: 'a data file or .manifest could not be parsed, so its digest was never compared',
|
|
123
|
+
hint: 'OPA hashes data files by parsed value and stops at the first one it cannot parse, before comparing digests. The file may have been modified after signing. Restore it, or fix it and sign again.',
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
reason: 'bundle_load_error',
|
|
127
|
+
pattern: /rego_\w+_error|errors? occurred|manifest roots/i,
|
|
128
|
+
summary: 'the bundle could not be loaded, so verification did not complete',
|
|
129
|
+
hint: 'OPA parses Rego after the signature and every digest passed, so the policy is signed and unmodified but does not load under Rego v1. A policy written for Rego v0 verifies with v0Compatible.',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
// A JWT payload that decodes but is not JSON: OPA prints only the JSON
|
|
133
|
+
// error, with none of the prefixes matched above.
|
|
134
|
+
reason: 'signatures_malformed',
|
|
135
|
+
pattern: /invalid character/i,
|
|
136
|
+
summary: '.signatures.json is not a valid signature file',
|
|
137
|
+
},
|
|
138
|
+
];
|
|
139
|
+
/** Classify OPA's stdout+stderr from a failed verification. */
|
|
140
|
+
export function classifyVerificationFailure(output) {
|
|
141
|
+
for (const rule of FAILURE_RULES) {
|
|
142
|
+
if (rule.pattern.test(output)) {
|
|
143
|
+
const { pattern: _pattern, ...failure } = rule;
|
|
144
|
+
return failure;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
reason: 'unknown',
|
|
149
|
+
summary: 'OPA rejected the bundle for a reason this tool does not recognise',
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=bundle-signatures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle-signatures.js","sourceRoot":"","sources":["../../src/lib/bundle-signatures.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/child-env.d.ts
CHANGED
|
@@ -10,7 +10,13 @@
|
|
|
10
10
|
* `OPA_TOKEN`, the `GITHUB_TOKEN` this project's own README asks users to put in
|
|
11
11
|
* their client config, and whatever else the operator's shell happens to hold.
|
|
12
12
|
*
|
|
13
|
-
* So the child gets an explicit allow-list instead.
|
|
13
|
+
* So the child gets an explicit allow-list instead. It holds no cloud or
|
|
14
|
+
* repository token, which is what motivated the list, but it is not free of
|
|
15
|
+
* credentials: a proxy URL can embed one, and `HTTP_PROXY` and its siblings are
|
|
16
|
+
* on the list because dropping them breaks every user behind a corporate proxy.
|
|
17
|
+
* An operator who would rather lose proxy support than expose those credentials
|
|
18
|
+
* to evaluated policy can name them in `OPA_MCP_BLOCK_ENV`.
|
|
19
|
+
*
|
|
14
20
|
* Measured against the bundled OPA 1.19.0, `version`, `eval`, `check`, `test`
|
|
15
21
|
* and `build` all succeed with a completely empty environment, so the entries
|
|
16
22
|
* below exist for correctness in real-world setups (proxies, custom CA bundles,
|
|
@@ -25,7 +31,8 @@
|
|
|
25
31
|
*
|
|
26
32
|
* @param extra Variables the calling command needs. Readable by evaluated
|
|
27
33
|
* policy like everything else here, so pass secrets only when the
|
|
28
|
-
* command actually requires them.
|
|
34
|
+
* command actually requires them. `OPA_MCP_BLOCK_ENV` removes a
|
|
35
|
+
* name even when it appears here.
|
|
29
36
|
* @param source Environment to read from. Injectable for testing.
|
|
30
37
|
*/
|
|
31
38
|
export declare function buildChildEnv(extra?: Record<string, string>, source?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"child-env.d.ts","sourceRoot":"","sources":["../../src/lib/child-env.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"child-env.d.ts","sourceRoot":"","sources":["../../src/lib/child-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AA0HH;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,MAAM,GAAE,MAAM,CAAC,UAAwB,GACtC,MAAM,CAAC,UAAU,CAyBnB;AAED,yDAAyD;AACzD,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAAY,CAAC"}
|
package/dist/lib/child-env.js
CHANGED
|
@@ -10,7 +10,13 @@
|
|
|
10
10
|
* `OPA_TOKEN`, the `GITHUB_TOKEN` this project's own README asks users to put in
|
|
11
11
|
* their client config, and whatever else the operator's shell happens to hold.
|
|
12
12
|
*
|
|
13
|
-
* So the child gets an explicit allow-list instead.
|
|
13
|
+
* So the child gets an explicit allow-list instead. It holds no cloud or
|
|
14
|
+
* repository token, which is what motivated the list, but it is not free of
|
|
15
|
+
* credentials: a proxy URL can embed one, and `HTTP_PROXY` and its siblings are
|
|
16
|
+
* on the list because dropping them breaks every user behind a corporate proxy.
|
|
17
|
+
* An operator who would rather lose proxy support than expose those credentials
|
|
18
|
+
* to evaluated policy can name them in `OPA_MCP_BLOCK_ENV`.
|
|
19
|
+
*
|
|
14
20
|
* Measured against the bundled OPA 1.19.0, `version`, `eval`, `check`, `test`
|
|
15
21
|
* and `build` all succeed with a completely empty environment, so the entries
|
|
16
22
|
* below exist for correctness in real-world setups (proxies, custom CA bundles,
|
|
@@ -77,9 +83,8 @@ const TOOL_CONFIG = [
|
|
|
77
83
|
'REGISTRY_AUTH_FILE',
|
|
78
84
|
];
|
|
79
85
|
const ALLOWED = [...COMMON, ...POSIX, ...WINDOWS, ...NETWORK, ...TOOL_CONFIG];
|
|
80
|
-
/**
|
|
81
|
-
function
|
|
82
|
-
const raw = source['OPA_MCP_PASSTHROUGH_ENV'];
|
|
86
|
+
/** Split a comma or semicolon separated list of variable names. */
|
|
87
|
+
function nameList(raw) {
|
|
83
88
|
if (!raw)
|
|
84
89
|
return [];
|
|
85
90
|
return raw
|
|
@@ -87,6 +92,21 @@ function passthroughNames(source) {
|
|
|
87
92
|
.map((s) => s.trim())
|
|
88
93
|
.filter((s) => s.length > 0);
|
|
89
94
|
}
|
|
95
|
+
/** Names an operator opted into via OPA_MCP_PASSTHROUGH_ENV. */
|
|
96
|
+
function passthroughNames(source) {
|
|
97
|
+
return nameList(source['OPA_MCP_PASSTHROUGH_ENV']);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Names an operator withheld via OPA_MCP_BLOCK_ENV.
|
|
101
|
+
*
|
|
102
|
+
* Applied last, so it overrides the allow-list, the passthrough list and the
|
|
103
|
+
* caller's own `extra`. The point is to be able to say no to something this
|
|
104
|
+
* module would otherwise hand down, and a rule that could be overridden by the
|
|
105
|
+
* thing it is meant to restrain would not be worth having.
|
|
106
|
+
*/
|
|
107
|
+
function blockedNames(source) {
|
|
108
|
+
return nameList(source['OPA_MCP_BLOCK_ENV']);
|
|
109
|
+
}
|
|
90
110
|
/**
|
|
91
111
|
* Windows treats variable names case-insensitively, and the casing in
|
|
92
112
|
* `process.env` follows whatever the parent used, so an exact-key lookup would
|
|
@@ -123,7 +143,8 @@ const WINDOWS_IDENTITY_TO_BLANK = ['USERNAME', 'USERDOMAIN', 'LOGONSERVER'];
|
|
|
123
143
|
*
|
|
124
144
|
* @param extra Variables the calling command needs. Readable by evaluated
|
|
125
145
|
* policy like everything else here, so pass secrets only when the
|
|
126
|
-
* command actually requires them.
|
|
146
|
+
* command actually requires them. `OPA_MCP_BLOCK_ENV` removes a
|
|
147
|
+
* name even when it appears here.
|
|
127
148
|
* @param source Environment to read from. Injectable for testing.
|
|
128
149
|
*/
|
|
129
150
|
export function buildChildEnv(extra, source = process.env) {
|
|
@@ -137,7 +158,18 @@ export function buildChildEnv(extra, source = process.env) {
|
|
|
137
158
|
if (value !== undefined)
|
|
138
159
|
env[name] = value;
|
|
139
160
|
}
|
|
140
|
-
|
|
161
|
+
const result = extra ? { ...env, ...extra } : env;
|
|
162
|
+
for (const name of blockedNames(source)) {
|
|
163
|
+
delete result[name];
|
|
164
|
+
if (process.platform === 'win32') {
|
|
165
|
+
const wanted = name.toLowerCase();
|
|
166
|
+
for (const key of Object.keys(result)) {
|
|
167
|
+
if (key.toLowerCase() === wanted)
|
|
168
|
+
delete result[key];
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return result;
|
|
141
173
|
}
|
|
142
174
|
/** Exposed for tests and for documenting the surface. */
|
|
143
175
|
export const ALLOWED_CHILD_ENV_VARS = ALLOWED;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"child-env.js","sourceRoot":"","sources":["../../src/lib/child-env.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"child-env.js","sourceRoot":"","sources":["../../src/lib/child-env.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,8 +20,20 @@ export interface ConftestFileResult {
|
|
|
20
20
|
failures: ConftestMessage[];
|
|
21
21
|
warnings: ConftestMessage[];
|
|
22
22
|
skipped: ConftestMessage[];
|
|
23
|
-
exceptions:
|
|
23
|
+
exceptions: ConftestMessage[];
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Parse `--output=json` from `conftest test` or `conftest verify` into
|
|
27
|
+
* results whose array fields are always present.
|
|
28
|
+
*
|
|
29
|
+
* conftest marks every array `omitempty`, so a file that passes cleanly
|
|
30
|
+
* arrives as `{filename, namespace, successes}` with no `failures` key at
|
|
31
|
+
* all, and `verify` with no test rules prints the literal `null`. Reading
|
|
32
|
+
* `.failures.length` off that threw on every clean run. Returns null when
|
|
33
|
+
* stdout is not a JSON array (or `null`), which is what a command-level
|
|
34
|
+
* failure looks like.
|
|
35
|
+
*/
|
|
36
|
+
export declare function parseConftestResults(stdout: string): ConftestFileResult[] | null;
|
|
25
37
|
/** Input for `conftest test`. */
|
|
26
38
|
export interface ConftestTestInput {
|
|
27
39
|
/** Absolute paths to configuration files to evaluate. */
|
|
@@ -30,10 +42,10 @@ export interface ConftestTestInput {
|
|
|
30
42
|
inlineConfig?: string;
|
|
31
43
|
/**
|
|
32
44
|
* Parser used for inline config content. Determines the temp file
|
|
33
|
-
*
|
|
45
|
+
* name (yaml -> config.yaml, dockerfile -> Dockerfile, and so on).
|
|
34
46
|
* Defaults to `yaml` when not specified.
|
|
35
47
|
*/
|
|
36
|
-
inlineConfigParser?:
|
|
48
|
+
inlineConfigParser?: ConftestParser;
|
|
37
49
|
/**
|
|
38
50
|
* Absolute path to a directory or file containing Rego policies.
|
|
39
51
|
* Defaults to `./policy` (conftest's convention). Mutually exclusive
|
|
@@ -60,7 +72,7 @@ export interface ConftestTestInput {
|
|
|
60
72
|
* flag, overriding extension-based detection. Use it to parse files whose
|
|
61
73
|
* extension does not match their format (e.g. a `.tfstate` file as `json`).
|
|
62
74
|
*/
|
|
63
|
-
parser?:
|
|
75
|
+
parser?: ConftestParser;
|
|
64
76
|
}
|
|
65
77
|
/** Input for `conftest verify`. */
|
|
66
78
|
export interface ConftestVerifyInput {
|
|
@@ -86,12 +98,15 @@ export interface ConftestPushInput {
|
|
|
86
98
|
policy?: string;
|
|
87
99
|
}
|
|
88
100
|
/**
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
101
|
+
* The parsers conftest 0.69 accepts for `--parser`, and the only values a
|
|
102
|
+
* caller may pass. The name also chooses the temp file name for inline
|
|
103
|
+
* config, so it must never be free text: a value carrying path separators
|
|
104
|
+
* used to be joined straight into the temp path, and `../` sequences in it
|
|
105
|
+
* walked out of the temp directory to wherever the caller pointed.
|
|
94
106
|
*/
|
|
107
|
+
export declare const CONFTEST_PARSERS: readonly ["cue", "dockerfile", "dotenv", "edn", "hcl1", "hcl2", "hocon", "ignore", "ini", "json", "jsonnet", "nginx", "properties", "spdx", "textproto", "toml", "vcl", "xml", "yaml"];
|
|
108
|
+
export type ConftestParser = (typeof CONFTEST_PARSERS)[number];
|
|
109
|
+
export declare function isConftestParser(value: string): value is ConftestParser;
|
|
95
110
|
export declare class ConftestCli {
|
|
96
111
|
private readonly config;
|
|
97
112
|
constructor(config: Config);
|
|
@@ -129,7 +144,7 @@ export declare class ConftestCli {
|
|
|
129
144
|
* Run `conftest` with the given argv. Tools should prefer the typed
|
|
130
145
|
* methods above; this is the escape hatch for unusual invocations.
|
|
131
146
|
*/
|
|
132
|
-
run(args: string[], signal?: AbortSignal): Promise<SpawnResult>;
|
|
147
|
+
run(args: string[], signal?: AbortSignal, cwd?: string): Promise<SpawnResult>;
|
|
133
148
|
/**
|
|
134
149
|
* Create temp assets for inline inputs, run `fn`, then clean up.
|
|
135
150
|
* Returns whatever `fn` returns.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conftest-cli.d.ts","sourceRoot":"","sources":["../../src/lib/conftest-cli.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"conftest-cli.d.ts","sourceRoot":"","sources":["../../src/lib/conftest-cli.ts"],"names":[],"mappings":"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"}
|