@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
|
@@ -103,10 +103,24 @@ import rego.v1
|
|
|
103
103
|
|
|
104
104
|
default allow := false
|
|
105
105
|
|
|
106
|
+
# Don't show "secret" resources to anyone outside the owner's
|
|
107
|
+
# organization, even admins.
|
|
108
|
+
#
|
|
109
|
+
# Written as a guard the permissive rules consult. A second rule
|
|
110
|
+
# assigning \`allow := false\` is a conflict in Rego, not an override:
|
|
111
|
+
# both rules produce a value for the same document and evaluation
|
|
112
|
+
# fails with eval_conflict_error. Deny wins by being a precondition,
|
|
113
|
+
# not by being written last.
|
|
114
|
+
hidden_from_other_org if {
|
|
115
|
+
input.resource.classification == "secret"
|
|
116
|
+
input.resource.org_id != input.user.org_id
|
|
117
|
+
}
|
|
118
|
+
|
|
106
119
|
# A user can read any resource they own.
|
|
107
120
|
allow if {
|
|
108
121
|
input.action == "read"
|
|
109
122
|
input.resource.owner_id == input.user.id
|
|
123
|
+
not hidden_from_other_org
|
|
110
124
|
}
|
|
111
125
|
|
|
112
126
|
# A user can read shared resources at their organization.
|
|
@@ -114,19 +128,14 @@ allow if {
|
|
|
114
128
|
input.action == "read"
|
|
115
129
|
input.resource.shared
|
|
116
130
|
input.resource.org_id == input.user.org_id
|
|
131
|
+
not hidden_from_other_org
|
|
117
132
|
}
|
|
118
133
|
|
|
119
134
|
# Admins can do anything within their organization.
|
|
120
135
|
allow if {
|
|
121
136
|
"admin" in input.user.roles
|
|
122
137
|
input.resource.org_id == input.user.org_id
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
# Don't show "secret" resources to anyone outside the owner's
|
|
126
|
-
# organization, even admins.
|
|
127
|
-
allow := false if {
|
|
128
|
-
input.resource.classification == "secret"
|
|
129
|
-
input.resource.org_id != input.user.org_id
|
|
138
|
+
not hidden_from_other_org
|
|
130
139
|
}
|
|
131
140
|
\`\`\`
|
|
132
141
|
|
|
@@ -160,8 +169,12 @@ test_admin_blocked_from_secret_in_other_org if {
|
|
|
160
169
|
\`\`\`
|
|
161
170
|
|
|
162
171
|
**Pitfalls:**
|
|
163
|
-
- Multiple \`allow\` rules combine with logical OR.
|
|
164
|
-
|
|
172
|
+
- Multiple \`allow\` rules combine with logical OR. A later rule
|
|
173
|
+
cannot override an earlier one by assigning a different value:
|
|
174
|
+
two rules producing different values for the same document is an
|
|
175
|
+
\`eval_conflict_error\` and evaluation fails. Express a denial as a
|
|
176
|
+
condition the permissive rules must pass, as \`hidden_from_other_org\`
|
|
177
|
+
does above.
|
|
165
178
|
- Don't compute attributes inside the policy; compute them at the
|
|
166
179
|
boundary and pass via \`input\`.
|
|
167
180
|
|
|
@@ -236,14 +249,27 @@ deny contains msg if {
|
|
|
236
249
|
}
|
|
237
250
|
|
|
238
251
|
# Reject IAM policies with action "*" on resource "*".
|
|
252
|
+
#
|
|
253
|
+
# AWS accepts either a bare string or an array for Statement, Action
|
|
254
|
+
# and Resource, so each is widened to a set before the wildcard test.
|
|
255
|
+
# Testing the array form alone lets the most common admin policy of
|
|
256
|
+
# all, {"Action": "*", "Resource": "*"}, through untouched.
|
|
257
|
+
to_set(v) := {v} if is_string(v)
|
|
258
|
+
|
|
259
|
+
to_set(v) := {x | some x in v} if is_array(v)
|
|
260
|
+
|
|
261
|
+
statements(policy) := to_set(policy.Statement) if is_array(policy.Statement)
|
|
262
|
+
|
|
263
|
+
statements(policy) := {policy.Statement} if is_object(policy.Statement)
|
|
264
|
+
|
|
239
265
|
deny contains msg if {
|
|
240
266
|
resource := input.resource_changes[_]
|
|
241
267
|
resource.type == "aws_iam_policy"
|
|
242
268
|
policy := json.unmarshal(resource.change.after.policy)
|
|
243
|
-
statement
|
|
269
|
+
some statement in statements(policy)
|
|
244
270
|
statement.Effect == "Allow"
|
|
245
|
-
"*" in statement.Action
|
|
246
|
-
statement.Resource
|
|
271
|
+
"*" in to_set(statement.Action)
|
|
272
|
+
"*" in to_set(statement.Resource)
|
|
247
273
|
msg := sprintf("IAM policy %q grants Allow * on *", [resource.address])
|
|
248
274
|
}
|
|
249
275
|
\`\`\`
|
|
@@ -253,6 +279,8 @@ deny contains msg if {
|
|
|
253
279
|
\`terraform plan -json\` schema you target.
|
|
254
280
|
- \`resource_changes[_].change.after\` may be \`null\` for destroys --
|
|
255
281
|
guard against it.
|
|
282
|
+
- IAM policy documents are string-or-array in several places. Match
|
|
283
|
+
both, or a policy that grants everything slips through.
|
|
256
284
|
- For wide-radius changes, use \`opa exec --decision\` against a plan
|
|
257
285
|
file in CI, not the live API.
|
|
258
286
|
|
|
@@ -368,9 +396,8 @@ deny_reason := sprintf(
|
|
|
368
396
|
|
|
369
397
|
## Where these patterns came from
|
|
370
398
|
|
|
371
|
-
Each is distilled from production policy code
|
|
372
|
-
tests
|
|
373
|
-
repository under \`tests/fixtures/policies/\`.
|
|
399
|
+
Each is distilled from production policy code, and this server's
|
|
400
|
+
integration tests evaluate every pattern against OPA.
|
|
374
401
|
|
|
375
402
|
For more patterns, see:
|
|
376
403
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/resources/patterns.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG
|
|
1
|
+
{"version":3,"file":"patterns.js","sourceRoot":"","sources":["../../src/resources/patterns.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+YvB,CAAC"}
|
package/dist/server.d.ts
CHANGED
|
@@ -11,8 +11,8 @@ export { SERVER_NAME, SERVER_VERSION };
|
|
|
11
11
|
*/
|
|
12
12
|
export declare function buildServer(config: Config): McpServer;
|
|
13
13
|
/**
|
|
14
|
-
* Probe the configured `opa` and `
|
|
15
|
-
*
|
|
14
|
+
* Probe the configured `opa`, `regal` and `conftest` binaries at startup
|
|
15
|
+
* and log a warning for each that is unreachable. Runs in the background so it
|
|
16
16
|
* doesn't delay the MCP `initialize` handshake. Most users only see
|
|
17
17
|
* the failure when they call a tool; surfacing it early in the log
|
|
18
18
|
* file gives operators a place to look when diagnosing
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AAaA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAI/E,OAAO,EAAc,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAa7D,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;AAiBvC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAuBrD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA0CvE;AAED;;;;;;;GAOG;AACH,wBAAsB,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CA4DpE"}
|
package/dist/server.js
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* IMPORTANT: never write to stdout from anywhere in this process --
|
|
9
9
|
* stdout is the MCP protocol channel. Use `logger` (file) or stderr.
|
|
10
10
|
*/
|
|
11
|
-
import {
|
|
11
|
+
import { realpathSync } from 'node:fs';
|
|
12
|
+
import { fileURLToPath } from 'node:url';
|
|
12
13
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
13
14
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
14
15
|
import { formatHelp, formatStartupBanner, formatVersion, parseCliArgs } from './cli.js';
|
|
@@ -19,6 +20,9 @@ import { getInstallId } from './lib/install-id.js';
|
|
|
19
20
|
import { ConftestCli } from './lib/conftest-cli.js';
|
|
20
21
|
import { OpaCli } from './lib/opa-cli.js';
|
|
21
22
|
import { RegalCli } from './lib/regal-cli.js';
|
|
23
|
+
import { isZ3Busy, isZ3Failure, markZ3Unusable, z3RecoveriesLeft } from './lib/rego-z3.js';
|
|
24
|
+
import { redactUrlCredentials } from './lib/opa-client.js';
|
|
25
|
+
import { terminateChildren } from './lib/subprocess.js';
|
|
22
26
|
import { registerPrompts } from './prompts/index.js';
|
|
23
27
|
import { registerResources } from './resources/index.js';
|
|
24
28
|
import { registerTools } from './tools/index.js';
|
|
@@ -48,7 +52,7 @@ export function buildServer(config) {
|
|
|
48
52
|
initLogger(config.logFile, config.logLevel);
|
|
49
53
|
logger.info('starting orygn-opa-mcp', {
|
|
50
54
|
version: SERVER_VERSION,
|
|
51
|
-
opaUrl: config.opaUrl,
|
|
55
|
+
opaUrl: redactUrlCredentials(config.opaUrl),
|
|
52
56
|
opaBinary: config.opaBinary,
|
|
53
57
|
regalBinary: config.regalBinary,
|
|
54
58
|
});
|
|
@@ -61,8 +65,8 @@ export function buildServer(config) {
|
|
|
61
65
|
return server;
|
|
62
66
|
}
|
|
63
67
|
/**
|
|
64
|
-
* Probe the configured `opa` and `
|
|
65
|
-
*
|
|
68
|
+
* Probe the configured `opa`, `regal` and `conftest` binaries at startup
|
|
69
|
+
* and log a warning for each that is unreachable. Runs in the background so it
|
|
66
70
|
* doesn't delay the MCP `initialize` handshake. Most users only see
|
|
67
71
|
* the failure when they call a tool; surfacing it early in the log
|
|
68
72
|
* file gives operators a place to look when diagnosing
|
|
@@ -90,9 +94,9 @@ export async function runStartupSelfCheck(config) {
|
|
|
90
94
|
logger.info('startup self-check: opa OK', { version: opaVersion });
|
|
91
95
|
}
|
|
92
96
|
if (regalVersion === null) {
|
|
93
|
-
logger.warn('startup self-check: regal binary not reachable; rego_lint will return REGAL_NOT_FOUND', {
|
|
97
|
+
logger.warn('startup self-check: regal binary not reachable; rego_lint, rego_security_audit and rego_fix will return REGAL_NOT_FOUND', {
|
|
94
98
|
regalBinary: config.regalBinary,
|
|
95
|
-
hint: 'set REGAL_BINARY to an absolute path, or ensure regal is on PATH. Regal is optional; only rego_lint
|
|
99
|
+
hint: 'set REGAL_BINARY to an absolute path, or ensure regal is on PATH. Regal is optional; only rego_lint, rego_security_audit and rego_fix require it.',
|
|
96
100
|
});
|
|
97
101
|
}
|
|
98
102
|
else {
|
|
@@ -124,6 +128,38 @@ export async function main(transport) {
|
|
|
124
128
|
if (!transport) {
|
|
125
129
|
process.stderr.write(formatStartupBanner(config, process.stderr.isTTY === true) + '\n');
|
|
126
130
|
}
|
|
131
|
+
// A child sits in its own process group (see lib/subprocess.ts), so a
|
|
132
|
+
// signal that stops the server does not reach it by itself. Not when a
|
|
133
|
+
// test drives the server through its own transport: the runner owns the
|
|
134
|
+
// signals then.
|
|
135
|
+
if (!transport) {
|
|
136
|
+
for (const sig of ['SIGINT', 'SIGTERM']) {
|
|
137
|
+
process.once(sig, () => {
|
|
138
|
+
terminateChildren('SIGTERM');
|
|
139
|
+
process.exit(sig === 'SIGINT' ? 130 : 143);
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
// Z3 lives in a WASM heap that, exhausted, aborts outside every
|
|
143
|
+
// try/catch. Verification is the only thing on that heap, so give it up
|
|
144
|
+
// and keep the server rather than the reverse. Anything else uncaught is
|
|
145
|
+
// a bug the process must not paper over.
|
|
146
|
+
process.on('uncaughtException', (e) => {
|
|
147
|
+
const detail = e instanceof Error ? e.message : String(e);
|
|
148
|
+
// Only a WASM fault while a solve is running is Z3's; anything else
|
|
149
|
+
// that happens to land in that window is a bug of its own.
|
|
150
|
+
if (isZ3Busy() && isZ3Failure(e)) {
|
|
151
|
+
markZ3Unusable(detail);
|
|
152
|
+
logger.error(z3RecoveriesLeft() > 0
|
|
153
|
+
? 'Z3 faulted outside a try/catch; the solve in flight is retried on a fresh Z3'
|
|
154
|
+
: 'Z3 faulted outside a try/catch and no recoveries remain; rego_verify is disabled until restart', { error: detail, recoveriesLeft: z3RecoveriesLeft() });
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
logger.error('uncaught exception', {
|
|
158
|
+
error: e instanceof Error ? (e.stack ?? detail) : detail,
|
|
159
|
+
});
|
|
160
|
+
process.exit(1);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
127
163
|
const connectTo = transport ?? new StdioServerTransport();
|
|
128
164
|
await server.connect(connectTo);
|
|
129
165
|
logger.info('connected to transport, ready for requests');
|
|
@@ -144,9 +180,16 @@ function isEntryPoint() {
|
|
|
144
180
|
if (!argv1)
|
|
145
181
|
return false;
|
|
146
182
|
try {
|
|
147
|
-
|
|
183
|
+
// Compare real paths. Node resolves symlinks for the module's own URL but
|
|
184
|
+
// leaves process.argv[1] as it was invoked, so a server reached through a
|
|
185
|
+
// link saw two different strings and started nothing: no --version, no
|
|
186
|
+
// --help, and no transport, which a client sees as a process that exits
|
|
187
|
+
// immediately. npm's bin entry is a symlink on macOS and Linux, and
|
|
188
|
+
// installing globally or running through npx goes through it.
|
|
189
|
+
return realpathSync(fileURLToPath(import.meta.url)) === realpathSync(argv1);
|
|
148
190
|
}
|
|
149
191
|
catch {
|
|
192
|
+
// A path that cannot be resolved is not this module.
|
|
150
193
|
return false;
|
|
151
194
|
}
|
|
152
195
|
}
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAGjF,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExF,OAAO,EAAE,UAAU,EAAe,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,CAAC;AAEvC,SAAS,iBAAiB;IACxB,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,KAAK,GAAG;QAAE,OAAO;IACxD,KAAK,CAAC,KAAK,IAAI,EAAE;QACf,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;YACjC,CAAC,EAAE,cAAc;YACjB,CAAC,EAAE,OAAO,CAAC,QAAQ;SACpB,CAAC,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,YAAY,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,EAAE;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QAC5B,MAAM,KAAK,CAAC,0DAA0D,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE;YACzF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;IACL,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AACvB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IAE5C,MAAM,CAAC,IAAI,CAAC,wBAAwB,EAAE;QACpC,OAAO,EAAE,cAAc;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,12 +2,16 @@ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
2
2
|
import type { Config } from '../../config.js';
|
|
3
3
|
export interface RegoCapabilitiesOutput {
|
|
4
4
|
builtins?: unknown[];
|
|
5
|
+
/** How many of the names in a `builtins` filter were found. */
|
|
6
|
+
matched?: number;
|
|
5
7
|
builtin_names?: string[];
|
|
6
8
|
builtin_count?: number;
|
|
7
9
|
future_keywords?: unknown[];
|
|
8
10
|
features?: unknown[];
|
|
9
11
|
wasm_abi_versions?: unknown[];
|
|
10
12
|
versions?: string[];
|
|
13
|
+
/** Names asked for through `builtins` that the capabilities do not hold. */
|
|
14
|
+
missing?: string[];
|
|
11
15
|
}
|
|
12
16
|
export declare function registerRegoCapabilities(server: McpServer, config: Config): void;
|
|
13
17
|
//# sourceMappingURL=capabilities.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../src/tools/authoring/capabilities.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../../src/tools/authoring/capabilities.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAkC9C,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,EAAE,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAmHhF"}
|
|
@@ -21,14 +21,19 @@ const RegoCapabilitiesInput = {
|
|
|
21
21
|
names_only: z
|
|
22
22
|
.boolean()
|
|
23
23
|
.optional()
|
|
24
|
-
.default(
|
|
25
|
-
|
|
24
|
+
.describe('When true, or omitted, return only builtin names, count, future keywords, and features. The full payload for every builtin is larger than the default response cap (OPA_MCP_MAX_RESPONSE_BYTES), so `names_only: false` on its own needs that cap raised; use `builtins` to get full records for a few names instead.'),
|
|
25
|
+
builtins: z
|
|
26
|
+
.array(z.string().min(1))
|
|
27
|
+
.min(1)
|
|
28
|
+
.max(100)
|
|
29
|
+
.optional()
|
|
30
|
+
.describe('Return the full record (type signature, documentation, metadata) for up to 100 builtin names, exact matches only. `matched` counts the records returned and names not found are listed under `missing`. When the records would not fit the response cap the tool returns OUTPUT_TOO_LARGE rather than a truncated result; ask for fewer names. Do not combine with `names_only: true`, which asks for the opposite.'),
|
|
26
31
|
};
|
|
27
32
|
export function registerRegoCapabilities(server, config) {
|
|
28
33
|
const opa = new OpaCli(config);
|
|
29
34
|
server.registerTool('rego_capabilities', {
|
|
30
35
|
title: 'OPA capabilities',
|
|
31
|
-
description: 'Return OPA capabilities -- the available builtins, future keywords, features, and WASM ABI versions. With `current: true`, returns the running OPA\'s capabilities. With `version: "v1.19.0"`, returns those of a specific version. With neither, lists available named versions. By default (`names_only: true`), returns only builtin names and count to stay within response size limits
|
|
36
|
+
description: 'Return OPA capabilities -- the available builtins, future keywords, features, and WASM ABI versions. With `current: true`, returns the running OPA\'s capabilities. With `version: "v1.19.0"`, returns those of a specific version. With neither, lists available named versions. By default (`names_only: true`), returns only builtin names and count to stay within response size limits. Pass `builtins: [...]` for the full type signatures and documentation of a few named builtins; `names_only: false` returns every full record, which needs OPA_MCP_MAX_RESPONSE_BYTES raised above its default.',
|
|
32
37
|
inputSchema: RegoCapabilitiesInput,
|
|
33
38
|
annotations: {
|
|
34
39
|
readOnlyHint: true,
|
|
@@ -36,11 +41,19 @@ export function registerRegoCapabilities(server, config) {
|
|
|
36
41
|
idempotentHint: true,
|
|
37
42
|
openWorldHint: false,
|
|
38
43
|
},
|
|
39
|
-
}, async ({ current, version, names_only }, { signal }) => {
|
|
44
|
+
}, async ({ current, version, names_only, builtins }, { signal }) => {
|
|
40
45
|
return withToolEnvelope(config, async () => {
|
|
41
46
|
if (current && version) {
|
|
42
47
|
return err('INVALID_INPUT', 'rego_capabilities accepts at most one of `current` or `version`.');
|
|
43
48
|
}
|
|
49
|
+
if (names_only === true && builtins !== undefined) {
|
|
50
|
+
return err('INVALID_INPUT', 'rego_capabilities: `names_only: true` asks for names alone and `builtins` asks for full records; pass one or the other.');
|
|
51
|
+
}
|
|
52
|
+
// The schema bounds the filter; the handler does too, before opa is
|
|
53
|
+
// run, since a unit harness may call it directly.
|
|
54
|
+
if (builtins !== undefined && (builtins.length === 0 || builtins.length > 100)) {
|
|
55
|
+
return err('INVALID_INPUT', '`builtins` takes between 1 and 100 names.');
|
|
56
|
+
}
|
|
44
57
|
const result = await opa.capabilities({ current, version }, signal);
|
|
45
58
|
const subprocessFailure = mapSubprocessFailure(result, 'opa');
|
|
46
59
|
if (subprocessFailure)
|
|
@@ -61,6 +74,30 @@ export function registerRegoCapabilities(server, config) {
|
|
|
61
74
|
details: { stdout: trimmed },
|
|
62
75
|
});
|
|
63
76
|
}
|
|
77
|
+
// A handful of full records fits the cap where the whole payload does
|
|
78
|
+
// not; this is the way to read a builtin's signature and docs.
|
|
79
|
+
if (builtins !== undefined && builtins.length > 0) {
|
|
80
|
+
const wanted = new Set(builtins);
|
|
81
|
+
const records = (parsed.builtins ?? []).filter((b) => wanted.has(b.name ?? ''));
|
|
82
|
+
const found = new Set(records.map((b) => b.name));
|
|
83
|
+
const missing = builtins.filter((n) => !found.has(n));
|
|
84
|
+
const data = {
|
|
85
|
+
builtins: records,
|
|
86
|
+
matched: records.length,
|
|
87
|
+
...(missing.length > 0 ? { missing } : {}),
|
|
88
|
+
};
|
|
89
|
+
// A count cannot promise a size: the largest records run past 2 KB
|
|
90
|
+
// each, so a hundred of those exceed the default cap. Measure the
|
|
91
|
+
// envelope as it will be sent and refuse rather than truncate.
|
|
92
|
+
const bytes = Buffer.byteLength(JSON.stringify(ok(data), null, 2), 'utf8');
|
|
93
|
+
if (bytes > config.maxResponseBytes) {
|
|
94
|
+
return err('OUTPUT_TOO_LARGE', `The full records for these ${records.length} builtins serialise to ${bytes} bytes, above the ${config.maxResponseBytes}-byte response cap.`, {
|
|
95
|
+
hint: 'Ask for fewer names, or raise OPA_MCP_MAX_RESPONSE_BYTES.',
|
|
96
|
+
details: { matched: records.length, bytes, cap: config.maxResponseBytes },
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return ok(data);
|
|
100
|
+
}
|
|
64
101
|
// names_only defaults to true; treat undefined as true so the default
|
|
65
102
|
// applies even when the MCP SDK's schema validation is bypassed.
|
|
66
103
|
if (names_only !== false) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../../src/tools/authoring/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAEjG,MAAM,qBAAqB,GAAG;IAC5B,OAAO,EAAE,CAAC;SACP,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,QAAQ,CACP,2FAA2F,CAC5F;IACH,OAAO,EAAE,CAAC;SACP,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CACP,2GAA2G,CAC5G;IACH,UAAU,EAAE,CAAC;SACV,OAAO,EAAE;SACT,QAAQ,EAAE;SACV,
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../../src/tools/authoring/capabilities.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,6 +15,12 @@ export interface RegoCheckSchemaOutput {
|
|
|
15
15
|
/** Structured diagnostics. Empty when `valid` is true. */
|
|
16
16
|
errors: CheckErrorRecord[];
|
|
17
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Whether the source carries a `# METADATA` comment block with a `schemas:`
|
|
20
|
+
* entry, the one way opa reads a schema directory: each entry names a file
|
|
21
|
+
* in it for a path in `input` or `data`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function declaresSchemas(source: string): boolean;
|
|
18
24
|
export declare function registerRegoCheckSchema(server: McpServer, config: Config): void;
|
|
19
25
|
export {};
|
|
20
26
|
//# sourceMappingURL=check-schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-schema.d.ts","sourceRoot":"","sources":["../../../src/tools/authoring/check-schema.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"check-schema.d.ts","sourceRoot":"","sources":["../../../src/tools/authoring/check-schema.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AA6C9C,UAAU,gBAAgB;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1D;AAED,MAAM,WAAW,qBAAqB;IACpC,4DAA4D;IAC5D,KAAK,EAAE,OAAO,CAAC;IACf,0DAA0D;IAC1D,MAAM,EAAE,gBAAgB,EAAE,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CASvD;AA4BD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAkJ/E"}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* rego_infer_input_schema to derive the schema from policy A, then pass its
|
|
16
16
|
* output directly as `inlineSchema` here to validate policy B against it.
|
|
17
17
|
*/
|
|
18
|
-
import { mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
18
|
+
import { mkdtemp, rm, stat, writeFile } from 'node:fs/promises';
|
|
19
19
|
import { tmpdir } from 'node:os';
|
|
20
20
|
import { join } from 'node:path';
|
|
21
21
|
import { z } from 'zod';
|
|
@@ -38,17 +38,54 @@ const RegoCheckSchemaInput = {
|
|
|
38
38
|
schemaPath: z
|
|
39
39
|
.string()
|
|
40
40
|
.optional()
|
|
41
|
-
.describe('Path to a JSON Schema file on disk to use for `input` validation. Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). Mutually exclusive with `inlineSchema`.'),
|
|
41
|
+
.describe('Path to a JSON Schema file on disk to use for `input` validation, or to a schema directory when the policy carries `# METADATA` / `schemas:` annotations naming files in it (opa reads a directory only through those). Must be inside an allowed root (OPA_MCP_ALLOWED_PATHS). Mutually exclusive with `inlineSchema`.'),
|
|
42
42
|
strict: z
|
|
43
43
|
.boolean()
|
|
44
44
|
.optional()
|
|
45
45
|
.describe('Enable strict mode -- also fail on unused variables, deprecated builtins, and other non-fatal issues in addition to schema violations.'),
|
|
46
46
|
};
|
|
47
|
+
/**
|
|
48
|
+
* Whether the source carries a `# METADATA` comment block with a `schemas:`
|
|
49
|
+
* entry, the one way opa reads a schema directory: each entry names a file
|
|
50
|
+
* in it for a path in `input` or `data`.
|
|
51
|
+
*/
|
|
52
|
+
export function declaresSchemas(source) {
|
|
53
|
+
const lines = source.split(/\r?\n/);
|
|
54
|
+
for (let i = 0; i < lines.length; i++) {
|
|
55
|
+
if (!/^\s*#\s*METADATA\b/.test(lines[i]))
|
|
56
|
+
continue;
|
|
57
|
+
for (let j = i + 1; j < lines.length && /^\s*#/.test(lines[j]); j++) {
|
|
58
|
+
if (/^\s*#\s*schemas\s*:/.test(lines[j]))
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Whether any policy under `paths` carries a `schemas:` annotation, as OPA
|
|
66
|
+
* itself reads it. Asking opa keeps this tool from reading policy files on
|
|
67
|
+
* its own, and a path opa cannot inspect is left for opa check to report.
|
|
68
|
+
*/
|
|
69
|
+
async function anyPathDeclaresSchemas(opa, paths, signal) {
|
|
70
|
+
for (const target of paths) {
|
|
71
|
+
const result = await opa.inspect({ target }, signal);
|
|
72
|
+
const failure = mapSubprocessFailure(result, 'opa');
|
|
73
|
+
if (failure)
|
|
74
|
+
return failure;
|
|
75
|
+
if (result.exitCode !== 0)
|
|
76
|
+
continue;
|
|
77
|
+
const parsed = tryParseJson(result.stdout);
|
|
78
|
+
const declared = (parsed?.annotations ?? []).some((entry) => Array.isArray(entry.annotations?.schemas) && entry.annotations.schemas.length > 0);
|
|
79
|
+
if (declared)
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
47
84
|
export function registerRegoCheckSchema(server, config) {
|
|
48
85
|
const opa = new OpaCli(config);
|
|
49
86
|
server.registerTool('rego_check_schema', {
|
|
50
87
|
title: 'Check Rego against a JSON Schema',
|
|
51
|
-
description: "Validate that a Rego policy's input.* field references are consistent with a JSON Schema using `opa check --schema`. Every field the policy reads from `input` must exist in the schema; mismatches surface as rego_type_error diagnostics with file/line locations. Returns `{ valid: true, errors: [] }` when all references match the schema, or `{ valid: false, errors: [...] }` with structured diagnostics when they do not. Accepts the schema inline (pass the `schema` output of `rego_infer_input_schema` directly as `inlineSchema`) or as a path to
|
|
88
|
+
description: "Validate that a Rego policy's input.* field references are consistent with a JSON Schema using `opa check --schema`. Every field the policy reads from `input` must exist in the schema; mismatches surface as rego_type_error diagnostics with file/line locations. Returns `{ valid: true, errors: [] }` when all references match the schema, or `{ valid: false, errors: [...] }` with structured diagnostics when they do not. Accepts the schema inline (pass the `schema` output of `rego_infer_input_schema` directly as `inlineSchema`) or as a path to a JSON Schema file on disk, or to a schema directory when the policy declares `schemas:` annotations (`schemaPath`). Provide `source` for inline Rego or `paths` for file/directory checking.",
|
|
52
89
|
inputSchema: RegoCheckSchemaInput,
|
|
53
90
|
annotations: {
|
|
54
91
|
readOnlyHint: true,
|
|
@@ -87,6 +124,22 @@ export function registerRegoCheckSchema(server, config) {
|
|
|
87
124
|
if (!v.ok)
|
|
88
125
|
return v.error;
|
|
89
126
|
resolvedSchemaFile = v.resolved[0];
|
|
127
|
+
// opa accepts a directory here, but reads from it only where the
|
|
128
|
+
// policy carries schema annotations naming files in it. Without
|
|
129
|
+
// those a directory checked nothing and came back valid.
|
|
130
|
+
if ((await stat(resolvedSchemaFile)).isDirectory()) {
|
|
131
|
+
const annotated = source !== undefined
|
|
132
|
+
? declaresSchemas(source)
|
|
133
|
+
: await anyPathDeclaresSchemas(opa, resolvedPaths ?? [], signal);
|
|
134
|
+
if (typeof annotated !== 'boolean')
|
|
135
|
+
return annotated;
|
|
136
|
+
if (!annotated) {
|
|
137
|
+
return err('INVALID_INPUT', 'schemaPath is a directory, which opa reads only where the policy carries `schemas:` annotations naming files in it; this policy carries none, so nothing would be checked.', {
|
|
138
|
+
hint: 'Pass the schema file directly, supply it as inlineSchema, or annotate the policy with a `# METADATA` block whose `schemas:` entry names a file in the directory.',
|
|
139
|
+
details: { schemaPath },
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
}
|
|
90
143
|
}
|
|
91
144
|
// ── Inline schema: write to a temp file, clean up unconditionally ─
|
|
92
145
|
let tempDir;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-schema.js","sourceRoot":"","sources":["../../../src/tools/authoring/check-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"check-schema.js","sourceRoot":"","sources":["../../../src/tools/authoring/check-schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/tools/authoring/format.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/tools/authoring/format.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAc9C,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;CAClB;AAuCD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CA6E1E"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
import { OpaCli } from '../../lib/opa-cli.js';
|
|
9
9
|
import { err, ok } from '../../lib/errors.js';
|
|
10
|
-
import { mapSubprocessFailure, tryParseJson, withToolEnvelope } from '../../lib/tool-helpers.js';
|
|
10
|
+
import { mapSubprocessFailure, sanitizeInlinePathsDeep, tryParseJson, withToolEnvelope, } from '../../lib/tool-helpers.js';
|
|
11
11
|
const RegoFormatInput = {
|
|
12
12
|
source: z.string().min(1).describe('Rego source code to format.'),
|
|
13
13
|
};
|
|
@@ -89,7 +89,7 @@ export function registerRegoFormat(server, config) {
|
|
|
89
89
|
// available.
|
|
90
90
|
const parsedErrors = tryParseJson(result.stderr);
|
|
91
91
|
return err('INVALID_REGO', 'opa fmt rejected the source; the input is not parseable Rego.', {
|
|
92
|
-
details: parsedErrors ?? { stderr: result.stderr.trim() },
|
|
92
|
+
details: sanitizeInlinePathsDeep(parsedErrors ?? { stderr: result.stderr.trim() }),
|
|
93
93
|
});
|
|
94
94
|
}
|
|
95
95
|
const formatted = result.stdout;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/tools/authoring/format.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/tools/authoring/format.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,YAAY,EACZ,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,eAAe,GAAG;IACtB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,6BAA6B,CAAC;CAClE,CAAC;AAOF,+EAA+E;AAE/E,gFAAgF;AAChF,SAAS,sBAAsB,CAAC,MAAc;IAC5C,OAAO,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxD,CAAC;AAED,sGAAsG;AACtG,SAAS,eAAe,CAAC,MAAc;IACrC,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACH,SAAS,YAAY,CAAC,CAAS;IAC7B,MAAM,CAAC,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzC,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED;;;;GAIG;AACH,SAAS,sBAAsB,CAAC,OAAe;IAC7C,MAAM,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACrB,OAAO,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,iFAAiF;AAEjF,MAAM,UAAU,kBAAkB,CAAC,MAAiB,EAAE,MAAc;IAClE,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;IAE/B,MAAM,CAAC,YAAY,CACjB,aAAa,EACb;QACE,KAAK,EAAE,aAAa;QACpB,WAAW,EACT,iJAAiJ;YACjJ,yOAAyO;QAC3O,WAAW,EAAE,eAAe;QAC5B,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAC/B,OAAO,gBAAgB,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE;YACzC,MAAM,QAAQ,GAAa,EAAE,CAAC;YAE9B,iEAAiE;YACjE,6DAA6D;YAC7D,iEAAiE;YACjE,iEAAiE;YACjE,4DAA4D;YAC5D,sDAAsD;YACtD,IAAI,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC7C,IAAI,UAAU,KAAK,IAAI,IAAI,sBAAsB,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC9D,IAAI,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC5B,OAAO,GAAG,CACR,yBAAyB,EACzB,YAAY,UAAU,mJAAmJ,EACzK;4BACE,IAAI,EAAE,mFAAmF;4BACzF,OAAO,EAAE,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE;yBAChE,CACF,CAAC;oBACJ,CAAC;oBACD,QAAQ,CAAC,IAAI,CACX,QAAQ,UAAU,yRAAyR,CAC5S,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC;YAEjD,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC9D,IAAI,iBAAiB;gBAAE,OAAO,iBAAiB,CAAC;YAEhD,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;gBAC1B,yDAAyD;gBACzD,4DAA4D;gBAC5D,2DAA2D;gBAC3D,aAAa;gBACb,MAAM,YAAY,GAAG,YAAY,CAE9B,MAAM,CAAC,MAAM,CAAC,CAAC;gBAClB,OAAO,GAAG,CACR,cAAc,EACd,+DAA+D,EAC/D;oBACE,OAAO,EAAE,uBAAuB,CAAC,YAAY,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;iBACnF,CACF,CAAC;YACJ,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;YAChC,OAAO,EAAE,CACP,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,KAAK,MAAM,EAAE,EAC5C,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAC3C,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../../src/tools/authoring/lint.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"lint.d.ts","sourceRoot":"","sources":["../../../src/tools/authoring/lint.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAuC9C,UAAU,aAAa;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAmBD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAmFxE"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { z } from 'zod';
|
|
8
8
|
import { RegalCli } from '../../lib/regal-cli.js';
|
|
9
9
|
import { err, ok } from '../../lib/errors.js';
|
|
10
|
-
import { INLINE_TEMP_PATH_PATTERN, mapSubprocessFailure, sanitizeInlinePath, tryParseJson, validatePaths, withToolEnvelope, } from '../../lib/tool-helpers.js';
|
|
10
|
+
import { INLINE_TEMP_PATH_PATTERN, mapSubprocessFailure, sanitizeInlinePath, sanitizeInlinePathsDeep, tryParseJson, validatePaths, withToolEnvelope, } from '../../lib/tool-helpers.js';
|
|
11
11
|
const RegoLintInput = {
|
|
12
12
|
source: z.string().optional().describe('Inline Rego source. Mutually exclusive with `paths`.'),
|
|
13
13
|
paths: z
|
|
@@ -56,10 +56,9 @@ export function registerRegoLint(server, config) {
|
|
|
56
56
|
description: 'Lint Rego source with the Regal linter. Returns categorized violations (style, bugs, idiomatic, performance) with file/line locations. Requires `regal` on PATH or `REGAL_BINARY` set; returns REGAL_NOT_FOUND otherwise. When called with inline `source`, location-bound rules whose verdict depends on the on-disk path (`directory-package-mismatch`) are auto-disabled to avoid temp-file false positives, and `location.file` is reported as `<inline>` instead of the randomized temp path. Re-enable those rules via `enable` if your workflow actually needs them.',
|
|
57
57
|
inputSchema: RegoLintInput,
|
|
58
58
|
annotations: {
|
|
59
|
-
readOnlyHint:
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
openWorldHint: false,
|
|
59
|
+
readOnlyHint: false,
|
|
60
|
+
// Runs a project's custom Regal rules, which are Rego with the network built-ins.
|
|
61
|
+
openWorldHint: true,
|
|
63
62
|
},
|
|
64
63
|
}, async (input, { signal }) => {
|
|
65
64
|
return withToolEnvelope(config, async () => {
|
|
@@ -101,7 +100,10 @@ export function registerRegoLint(server, config) {
|
|
|
101
100
|
const parsed = tryParseJson(result.stdout);
|
|
102
101
|
if (!parsed) {
|
|
103
102
|
return err('UNKNOWN_ERROR', 'regal lint produced no parseable JSON output.', {
|
|
104
|
-
details: {
|
|
103
|
+
details: sanitizeInlinePathsDeep({
|
|
104
|
+
stderr: result.stderr.trim(),
|
|
105
|
+
exitCode: result.exitCode,
|
|
106
|
+
}),
|
|
105
107
|
});
|
|
106
108
|
}
|
|
107
109
|
const rawViolations = parsed.violations ?? [];
|