v0.45.0
This release contains a mix of bugfixes, optimizations, and new features.
Improved Decision Logging with nd_builtin_cache
OPA has several non-deterministic built-ins, such as rand.intn
and http.send
that can make debugging policies from decision log results a surprisingly tricky and involved process. To improve the situation around debugging policies that use those built-ins, OPA now provides an opt-in system for caching the inputs and outputs of these built-ins during policy evaluation, and can include this information in decision log entries.
A new top-level config key is used to enable the non-deterministic builtin caching feature, as shown below:
nd_builtin_cache: true
This data is exposed to OPA's decision log masking system under the /nd_builtin_cache
path, which allows masking or dropping sensitive values from decision logs selectively. This can be useful in situations where only some information about a non-deterministic built-in was needed, or the arguments to the built-in involved sensitive data.
To prevent unexpected decision log size growth from non-deterministic built-ins like http.send
, the new cache information is included in decision logs on a best-effort basis. If a decision log event exceeds the decision_logs.reporting.upload_size_limit_bytes
limit for an OPA instance, OPA will reattempt uploading it, after dropping the non-deterministic builtin cache information from the event. This behavior will trigger a log error when it happens, and will increment the decision_logs_nd_builtin_cache_dropped
metrics counter, so that it will be possible to debug cases where the cache information is unexpectedly missing from a decision log entry.
Decision Logging Example
To observe the change in decision logging we can run OPA in server mode with nd_builtin_cache
enabled:
opa run -s --set=decision_logs.console=true,nd_builtin_cache=true
After sending it the query x := rand.intn("a", 15)
we should see something like the following in the decision logs:
{..., "msg":"Decision Log", "nd_builtin_cache":{"rand.intn":{"[\"a\",15]":3}}, "query":"assign(x, rand.intn(\"a\", 15))", ..., "result":[{"x":3}], ..., "type":"openpolicyagent.org/decision_logs"}
The new information is included under the optional nd_builtin_cache
JSON key, and shows what arguments were provided for each unique invocation of rand.intn
, as well as what the output of that builtin call was (in this case, 3
).
If we send the query x := rand.intn("a", 15); y := rand.intn("b", 150)"
we can see how unique input arguments get recorded in the cache:
{..., "msg":"Decision Log", "nd_builtin_cache":{"rand.intn":{"[\"a\",15]":12,"[\"b\",150]":149}}, "query":"assign(x, rand.intn(\"a\", 15)); assign(y, rand.intn(\"b\", 150))", ..., "result":[{"x":12,"y":149}], ..., "type":"openpolicyagent.org/decision_logs"}
With this information, it's now easier to debug exactly why a particular rule is used or why a rule fails when non-deterministic builtins are used in a policy.
New Built-in Function: regex.replace
This release introduces a new builtin for regex-based search/replace on strings: regex.replace
.
See the built-in functions docs for all the details
This implementation fixes #5162 and was authored by @boranx
.
object.union_n
Optimization
The object.union_n
builtin allows easily merging together an array of Objects.
... (truncated)