@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/CHANGELOG.md
CHANGED
|
@@ -17,6 +17,577 @@ not part of the public surface and may change in minor releases.
|
|
|
17
17
|
|
|
18
18
|
## [Unreleased]
|
|
19
19
|
|
|
20
|
+
## [0.6.0] - 2026-09-07
|
|
21
|
+
|
|
22
|
+
### Security
|
|
23
|
+
|
|
24
|
+
- `rego_playground_share` created public Gists, listed on the account and
|
|
25
|
+
searchable, while the README described them as secret. Anyone who shared a
|
|
26
|
+
policy with it should assume the policy was public from the moment it was
|
|
27
|
+
posted. Gists are now secret unless `public: true` is passed: reachable by
|
|
28
|
+
their link, listed nowhere. The change is not retroactive: GitHub cannot make
|
|
29
|
+
an existing Gist secret, so a Gist created earlier that should not have been
|
|
30
|
+
public has to be deleted at github.com/gists and shared again.
|
|
31
|
+
|
|
32
|
+
### Changed
|
|
33
|
+
|
|
34
|
+
- `rego_bench` reports `iterations`, `nsPerOp`, `allocsPerOp` and
|
|
35
|
+
`bytesPerOp`, whole numbers as opa's own summary prints them, and keeps the
|
|
36
|
+
document opa printed under `raw` for a single run. Its fields `N`, `T`,
|
|
37
|
+
`Bytes`, `MemAllocs`, `MemBytes` and `Extra` were top-level before and now
|
|
38
|
+
sit under `raw`; the type had promised `iterations` and `metrics`, which
|
|
39
|
+
were never set. With `count` above one, `runs` holds every document and
|
|
40
|
+
`fastest` indexes the one the figures come from, so none is repeated.
|
|
41
|
+
|
|
42
|
+
### Added
|
|
43
|
+
|
|
44
|
+
- `rego_capabilities` takes a `builtins` filter of up to 100 names and returns
|
|
45
|
+
their full records under `builtins`, with a `matched` count and the
|
|
46
|
+
`missing` names. When the records would not fit the response cap it returns
|
|
47
|
+
`OUTPUT_TOO_LARGE` rather than a truncated result, and `names_only: true`
|
|
48
|
+
alongside it is refused as a contradiction; `names_only: false`
|
|
49
|
+
returns every record and is documented as needing the cap raised.
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- Windows: a Rego module on a different drive from the server's working
|
|
54
|
+
directory was reported missing. The 0.5.0 drive-letter fix respelled data
|
|
55
|
+
documents relative to a working directory on their drive but left modules
|
|
56
|
+
absolute, since a module mounts at its own `package` whatever path it
|
|
57
|
+
arrives by. OPA still opens the module by the remainder after the colon, a
|
|
58
|
+
root-relative path it resolves against the drive the child is running on, so
|
|
59
|
+
a module on any other drive failed with a file-not-found. Every load path now
|
|
60
|
+
takes part in choosing the working directory; only data documents are
|
|
61
|
+
respelled.
|
|
62
|
+
- Windows: `rego_check` with inline source and `rego_inspect` reported a
|
|
63
|
+
module missing when the server's temp directory was on a different drive
|
|
64
|
+
from its working directory, and `conftest_test` and `conftest_verify` failed
|
|
65
|
+
the same way through `--policy`. OPA and conftest open an absolute path by
|
|
66
|
+
the part after its first colon, resolved on the drive the process runs on;
|
|
67
|
+
each command now runs from the path's own drive. The configs under test are
|
|
68
|
+
read by conftest itself and may sit on any drive; a policy and a data
|
|
69
|
+
directory spread across two drives are refused with a message saying so.
|
|
70
|
+
- The subprocess timeout is now hard on Linux and macOS. The SIGKILL escalation
|
|
71
|
+
fired on a flag Node sets when a signal is sent rather than when the child
|
|
72
|
+
ends, so a child that ignored SIGTERM hung the tool call for good, and a
|
|
73
|
+
wrapper script that left a grandchild holding the pipes kept the result from
|
|
74
|
+
ever settling. A child killed from outside the server is reported as
|
|
75
|
+
`SUBPROCESS_KILLED` naming the signal, not as a missing binary. On SIGINT or
|
|
76
|
+
SIGTERM the server now signals the children it started before exiting.
|
|
77
|
+
- `rego_eval`, `rego_eval_with_explain`, `rego_eval_with_profile`,
|
|
78
|
+
`rego_eval_with_coverage`, `rego_compile_query`, `rego_explain_decision`: a
|
|
79
|
+
string input that happened to parse as JSON, such as `"42"`, `"true"` or a
|
|
80
|
+
quoted string, was retyped or unwrapped before evaluation. Strings now reach
|
|
81
|
+
the policy as strings; only an object or array that arrived serialized as a
|
|
82
|
+
string is still repaired, the way `rego_bench` and the server-management
|
|
83
|
+
tools already did.
|
|
84
|
+
- `rego_fix`: a real run reported zero fixes and no changed files after
|
|
85
|
+
changing them, because only the dry-run wording of regal's summary was read.
|
|
86
|
+
Both forms are read now.
|
|
87
|
+
- `opa_*` server tools: a request that OPA did not answer within
|
|
88
|
+
`OPA_MCP_HTTP_TIMEOUT_MS` was reported as `OPA_UNREACHABLE`, with a hint to
|
|
89
|
+
start a server that was already running. It is now `TIMEOUT`, naming the
|
|
90
|
+
limit, and the timer covers the response body as well as the headers.
|
|
91
|
+
- `conftest_test`: a denial reported under `failOnWarn` came back as a tool
|
|
92
|
+
error rather than as a failed check, because conftest exits 2 for it. Any
|
|
93
|
+
exit code with results on stdout is now an outcome, and only output without
|
|
94
|
+
results is treated as a command error, whose message now carries conftest's
|
|
95
|
+
own text; `conftest_verify` shares that last part.
|
|
96
|
+
- `rego_verify`: a policy that exhausted the Z3 WASM heap took the whole
|
|
97
|
+
server down, since the abort surfaced outside every try/catch. The solver is
|
|
98
|
+
now bounded at 768 MB, under a 1 GiB ceiling on Z3's allocations, so an
|
|
99
|
+
oversized problem comes back inconclusive.
|
|
100
|
+
- `rego_verify`: a helper whose body contains a literal `false` was inlined as
|
|
101
|
+
an always-true body, so a rule that can never fire was reported proven always
|
|
102
|
+
true, and a negated literal (`not false`, `not true`) was read as the bare
|
|
103
|
+
one in helpers and rule bodies alike. Boolean literals are now read as what
|
|
104
|
+
they say, and a helper with a true default and a body that never holds is
|
|
105
|
+
recognised as always holding.
|
|
106
|
+
- Every tool that evaluates Rego, including the Regal tools that run a
|
|
107
|
+
project's custom rules, now declares `openWorldHint: true` and no longer
|
|
108
|
+
claims `readOnlyHint`, since a policy's own `http.send` can reach, and write
|
|
109
|
+
to, a remote system. A client that gates on the hints will ask before running
|
|
110
|
+
one. The destructive and idempotent hints on those tools are left to the
|
|
111
|
+
spec's defaults, since a policy chooses its own HTTP method.
|
|
112
|
+
- Docker: the `opa` and `regal` downloads in the image build are now checked
|
|
113
|
+
against the digests published with their releases. The image was described
|
|
114
|
+
as reproducible while nothing verified those downloads; the wording now says
|
|
115
|
+
what the build does.
|
|
116
|
+
- `rego_security_audit` was described as running regal's `security` and
|
|
117
|
+
`bugs` categories; regal ships no `security` category, so that half of the
|
|
118
|
+
sweep matched nothing. The description now says what runs: the `bugs`
|
|
119
|
+
category, plus any custom rules a project places in a `security` category.
|
|
120
|
+
- `rego_explain_undefined`: on the path where OPA's indexer skips the rule, the
|
|
121
|
+
blocking condition was chosen from each body expression evaluated on its own,
|
|
122
|
+
so an expression that needs an earlier local or a sibling rule came back
|
|
123
|
+
unevaluable and was blamed ahead of the guard that really failed. The body is
|
|
124
|
+
now evaluated as cumulative prefixes inside the rule's package, with its
|
|
125
|
+
imports, and the first condition that stops holding is the one reported; the
|
|
126
|
+
conditions after it are left unevaluated, as on the traced path.
|
|
127
|
+
- `rego_check_schema` reported `valid: true` when `schemaPath` was a
|
|
128
|
+
directory, since opa reads a schema directory only through `schemas:`
|
|
129
|
+
annotations in the policy. A directory is now accepted when the policy
|
|
130
|
+
carries them (read from the source, or reported by `opa inspect` for files
|
|
131
|
+
on disk) and refused before opa runs when it does not, with the file form,
|
|
132
|
+
`inlineSchema` and the annotation named as the ways to make it work.
|
|
133
|
+
- `opa_bundle_sign` reported `signed: true` for a `.tar.gz` archive after
|
|
134
|
+
writing a `.signatures.json` beside it, which OPA never reads, so the
|
|
135
|
+
archive stayed unsigned. An archive is now refused with a pointer to
|
|
136
|
+
`opa_bundle_build`, which produces a signed one. The `outputDir` input,
|
|
137
|
+
which only applied to archives, is gone.
|
|
138
|
+
- `OPA_MCP_MAX_RESPONSE_BYTES` now bounds error envelopes as well as
|
|
139
|
+
results. An oversize error was sent whole with `truncated: true` set; its
|
|
140
|
+
details are now dropped first and its message cut last, so the code and
|
|
141
|
+
the message stay readable within the cap.
|
|
142
|
+
The cap bounds a success envelope's warnings as well, and
|
|
143
|
+
`OPA_MCP_MAX_RESPONSE_BYTES` refuses a value below 512, which sits above
|
|
144
|
+
the smallest complete envelope, rather than exceeding it.
|
|
145
|
+
- The temp directory inline source is written to could appear in the error
|
|
146
|
+
details of a dozen tools, in the message a binary printed about the file.
|
|
147
|
+
Every error envelope now passes through the sanitiser, which also covers a
|
|
148
|
+
JSON-encoded spelling, a directory name with a space, the inline schema and
|
|
149
|
+
bundle-verify temp files, and takes linear time on any input.
|
|
150
|
+
The server's own temp directory is matched by its exact spelling first,
|
|
151
|
+
so no guess about where a path begins is involved for the files it writes.
|
|
152
|
+
- `rego_explain_undefined` turned a spawn failure during its per-condition
|
|
153
|
+
evals or its parse step into a per-condition note or an empty analysis. A
|
|
154
|
+
binary that cannot run or a run that timed out now returns the tool's
|
|
155
|
+
`OPA_BINARY_NOT_FOUND` or `TIMEOUT` like every other tool.
|
|
156
|
+
- `rego_explain_undefined` validated `inputPath` and then passed the argument
|
|
157
|
+
as written to opa instead of the resolved path.
|
|
158
|
+
- The `*_BINARY` variables now refuse a relative path at startup, which the
|
|
159
|
+
README said they did, a drive-relative or root-relative name included; a
|
|
160
|
+
bare command name or an absolute path is accepted.
|
|
161
|
+
- Docs: the install note described a missing-`opa` failure that the npm
|
|
162
|
+
package's bundled binary already prevents, and now says where it still
|
|
163
|
+
applies; CONTRIBUTING said input fields are `snake_case` when the surface
|
|
164
|
+
is `camelCase`; two prompts sent readers to `rego_describe_policy` for input
|
|
165
|
+
refs, which `rego_infer_input_schema` reports.
|
|
166
|
+
- `rego_migrate_v1` reported a built-in that v1 removed, which fails type
|
|
167
|
+
checking in the `opa fmt --rego-v1` phase, as a parse failure with advice to
|
|
168
|
+
fix syntax. The type error opa gives is now the message, with a hint to
|
|
169
|
+
replace the built-in first; the description says so.
|
|
170
|
+
- `rego_verify`: a quoted key holding a dot, `input["a.b"]`, and the nested
|
|
171
|
+
path `input.a.b` were treated as one field, so a rule reading both was
|
|
172
|
+
proved never true, and a witness for the quoted key was built as the nested
|
|
173
|
+
object. Paths are now rendered the way Rego writes them and read back the
|
|
174
|
+
same way.
|
|
175
|
+
The soundness fuzz now carries quoted keys, so it exercises this.
|
|
176
|
+
- `conftest_test`, `conftest_verify`: an error from conftest named the temp
|
|
177
|
+
file an inline config or policy had been written to, a file the tool had
|
|
178
|
+
already removed. The path is replaced in stderr as it already was in the
|
|
179
|
+
results.
|
|
180
|
+
- `rego_verify`: a witness holding a non-ASCII string came back in Z3's
|
|
181
|
+
escape text, one escape per byte, which OPA did not accept as the string
|
|
182
|
+
the policy compares against. The escapes are decoded now. A backslash in a
|
|
183
|
+
policy literal is escaped on the way into Z3, so a literal that spells such
|
|
184
|
+
an escape itself is no longer read as one.
|
|
185
|
+
- Docs: the README now says an argument that fails a tool's input schema is
|
|
186
|
+
rejected by the MCP layer before the handler runs, names `rego_verify`'s
|
|
187
|
+
`kind` field, and describes `rego_suggest_fix` as returning suggestions with
|
|
188
|
+
a confidence level; the `opa://builtins` resource says which `opa` binary
|
|
189
|
+
it reflects.
|
|
190
|
+
- `rego_verify`: a field compared as a string, number or boolean and also read
|
|
191
|
+
as the object holding a deeper field was modelled as two unrelated values,
|
|
192
|
+
so a rule no input can satisfy was reported satisfiable with a witness OPA
|
|
193
|
+
rejects. The solver now knows that a field the rule compared equal to a
|
|
194
|
+
scalar, or fed to a string built-in, is never present alongside a path
|
|
195
|
+
beneath it. A rule that compares such a field in any other way (an
|
|
196
|
+
inequality, an ordering, a bare read, a comparison against another field)
|
|
197
|
+
and also reads beneath it is reported inconclusive, since the model gives
|
|
198
|
+
the field one scalar value that no input holding the deeper field can
|
|
199
|
+
match; before, that produced a counterexample OPA rejects. Both readings
|
|
200
|
+
are taken from the rule under test alone, so another rule in the module
|
|
201
|
+
does not decide either.
|
|
202
|
+
- `rego_verify` built its witness from every input path in the policy, so a
|
|
203
|
+
field only another rule reads was given a value and placed in the input.
|
|
204
|
+
Where that field was the parent of one the rule under test reads, the two
|
|
205
|
+
collided and the witness no longer satisfied the rule: `allow if input.x.y
|
|
206
|
+
== 2` beside `other if input.x > 1` returned `{"x": 0}`, which the policy
|
|
207
|
+
evaluates to undefined, and reported it as proof the rule can be true. A
|
|
208
|
+
witness now names only the fields its own rule reads. The witness
|
|
209
|
+
search that prefers every field present also re-checks after backing out,
|
|
210
|
+
rather than reading a stale model.
|
|
211
|
+
- `rego_test` with `coverage` or `threshold` and `count` above 1 returned no
|
|
212
|
+
coverage and reported the threshold as met: opa prints one report per
|
|
213
|
+
repetition and the concatenation did not parse as JSON, so none was read.
|
|
214
|
+
One is read now.
|
|
215
|
+
- `rego_test_multiroot` in coverage mode reported a root holding a `todo_`
|
|
216
|
+
test as failed and dropped its report, as `rego_test` used to; the report is
|
|
217
|
+
kept and the root passes.
|
|
218
|
+
- `rego_generate_test_skeleton` referenced every rule the same way, so a
|
|
219
|
+
function rule made the generated file fail to compile and a set, object or
|
|
220
|
+
value rule was compared to `true`. Each stub now follows the rule's head: a
|
|
221
|
+
function is called with placeholder arguments, a set or object is compared
|
|
222
|
+
to an empty one, a value rule to its literal when the head is one; a
|
|
223
|
+
computed head, which offers nothing to assert, becomes a `todo_test_` that
|
|
224
|
+
opa test skips rather than a placeholder that passes. The generated file no longer
|
|
225
|
+
imports the package it references by full path, which `opa check --strict`
|
|
226
|
+
reported as an unused import.
|
|
227
|
+
- A username and password embedded in `OPA_URL` were echoed into every
|
|
228
|
+
`opa_*` error envelope and the startup log, and made every call fail as
|
|
229
|
+
`OPA_UNREACHABLE`, since the HTTP client refuses such a URL. They are now
|
|
230
|
+
redacted wherever the URL is shown, and such a URL is refused with
|
|
231
|
+
`OPA_URL_INVALID` and a hint to use `OPA_TOKEN`.
|
|
232
|
+
Only the credentials are removed from the URL shown; its case, port and
|
|
233
|
+
path stay as the operator wrote them.
|
|
234
|
+
- `rego_verify` never gave the Z3 engine's memory back: its solver and
|
|
235
|
+
model were left to the JavaScript collector, which cannot see Z3's heap and
|
|
236
|
+
so had no reason to run, and the engine grew by half to one megabyte per
|
|
237
|
+
solve until its ceiling, between 600 MB and 1.7 GB over 1500 solves in the
|
|
238
|
+
same process depending on the run, with verdicts degrading to inconclusive
|
|
239
|
+
along the way. The solver is released as each solve ends, and its model
|
|
240
|
+
with it; 1500 solves now hold at about 210 MB.
|
|
241
|
+
- `rego_verify` could fault Z3 intermittently, which disabled verification
|
|
242
|
+
until the server restarted: z3-solver frees its objects from finalizers on
|
|
243
|
+
the main thread while a solve runs on a worker over the same shared
|
|
244
|
+
memory, and one landing mid-solve corrupted the heap. Finalizers are now
|
|
245
|
+
held while a solve runs, and a fault brings up a fresh Z3 on the next call,
|
|
246
|
+
three times per process, with the interrupted call retried once.
|
|
247
|
+
- The server reported itself as 0.4.0 on the 0.5.0 release, in the MCP
|
|
248
|
+
handshake, `mcp_server_info`, `--version` and the startup log: the version
|
|
249
|
+
was a constant kept apart from package.json. It is now read from
|
|
250
|
+
package.json, a test holds package.json, manifest.json and server.json to
|
|
251
|
+
one version, and a release stops before publishing when its tag names a
|
|
252
|
+
version package.json does not carry.
|
|
253
|
+
- The startup warning and hint for a missing `regal` named `rego_lint` alone;
|
|
254
|
+
`rego_security_audit` and `rego_fix` need it too, and the manifest, the
|
|
255
|
+
registry entry and the Smithery config say so now. `--help` lists
|
|
256
|
+
`OPA_MCP_BLOCK_ENV`. `conftest_verify` said an omitted `namespace` both
|
|
257
|
+
defaulted to `main` and verified all namespaces; it verifies all.
|
|
258
|
+
`rego_check_schema` and `rego_playground_share` describe the schema
|
|
259
|
+
directory form and the `public` field they already had.
|
|
260
|
+
|
|
261
|
+
## [0.5.0] - 2026-09-04
|
|
262
|
+
|
|
263
|
+
### Security
|
|
264
|
+
|
|
265
|
+
- `opa_config` described its output as sanitized with secrets excluded. OPA
|
|
266
|
+
drops the `credentials` block from `GET /v1/config` but returns
|
|
267
|
+
`services.*.headers` verbatim, and a header is the ordinary place to put an
|
|
268
|
+
API key or a bearer token for a bundle service, so a live credential was
|
|
269
|
+
handed to whatever agent called the tool. `opa_status` returns the same
|
|
270
|
+
document and had the same exposure. Header values are now replaced with a
|
|
271
|
+
marker and the header names kept, so the document still says what the server
|
|
272
|
+
is configured to send.
|
|
273
|
+
- `rego_verify` returned `proven` and `unsatisfiable` for claims that are false,
|
|
274
|
+
on ordinary policy shapes, and reported no unsupported constructs while doing
|
|
275
|
+
it, so nothing distinguished a real proof from a wrong one. A `proven` verdict
|
|
276
|
+
was not usable as evidence that a policy cannot be bypassed. Every released
|
|
277
|
+
version is affected. Five causes, each enough on its own: clauses whose head
|
|
278
|
+
shape the encoder does not support were dropped rather than reported, and a
|
|
279
|
+
rule with every clause dropped encoded to an empty body, which is vacuously
|
|
280
|
+
true; head values were discarded, so `allow := false if { ... }` was encoded as
|
|
281
|
+
though the head were true; `default` was not encoded at all, so
|
|
282
|
+
`default allow := true` with a non-matching body answered `never_true`; input
|
|
283
|
+
references were modelled as always present, so a body reading `input.x` was
|
|
284
|
+
treated as defined when `x` is absent; and locals were scoped by clause index
|
|
285
|
+
alone, so a helper and its caller sharing a variable name collapsed into one
|
|
286
|
+
symbol. Encoding now fails closed: a clause holding anything the encoder cannot
|
|
287
|
+
represent makes the verdict `inconclusive` rather than silently shrinking the
|
|
288
|
+
formula. That costs coverage, and about one generated policy in sixteen now
|
|
289
|
+
answers `inconclusive` where it previously gave a confident wrong answer.
|
|
290
|
+
Numbers encode as reals rather than integers, so `input.n > 0` with
|
|
291
|
+
`input.n < 1` is satisfiable at 0.5 instead of being falsely refuted.
|
|
292
|
+
Verification also ran without a mutex on the shared solver context.
|
|
293
|
+
- `conftest_test` joined the `inlineConfigParser` value into the temp file name
|
|
294
|
+
for inline config without checking it, so a value carrying `../` segments
|
|
295
|
+
placed the inline config, whose content the caller also chooses, at any path
|
|
296
|
+
the server could write. Parser names are now a closed set (conftest 0.69's
|
|
297
|
+
nineteen), enforced in the schema and again in the handler, and the parser is
|
|
298
|
+
passed to conftest explicitly rather than through the file name.
|
|
299
|
+
- Path validation followed links only for paths that already existed, so a
|
|
300
|
+
write destination that did not exist yet, such as an `opa_bundle_build` output
|
|
301
|
+
or a `conftest_pull` policy directory, was accepted on its spelling alone. A
|
|
302
|
+
junction or symbolic link inside an allowed root that pointed outside it made
|
|
303
|
+
such a write land outside the roots. A path is now judged by the real location
|
|
304
|
+
of its nearest existing ancestor with the missing segments re-attached, a
|
|
305
|
+
dangling link is refused, and roots and paths are compared in canonical form,
|
|
306
|
+
which also ends false rejections for a root spelled through a link (macOS
|
|
307
|
+
`/var`), a Windows short name, or a different letter case.
|
|
308
|
+
- `conftest_pull` and `conftest_push` skipped the allow-list entirely when
|
|
309
|
+
`policy` was omitted. Both tools document that the policy directory must sit
|
|
310
|
+
inside `OPA_MCP_ALLOWED_PATHS`, but the omitted case fell through to the
|
|
311
|
+
conftest default, resolved against the working directory of the server:
|
|
312
|
+
`conftest_pull` wrote policy files there, outside any allowed root. The
|
|
313
|
+
default is now resolved and checked like an explicit path, and refused with
|
|
314
|
+
`PATH_NOT_ALLOWED` when it falls outside.
|
|
315
|
+
- `opa_bundle_sign` wrote `.signatures.json` into the server's working directory,
|
|
316
|
+
outside `OPA_MCP_ALLOWED_PATHS`, and reported `signed: true` while the bundle it
|
|
317
|
+
was asked to sign stayed unsigned. `opa sign` puts the file wherever
|
|
318
|
+
`--output-file-path` says, that flag defaults to the process cwd, and it was
|
|
319
|
+
not being passed. A directory bundle is now signed in place and an archive
|
|
320
|
+
beside itself (or in `outputDir`), both validated like every other path the
|
|
321
|
+
server writes, and success is reported only after the file is observed on
|
|
322
|
+
disk. A `.signatures.json` already present as a symbolic link is refused
|
|
323
|
+
rather than written through. The response carries the path written, the
|
|
324
|
+
algorithm, and the number of files covered.
|
|
325
|
+
|
|
326
|
+
### Fixed
|
|
327
|
+
|
|
328
|
+
Results that were wrong without saying so:
|
|
329
|
+
|
|
330
|
+
- The five OPA data tools read a key containing a dot as two path segments and
|
|
331
|
+
returned a different document than the one asked for, with nothing to signal
|
|
332
|
+
the substitution. `opa_get_data` on `hosts/example.com` fetched
|
|
333
|
+
`/v1/data/hosts/example/com`; the same substitution applied to
|
|
334
|
+
`opa_put_data`, `opa_patch_data`, `opa_delete_data` and `opa_query_decision`,
|
|
335
|
+
so a write or a delete could land on the wrong document. A path containing a
|
|
336
|
+
slash now treats slash as its only separator, and a path without one is read
|
|
337
|
+
as dotted. Segments are percent-encoded: a key holding `?` or `#` truncated
|
|
338
|
+
the request URL at that character and read the parent document, and keys
|
|
339
|
+
holding a space, a percent sign or non-ASCII characters were unreachable.
|
|
340
|
+
- `opa_patch_data` documented an empty path for patching the root of the data
|
|
341
|
+
hierarchy, but the schema required at least one character and the path it
|
|
342
|
+
built for the root is one OPA answers with a redirect. Omitting both `path`
|
|
343
|
+
and `segments` now patches the root.
|
|
344
|
+
- `opa_exec` did not evaluate the rule it was asked for. Its `decision`
|
|
345
|
+
description told callers to pass a fully-qualified Rego reference such as
|
|
346
|
+
`data.authz.allow`, but `opa exec --decision` names a decision by
|
|
347
|
+
slash-separated path with no `data.` prefix. Any other spelling is accepted by
|
|
348
|
+
the flag and resolves to nothing, so every input file came back with
|
|
349
|
+
`opa_undefined_error`, which under a `deny`-style policy reads as a clean
|
|
350
|
+
pass. Both spellings are now converted to the path OPA expects, and a
|
|
351
|
+
reference with nothing left to name is rejected as `INVALID_INPUT`.
|
|
352
|
+
- `rego_test` and `rego_test_multiroot` counted a test OPA could not evaluate as
|
|
353
|
+
a passing test. OPA marks such a record with an `error` object and does not set
|
|
354
|
+
`fail`, so deriving the pass count as `total - failed - skipped` absorbed it,
|
|
355
|
+
and a suite whose tests all raised (a rule conflict, for instance) was reported
|
|
356
|
+
as fully passing with zero failures. Both tools now report `errored`
|
|
357
|
+
separately, and the multiroot aggregate carries `totalErrored`.
|
|
358
|
+
- Windows: a data document passed by absolute path was loaded under its drive
|
|
359
|
+
letter instead of where the policy expected it. OPA reads every load path as
|
|
360
|
+
an optional `prefix:path` pair and splits on the first colon, so
|
|
361
|
+
`C:\policies\data.json` mounted at `data.C` and a rule reading `data.tier`
|
|
362
|
+
found nothing, while the tool reported success. `opa test` on a suite whose
|
|
363
|
+
tests read data reported those tests as failing. Load paths are now passed
|
|
364
|
+
relative to a directory the `opa` process runs in, which is the only spelling
|
|
365
|
+
OPA reads correctly. Rego modules are unaffected either way, because a module
|
|
366
|
+
mounts at its own `package` rather than at its path, which is why policies
|
|
367
|
+
worked and only their data did not. Nothing changes on macOS or Linux, whose
|
|
368
|
+
absolute paths carry no drive letter. Load paths spanning two drives are now
|
|
369
|
+
reported as an error, since OPA cannot load documents from two drives in one
|
|
370
|
+
invocation.
|
|
371
|
+
- The ABAC example in the `opa://patterns` resource failed to evaluate on the
|
|
372
|
+
case it exists to handle. It expressed "hide secret resources from other
|
|
373
|
+
organizations" as a second rule assigning `allow := false`, which in Rego is a
|
|
374
|
+
conflict rather than an override: a user reading their own secret resource
|
|
375
|
+
from another organization got `eval_conflict_error` instead of a denial. The
|
|
376
|
+
denial is now a condition the permissive rules consult. The pitfalls list,
|
|
377
|
+
which recommended the broken form, says why it does not work.
|
|
378
|
+
- The Terraform example in the `opa://patterns` resource did not reject a
|
|
379
|
+
full-admin IAM policy. It tested `"*" in statement.Action`, which requires
|
|
380
|
+
`Action` to be a collection, and AWS accepts a bare string there, in
|
|
381
|
+
`Resource`, and for `Statement` itself. Of the four ways to spell
|
|
382
|
+
`Allow * on *`, the rule caught one; the most common form,
|
|
383
|
+
`{"Action": "*", "Resource": "*"}`, was allowed. Each position is now widened
|
|
384
|
+
to a set before the wildcard test. Scoped policies and `Deny` statements are
|
|
385
|
+
still allowed, so the rule has not become indiscriminate.
|
|
386
|
+
- `rego_test` with `coverage` or `threshold` reported `One or more tests
|
|
387
|
+
failed` for a suite where none did. A suite holding a `todo_` test exits
|
|
388
|
+
non-zero under `--coverage` with an empty stderr, and the coverage report is
|
|
389
|
+
on stdout as asked for. The report was discarded and the run called a
|
|
390
|
+
failure. A non-zero exit with a parseable report and no failure lines is now
|
|
391
|
+
the coverage result it is, and a report OPA did produce is kept in the error
|
|
392
|
+
details when tests really did fail.
|
|
393
|
+
- `rego_coverage_gaps` reported `testsPassed`, `testsFailed` and
|
|
394
|
+
`testsSkipped` as zero on every call. OPA emits no per-test records in
|
|
395
|
+
coverage mode, so the three counts could never be anything else, and three
|
|
396
|
+
zeros read as "no tests ran" rather than "not reported". They are now
|
|
397
|
+
omitted unless OPA supplied records.
|
|
398
|
+
- `opa_health` reported a reachable server as `OPA_UNREACHABLE`. A server that
|
|
399
|
+
answers `/health?bundles=true` with `one or more bundles are not activated`
|
|
400
|
+
is running; the caller was told no server was found and to go start one, and
|
|
401
|
+
OPA's own reason was buried in a stringified error. Such a response is now a
|
|
402
|
+
result, `healthy: false` with `reason`. A 401 maps to `OPA_AUTH_FAILED`, and
|
|
403
|
+
`OPA_UNREACHABLE` is left for a server that could not be reached.
|
|
404
|
+
|
|
405
|
+
Tools that did not work as documented:
|
|
406
|
+
|
|
407
|
+
- `opa_bundle_verify` passed `--verification-key` to `opa eval`, which has no
|
|
408
|
+
such flag, so verification always failed with "unknown flag" and was reported
|
|
409
|
+
as `INVALID_BUNDLE`, signed or not. Verification now runs through
|
|
410
|
+
`opa build --verification-key` into a discarded temp file, which is the path
|
|
411
|
+
OPA provides. Failures carry `details.reason`: `signature_invalid`,
|
|
412
|
+
`scope_mismatch`, `file_modified`, `file_added`, `file_missing`,
|
|
413
|
+
`file_unparseable`, `unsigned`, `signatures_malformed`, `not_a_bundle`,
|
|
414
|
+
`bundle_load_error`, or `unknown` when OPA's message is not recognised. A key
|
|
415
|
+
or algorithm OPA cannot use is reported as `INVALID_INPUT` by both tools.
|
|
416
|
+
- Directory bundles are signed and verified by name from the parent directory,
|
|
417
|
+
the way `opa sign --bundle <name>` records them, so a signed directory stays
|
|
418
|
+
valid wherever it is placed under that name and a directory signed with the
|
|
419
|
+
OPA CLI verifies. A symbolic link or junction given as the bundle is resolved
|
|
420
|
+
first; OPA does not descend a linked root and would sign an empty file list.
|
|
421
|
+
- `opa_bundle_build` passed `--signing-key` and `--verification-key` without
|
|
422
|
+
`--bundle`, which `opa build` refuses, so neither option worked unless
|
|
423
|
+
`bundle: true` was also set. Either option now implies bundle mode.
|
|
424
|
+
- `opa_bundle_sign` returned an empty `stderr` on failure because `opa sign`
|
|
425
|
+
prints its errors on stdout. `details` now carries both streams.
|
|
426
|
+
- `conftest_test` and `conftest_verify` threw `UNKNOWN_ERROR` on every clean run.
|
|
427
|
+
conftest omits every empty array from its JSON, so a passing file arrives with
|
|
428
|
+
no `failures` key and the summary code dereferenced it. Results now always
|
|
429
|
+
carry their arrays, `conftest_verify` reports `NO_TESTS_FOUND` for a policy
|
|
430
|
+
directory with no test rules (conftest prints `null` there), and both
|
|
431
|
+
summaries count files by name, since conftest emits one entry per namespace
|
|
432
|
+
or per test rule. `summary.successes` and `summary.failures` are added to
|
|
433
|
+
`conftest_test`. `exceptions` are messages, not strings, matching conftest.
|
|
434
|
+
- `conftest_pull` did not write to the directory it was given. Conftest resolves
|
|
435
|
+
`--policy` against the working directory rather than honouring an absolute
|
|
436
|
+
path, and the tool resolves the caller's path against the allow-list before
|
|
437
|
+
handing it over, so the path was always absolute. On Windows the pull failed
|
|
438
|
+
outright, reporting a path of the form `.\C:\...`. `conftest_push` had the
|
|
439
|
+
same handling and read from the same path on whichever drive it happened to
|
|
440
|
+
start on. Both now run from the parent directory and name the target
|
|
441
|
+
relatively.
|
|
442
|
+
- `rego_test` with `count` above 1 reported the suite as having no tests. OPA
|
|
443
|
+
prints one pretty-printed JSON array per repetition, back to back, which is
|
|
444
|
+
neither a single JSON value nor one record per line, so nothing parsed and the
|
|
445
|
+
tool returned `NO_TESTS_FOUND` for a suite that had just run. The repetitions
|
|
446
|
+
are now read and collapsed to one record per test carrying its worst outcome,
|
|
447
|
+
so a test that fails intermittently is reported as failing.
|
|
448
|
+
- `rego_test` did not populate `parameterizedGroups`. OPA reports a
|
|
449
|
+
`test_x[case]` rule as a single record carrying the per-case outcomes in
|
|
450
|
+
`sub_results`, not as one record per case, so looking for a bracketed test
|
|
451
|
+
name found nothing on any OPA 1.x run. A rule whose cases mostly passed was
|
|
452
|
+
reported as one failing test with no indication of which case failed. The
|
|
453
|
+
cases are now grouped under the rule name, and the bracketed form older
|
|
454
|
+
versions emitted is still read.
|
|
455
|
+
- `rego_bench` failed with `UNKNOWN_ERROR` for any `count` above 1. OPA prints
|
|
456
|
+
one JSON document per repetition, back to back, which is not a single JSON
|
|
457
|
+
value, so nothing parsed. Every repetition is now returned in `runs`, and the
|
|
458
|
+
top-level figures come from the fastest of them per iteration.
|
|
459
|
+
- `rego_bench` reported a failed benchmark with an empty error. `opa bench
|
|
460
|
+
--format=json` writes its diagnostics to stdout as an `errors` array and
|
|
461
|
+
leaves stderr empty, and the tool reported only stderr, so a query with a
|
|
462
|
+
syntax error came back as `EVAL_ERROR` with nothing in it. The diagnostics
|
|
463
|
+
are now included.
|
|
464
|
+
- `opa_list_policies` returned nothing but a truncation notice on a server
|
|
465
|
+
holding more than a couple of dozen policies. OPA answers the policy
|
|
466
|
+
endpoints with each policy's parsed AST alongside its source, and the AST is
|
|
467
|
+
far larger than the text it came from, so the response passed
|
|
468
|
+
`OPA_MCP_MAX_RESPONSE_BYTES` and the payload was replaced with advice to
|
|
469
|
+
narrow the scope. The tool took no arguments, so there was no scope to
|
|
470
|
+
narrow. It now returns the policy IDs and a count, with `includeSource` and
|
|
471
|
+
`includeAst` to ask for more.
|
|
472
|
+
- `opa_get_policy` returned the AST alongside the source, which nothing had
|
|
473
|
+
asked for: a 477-byte policy came back as a 19 KB response. The AST is now
|
|
474
|
+
behind `includeAst`.
|
|
475
|
+
- The server did nothing when it was reached through a symbolic link. Its
|
|
476
|
+
entry-point check compared `import.meta.url` with `process.argv[1]` as
|
|
477
|
+
strings, and Node resolves symlinks for a module's own URL while leaving
|
|
478
|
+
`argv[1]` as it was invoked, so the two differed and neither the CLI flags nor
|
|
479
|
+
the transport ran: the process started and exited in silence. npm's `bin`
|
|
480
|
+
entry is a symlink on macOS and Linux. The comparison is now between real
|
|
481
|
+
paths, so how the file was reached no longer matters.
|
|
482
|
+
- `rego_explain_undefined` had nothing to say about a policy written with
|
|
483
|
+
`default allow := false`. A default gives the query a value, so it is never
|
|
484
|
+
undefined and the tool returned that value and stopped, skipping the
|
|
485
|
+
per-clause analysis it exists for. A query whose value came from a default
|
|
486
|
+
and from nothing else is now analysed, and `queryResult` reports `default`.
|
|
487
|
+
- Clauses of a multi-clause rule were not told apart in the trace. OPA leaves
|
|
488
|
+
`Node.location` unset on trace events, so the row comparison meant to
|
|
489
|
+
distinguish them always fell through to matching on the rule name, and every
|
|
490
|
+
clause looked present in the trace as soon as one was. Those clauses were
|
|
491
|
+
never evaluated standalone: each came back with every condition
|
|
492
|
+
`unevaluable` and no blocking condition. The event's own location is now
|
|
493
|
+
used.
|
|
494
|
+
- `rego_lint`, `rego_fix` and `rego_security_audit` ignored the linted project's
|
|
495
|
+
own `.regal/config.yaml`, and applied any configuration sitting above the
|
|
496
|
+
server's working directory to every call instead. Regal discovers its
|
|
497
|
+
configuration by walking up from its own working directory rather than from
|
|
498
|
+
the files it is given, and it was spawned without one, so it inherited the
|
|
499
|
+
server's, which for a stdio server is wherever the client launched it. Rules a
|
|
500
|
+
project had turned off were reported anyway, and inline source, which belongs
|
|
501
|
+
to no project, picked up whatever happened to be above the server. Regal now
|
|
502
|
+
runs in the directory of what it is linting, and inline source runs in its own
|
|
503
|
+
temp directory. An explicit `configFile` still takes precedence.
|
|
504
|
+
|
|
505
|
+
Configuration and environment:
|
|
506
|
+
|
|
507
|
+
- An empty or blank environment variable was treated as a real value.
|
|
508
|
+
`OPA_BINARY=""`, which is what a shell leaves behind when it expands an
|
|
509
|
+
unset variable, is not the literal default `opa`, so binary resolution
|
|
510
|
+
skipped the bundled build and every `rego_*` call tried to spawn nothing.
|
|
511
|
+
Blank now means unset for every variable the server reads, and values are
|
|
512
|
+
trimmed.
|
|
513
|
+
- `OPA_MCP_TIMEOUT_MS` and `OPA_MCP_HTTP_TIMEOUT_MS` accepted values Node
|
|
514
|
+
cannot represent. A timer of 2147483648 ms or more is clamped to 1 ms with
|
|
515
|
+
only a process warning, so a large value set to mean "effectively no
|
|
516
|
+
timeout" timed out every subprocess and every HTTP call immediately. Values
|
|
517
|
+
above 2147483647 are now refused at startup with a message saying why.
|
|
518
|
+
- An `install-id` file that existed but held no id was a permanent trap. The
|
|
519
|
+
read found no id, the exclusive create failed because the file was there, and
|
|
520
|
+
the fallback read found no id again, on every run for the life of the machine.
|
|
521
|
+
The file is now rewritten when it holds no usable id; a brand-new file is
|
|
522
|
+
still created exclusively so two first runs cannot both claim it. A file can
|
|
523
|
+
end up empty after a crash or a full disk during the first run.
|
|
524
|
+
- The test suites no longer emit telemetry pings.
|
|
525
|
+
|
|
526
|
+
### Added
|
|
527
|
+
|
|
528
|
+
- `opa_bundle_sign` accepts `outputDir` for archives, the directory that
|
|
529
|
+
receives `.signatures.json`. A directory bundle is always signed in place,
|
|
530
|
+
since OPA only reads the signature from inside the bundle.
|
|
531
|
+
- `opa_bundle_verify` accepts `v0Compatible` for bundles written in Rego v0,
|
|
532
|
+
which otherwise fail to load after the signature has been checked.
|
|
533
|
+
- The five OPA data tools accept `segments`, an array of literal key segments,
|
|
534
|
+
for keys that contain both a dot and a slash and so cannot be written as a
|
|
535
|
+
path string. `opa_put_data`, `opa_patch_data` and `opa_delete_data` return the
|
|
536
|
+
resolved `segments` alongside the `path` that was supplied.
|
|
537
|
+
- `opa_exec` output gains `hint`, present when every input left the decision
|
|
538
|
+
undefined. That is the expected outcome when no rule matched and also what a
|
|
539
|
+
decision naming nothing looks like, and the per-file results do not
|
|
540
|
+
distinguish them.
|
|
541
|
+
- `OPA_MCP_BLOCK_ENV` withholds named variables from `opa`, `regal` and
|
|
542
|
+
`conftest` even when they are on the built-in allow-list. It is applied last,
|
|
543
|
+
so it also overrides `OPA_MCP_PASSTHROUGH_ENV` and anything a command passes
|
|
544
|
+
explicitly. It exists so an operator behind an authenticated proxy can choose
|
|
545
|
+
to lose proxy support rather than expose those credentials to evaluated
|
|
546
|
+
policy.
|
|
547
|
+
|
|
548
|
+
### Changed
|
|
549
|
+
|
|
550
|
+
- `rego_test` output gains `errored`, `repetitions` (present only when more
|
|
551
|
+
than one repetition ran; OPA stops repeating at the first run that fails, so
|
|
552
|
+
this can be lower than the requested `count`) and `caseCounts` (present only
|
|
553
|
+
when the run had a parameterized test; the top-level counts still follow OPA
|
|
554
|
+
and treat such a rule as one test however many cases it holds).
|
|
555
|
+
`rego_test_multiroot` gains `errored` per root and `totalErrored` overall.
|
|
556
|
+
- `opa_list_policies` output gains `count`.
|
|
557
|
+
- `rego_explain_undefined` output: `queryResult` gains `default`, and `value`
|
|
558
|
+
is populated for it. On a query that is genuinely defined the tool now also
|
|
559
|
+
runs `opa parse`, which is how it tells a default apart from a rule that
|
|
560
|
+
matched.
|
|
561
|
+
- `OPA_MCP_ALLOWED_PATHS` now refuses a relative entry, as documented. A
|
|
562
|
+
relative root was resolved against the server's working directory, so for a
|
|
563
|
+
stdio server the same configuration permitted different directories depending
|
|
564
|
+
on how the client launched it.
|
|
565
|
+
- `opa-mcp --help` lists `OPA_MCP_MAX_SUBPROCESS_BYTES`,
|
|
566
|
+
`OPA_MCP_PASSTHROUGH_ENV` and `OPA_MCP_NO_TELEMETRY`, which were documented
|
|
567
|
+
but absent from the output an invalid-configuration message points at.
|
|
568
|
+
- The 0.4.0 entry below, the README and the source comment all described the
|
|
569
|
+
child-process allow-list as containing no secret. It carries no cloud or
|
|
570
|
+
repository credential, but `HTTP_PROXY`, `HTTPS_PROXY` and `ALL_PROXY` are on
|
|
571
|
+
it and a proxy URL can embed a username and password, which any evaluated
|
|
572
|
+
policy can read through `opa.runtime().env`. All three now say so. No
|
|
573
|
+
behaviour changed; the exposure was there in 0.4.0 as shipped and is
|
|
574
|
+
unchanged by this correction.
|
|
575
|
+
- Documentation corrected where it did not match the tools: `opa_status`
|
|
576
|
+
returns `GET /v1/config`, not bundle or decision-log status;
|
|
577
|
+
`rego_describe_policy` does not report input references, so the two prompts
|
|
578
|
+
that told the model to use it for that now name `rego_infer_input_schema`;
|
|
579
|
+
`rego_lint` returns a flat list of violations rather than findings grouped by
|
|
580
|
+
category; `rego_capabilities` reflects the resolved `opa` binary rather than
|
|
581
|
+
the bundled one; `rego_explain_decision` returns a structured summary rather
|
|
582
|
+
than a natural-language explanation, and the extension manifest no longer
|
|
583
|
+
says the helper tools use AI; the MCPB bundle has no bundled-binary fallback;
|
|
584
|
+
unit tests run on macOS only on Node 22.
|
|
585
|
+
- Four error codes that nothing returns are no longer listed as codes a caller
|
|
586
|
+
can expect: `REGAL_VERSION_TOO_OLD`, `DEPENDENCY_CONFLICT`,
|
|
587
|
+
`VERIFY_INCONCLUSIVE` and `Z3_INIT_ERROR`. They remain reserved in the type.
|
|
588
|
+
The troubleshooting entry for a Regal minimum-version check that does not
|
|
589
|
+
exist is removed.
|
|
590
|
+
|
|
20
591
|
## [0.4.0] - 2026-09-03
|
|
21
592
|
|
|
22
593
|
### Security
|
|
@@ -29,9 +600,15 @@ not part of the public surface and may change in minor releases.
|
|
|
29
600
|
`rego_eval` accepts inline source, so `OPA_MCP_ALLOWED_PATHS` never applied and no
|
|
30
601
|
filesystem access was needed; a policy arriving through a README, an issue, or a
|
|
31
602
|
diff was enough. `conftest_test` was affected the same way, and is the likelier
|
|
32
|
-
route to third-party policy. Children now get an explicit allow-list
|
|
33
|
-
|
|
34
|
-
|
|
603
|
+
route to third-party policy. Children now get an explicit allow-list.
|
|
604
|
+
`OPA_MCP_PASSTHROUGH_ENV` opts individual variables back in, and anything named
|
|
605
|
+
there is readable by evaluated policy by design.
|
|
606
|
+
|
|
607
|
+
The allow-list carries no cloud or repository token, but it is not free of
|
|
608
|
+
credentials: `HTTP_PROXY`, `HTTPS_PROXY` and `ALL_PROXY` are on it, and a proxy
|
|
609
|
+
URL can embed a username and password, so an operator behind an authenticated
|
|
610
|
+
corporate proxy is still handing those to evaluated policy. They are on the list
|
|
611
|
+
because dropping them breaks proxied bundle downloads and `http.send`.
|
|
35
612
|
|
|
36
613
|
On Windows, libuv copies a fixed set of variables to every child regardless of what
|
|
37
614
|
is requested. `USERNAME`, `USERDOMAIN` and `LOGONSERVER` cannot be removed, so they
|
|
@@ -1028,7 +1605,9 @@ wrappers end-to-end. CI matrix: Ubuntu, macOS, and Windows on Node
|
|
|
1028
1605
|
20 and 22, plus CodeQL security scanning and weekly Dependabot updates
|
|
1029
1606
|
for npm, GitHub Actions, and Docker base images.
|
|
1030
1607
|
|
|
1031
|
-
[Unreleased]: https://github.com/OrygnsCode/opa-mcp-server/compare/v0.
|
|
1608
|
+
[Unreleased]: https://github.com/OrygnsCode/opa-mcp-server/compare/v0.6.0...HEAD
|
|
1609
|
+
[0.6.0]: https://github.com/OrygnsCode/opa-mcp-server/compare/v0.5.0...v0.6.0
|
|
1610
|
+
[0.5.0]: https://github.com/OrygnsCode/opa-mcp-server/compare/v0.4.0...v0.5.0
|
|
1032
1611
|
[0.4.0]: https://github.com/OrygnsCode/opa-mcp-server/compare/v0.3.0...v0.4.0
|
|
1033
1612
|
[0.3.0]: https://github.com/OrygnsCode/opa-mcp-server/compare/v0.2.1...v0.3.0
|
|
1034
1613
|
[0.2.1]: https://github.com/OrygnsCode/opa-mcp-server/compare/v0.2.0...v0.2.1
|