81 Commits

Author SHA1 Message Date
Ville Vesilehto f77322b3fb build: bump Go version requirement to 1.24 (#7839)
Go 1.23 is no longer supported as per Go release policy.

Changes:

- Use Go v1.24.6 as the project SDK requirement
- Apply lint fixes for Go 1.24
- Fix "non-constant format string in call" issues as seen in CI.

Signed-off-by: Ville Vesilehto <ville@vesilehto.fi>
2025-08-24 09:02:09 +02:00
Anders Eknert e43ef0a979 Use any in place of interface{} (#7566)
Earlier this evening I tried to run the Go
[modernize](https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/modernize)
analyzer on OPA. That didn't go as planned:

- https://github.com/golang/go/issues/73661
- https://github.com/golang/go/issues/73663

While we wait for that to be fixed, I figured an old-fashioned
search-and-replace across the repo may work for at least the
`interface{}` to `any` conversion. That should help make it easier
to see the other fixes as applied by the modernize tool once it has
had those issues resolved.

Signed-off-by: Anders Eknert <anders@styra.com>
2025-05-12 13:57:48 +02:00
Johan Fylling a179a24c48 v1 API
All packages, except for `cmd` and `internal`, have been moved into a new `v1` root package.

Old packages are kept for backwards-compatibility reasons. All contained code is replaced with simple type aliases and proxy functions to `v1` implementations.

Old packages default to the Rego v0 syntax, new `v1` packages default to the Rego v1 syntax.

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2024-12-12 15:27:34 +01:00
Johan Fylling 7bb6dbe36b Preparing for v1 API
Moving (most) source to v1 root package to prepare for v0/v1 API separation.

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2024-12-12 15:09:03 +01:00
Michael Chittenden a241c8716b Update eval_cancel_error logic to separate canceled, timeout errors (#7202)
This changes the `eval_cancel_error` logic to differentiate between
context.Canceled and context.DeadlineExceeded errors, because they are
distinct errors. By differentiating here, callers will be able to
determine if a call was stopped because a caller stopped the request, or
because the request went over some imposed deadline.

Signed-off-by: Mike Chittenden <mchittenden@digitalocean.com>
2024-12-03 10:44:17 +01:00
Ashutosh Narkar 2c56293695 Add a new inter-query value cache to cache data across queries
This commit adds a new inter-query value cache that built-in
functions can use to cache information across queries.
For example, the `regex` and `glob` builtins can use this
to cache compiled regex and glob match patterns respectively.

The number of entries in the cache can be configured via the OPA
config. By default there is no limit.

Fixes: #6908

Signed-off-by: Ashutosh Narkar <anarkar4387@gmail.com>
2024-09-23 13:03:03 -07:00
Johan Fylling c39673bfb0 rego-v1: Future-proofing rego package tests to be 1.0 compatible (#7022)
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2024-09-18 13:27:37 +02:00
Johan Fylling 7cd3fecae7 ast: Make Module.String() include if/contains for v1 modules (#7000)
Fixes: #6973
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2024-09-06 15:09:02 +02:00
Johan Fylling 5464b005e8 Bumping golangci-lint to v1.59.1 (#6817)
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2024-06-19 15:13:43 +02:00
Johan Fylling 38c2f0c5e0 Adding --v1-compatible flag to build, opa eval (#6478)
* ast+cmd+rego: Adding `--rego-v1` flag to `opa eval`

Fixes: #6463
Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Adding `--rego-v1` flag to `opa build`

Fixes: #6463
Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Formatting PE support modules to comply with rego-v1 when required

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Removing rego.v1 import when formatting for rego-v1 (not rego-v0-compat-v1)

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* touch up

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Fixing linting issues

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Consolidating `Bundle.FormatModules()` and `Bundle.FormatModulesForRegoVersion()`

Suggested by @ashutosh-narkar

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Adding descriptions to `RegoVersion`

Requested by @ashutosh-narkar

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Using `--v1-compatible` flag instead of `--rego-v1`

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Updating docs

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Reintroducing `ParserOptions.RegoV1Compatible` to avoid breaking change

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* cmd & tester

Adding `--v1-compatible` flag to `opa test`

Fixes: #6463
Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Adding `--v1-compatible` flag to `opa fmt`

Fixes: #6463
Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Adding `--v1-compatible` flag to `opa check`

Fixes: #6463
Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Making linter happy

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Review modifications suggested by @ashutosh-narkar

* Changing `ParserOptions.RegoV1Compatible` take precedence over `ParserOptions.RegoVersion`
* Fixing comment in test
* Updating `fmt --rego-v1` CLI description

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Review modifications suggested by @ashutosh-narkar

* Changing `ParserOptions.RegoV1Compatible` take precedence over `ParserOptions.RegoVersion`
* Fixing comment in test
* Updating `fmt --rego-v1` CLI description
* Adding back `Opts.RegoV1` and deprecating.
  * Making `Opts.RegoV1` take precedence over `Opts.RegoVersion`

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Review modifications suggested by @ashutosh-narkar

* Changing `ParserOptions.RegoV1Compatible` take precedence over `ParserOptions.RegoVersion`
* Fixing comment in test
* Updating `fmt --rego-v1` CLI description
* Adding back `Opts.RegoV1` and deprecating.
  * Making `Opts.RegoV1` take precedence over `Opts.RegoVersion`
* `TestPartialWitRegoV1` -> `TestPartialWithRegoV1`

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Review modifications suggested by @ashutosh-narkar

* Changing `ParserOptions.RegoV1Compatible` take precedence over `ParserOptions.RegoVersion`
* Fixing comment in test
* Updating `fmt --rego-v1` CLI description
* Adding back `Opts.RegoV1` and deprecating.
  * Making `Opts.RegoV1` take precedence over `Opts.RegoVersion`
* `TestPartialWitRegoV1` -> `TestPartialWithRegoV1`
* removing `Println` in test

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

* Review modifications suggested by @ashutosh-narkar

* Changing `ParserOptions.RegoV1Compatible` take precedence over `ParserOptions.RegoVersion`
* Fixing comment in test
* Updating `fmt --rego-v1` CLI description
* Adding back `Opts.RegoV1` and deprecating.
  * Making `Opts.RegoV1` take precedence over `Opts.RegoVersion`
* `TestPartialWitRegoV1` -> `TestPartialWithRegoV1`
* removing `Println` in test
* Updating docs with per-command behavioural descriptions for `--v1-compatible`.

Signed-off-by: Johan Fylling <johan.dev@fylling.se>

---------

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2023-12-20 10:59:14 +01:00
Luiz Carvalho 2eba2e66fc Propagate description of custom builtins (#6451)
This allows processes, such as doc generation, to have additional
information about custom builtin functions.

Fixes: #6449

Signed-off-by: Luiz Carvalho <lucarval@redhat.com>
2023-12-05 10:05:00 +00:00
Johan Fylling d38a4f1b07 Moving wasm test (#6399)
to not fail when running `make test`.

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2023-11-10 14:11:28 +01:00
Stephan Renatus 544fd0329d ast+rego: disable compiler stages for IR-based eval paths (#6335)
Only topdown can make sense of rules and comprehension indices, so Wasm and any
eval plugins should instruct the compiler to avoid that work.

Signed-off-by: Stephan Renatus <stephan@styra.com>
2023-10-24 17:52:07 +02:00
Stephan Renatus 6f543ae5e0 rego: allow for extending the rego targets with plugins (#5939)
The handoff point for plugins right now is the IR: that, the store, and
the open transaction is passed to `PrepareForEval`.

Rego target plugins  aren't plugged in through the plugin manager
machinery, and they don't need to be enabled via configs. They are
more akin to custom builtins, which also become available right
away after having been registered with the ast package.

In the future, another option would be to pass the Wasm bytes: we could
then have a wasmtime-based plugin, and a wazero-based one.

* rego.EvalContext: expose a few fields

* ()*Rego).Compile() is only used by our wasm tests, and doesn't even make
  sense for the "rego" target. Not added to the plugin interface.

* In rego.New, we now only gather plugins once, and have the plugins decide if
  a target is for them or not. This untangles the plugin name from the target
  matching; a plugin can have any name it wants now.

Signed-off-by: Stephan Renatus <stephan@styra.com>
2023-05-24 09:07:14 +02:00
Ashutosh Narkar 1ec047c063 ast: Set result of groundness check on indexer's AllRules func
We perform groundness checks at index creation time and then
include result of that in the indexer's result. Previously we
did not set this value on the indexer's AllRules call as a
result of which rule evaluation for complete rules would get skipped.
This change updates the indexer's AllRules call to include the
result of the groundness checks.

Fixes: #5857

Signed-off-by: Ashutosh Narkar <anarkar4387@gmail.com>
2023-04-25 22:58:05 -07:00
teselil 845652e115 rego: Fix printing duplication when parse errors length is 1
Signed-off-by: teselil <tzlil@datree.com>
2023-04-17 16:16:21 -07:00
Charlie Egan ac64e78c69 topdown/rego: Add BuiltinErrorList support to rego package, add to eval command (#5487)
```
$ cat pol.rego
package play

this_errors(number) := result {
        result := number / 0
}

this_errors_too(number) := result {
        result := number / 0
}

res1 := this_errors(1)

res2 := this_errors_too(1)

$ go run main.go eval --show-builtin-errors -d pol.rego data.play
{
  "errors": [
    {
      "message": "div: divide by zero",
      "code": "eval_builtin_error",
      "location": {
        "file": "pol.rego",
        "row": 4,
        "col": 12
      }
    },
    {
      "message": "div: divide by zero",
      "code": "eval_builtin_error",
      "location": {
        "file": "pol.rego",
        "row": 8,
        "col": 12
      }
    }
  ],
  "result": [
    {
      "expressions": [
        {
          "value": {},
          "text": "data.play",
          "location": {
            "row": 1,
            "col": 1
          }
        }
      ]
    }
  ]
}
```

Signed-off-by: Charlie Egan <charlieegan3@users.noreply.github.com>
2023-01-03 13:25:49 +00:00
Stephan Renatus 09dd80b3d2 topdown+ast+rego: read lazy objects from the store (#5380)
Before, any call to a builtin that would reference an object from data would force that
the entire object was transformed to an ast.Value, and a copy of it was passed to the builtin.

Now, we're doing something a little more involved: when an object is read from data, we'll
wrap it into a special container and don't convert it. The conversion only happens when it's
required. As such, we can avoid quite a bit of memory usage, and avoiding the extra work,
make evaluations faster.

Lazy objects are also immutable -- calling Insert() on them will panic. But based on how
topdown works, it should never happen. Only Golang coding modifying the results of a query
evaluation could be affected by this. If you are, see the opt-out mechanisms outlined below.

⚠️ The benchmark that follows is an edge case, but the issue at hand here has come up in
the real world before.

    name                         old time/op    new time/op    delta
    MemberWithKeyFromBaseDoc-16    40.2ms ±13%     0.0ms ± 5%  -99.97%  (p=0.000 n=9+10)
    ObjectGetFromBaseDoc-16        42.4ms ± 4%     0.0ms ± 2%  -99.97%  (p=0.000 n=9+10)

    name                         old alloc/op   new alloc/op   delta
    MemberWithKeyFromBaseDoc-16    17.2MB ± 0%     0.0MB ± 0%  -99.96%  (p=0.000 n=10+10)
    ObjectGetFromBaseDoc-16        17.2MB ± 0%     0.0MB ± 0%  -99.95%  (p=0.000 n=10+10)

    name                         old allocs/op  new allocs/op  delta
    MemberWithKeyFromBaseDoc-16      702k ± 0%        0k ± 0%  -99.98%  (p=0.000 n=10+10)
    ObjectGetFromBaseDoc-16          702k ± 0%        0k ± 0%  -99.98%  (p=0.000 n=10+10)

Note: The optimization is enabled by default, and for all storage implementations. However,
there are multiple layers of opt-out options, in case this causes any unforeseen trouble for
your usage of OPA via Golang. (OPA-as-server use cases don't need to worry about this.)

Concretely, these opt-out options are:

1. an option for `topdown.Query` to not start with lazy objects in the first place
2. an option for `ast.JSONWithOpt` to revert to the old behaviour when converting to golang native values
3. an `EvalOption` for `rego.PrepareForEval(...).Eval(...)` so that it keeps copying the maps it adds to the result set

Fixes #5325.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2022-11-16 19:43:51 +01:00
Stephan Renatus 965301f90e ast: support dotted heads (#4660)
This change allows rules to have string prefixes in their heads -- we've
come to call them "ref heads".

String prefixes means that where before, you had

    package a.b.c
    allow = true

you can now have

    package a
    b.c.allow = true

This allows for more concise policies, and different ways to structure
larger rule corpuses.

Backwards-compatibility:

- There are code paths that accept ast.Module structs that don't necessarily
  come from the parser -- so we're backfilling the rule's Head.Reference
  field from the Name when it's not present.
  This is exposed through (Head).Ref() which always returns a Ref.

  This also affects the `opa parse` "pretty" output:

  With x.rego as

    package x
    import future.keywords
    a.b.c.d if true
    e[x] if true

  we get

    $ opa parse x rego
    module
     package
      ref
       data
       "x"
     import
      ref
       future
       "keywords"

     rule
      head
       ref
        a
        "b"
        "c"
        "d"
       true
      body
       expr index=0
        true
     rule
      head
       ref
        e
        x
       true
      body
       expr index=0
        true

  Note that

    Name: e
    Key: x

  becomes

    Reference: e[x]

  in the output above (since that's how we're parsing it, back-compat edge cases aside)

- One special case for backcompat is `p[x] { ... }`:

    rule                    | ref   | key | value | name
    ------------------------+-------+-----+-------+-----
    p[x] { ... }            | p     | x   | nil   | "p"
    p contains x if { ... } | p     | x   | nil   | "p"
    p[x] if { ... }         | p[x]  | nil | true  | ""

  For interpreting a rule, we now have the following procedure:

  1. if it has a Key, it's a multi-value rule; and its Ref defines the set:

     Head{Key: x, Ref: p} ~> p is a set
     ^-- we'd get this from `p contains x if true`
         or `p[x] { true }` (back compat)

  2. if it has a Value, it's a single-value rule; its Ref may contain vars:

     Head{Ref: p.q.r[s], Value: 12} ~> body determines s, `p.q.r.[s]` is 12
     ^-- we'd get this from `p.q.r[s] = 12 { s := "whatever" }`

     Head{Key: x, Ref: p[x], Value: 3} ~> `p[x]` has value 3, `x` is determined
                                          by the rule body
     ^-- we'd get this from `p[x] = 3 if x := 2`
         or `p[x] = 3 { x := 2 }` (back compat)

     Here, the Key isn't used, it's present for backwards compatibility: for ref-
     less rule heads, `p[x] = 3` used to be a partial object: key x, value 3,
     name "p"

- The destinction between complete rules and partial object rules disappears.
  They're both single-value rules now.

- We're now outputting the refs of the rules completely in error messages, as
  it's hard to make sense of "rule r" when there's rule r in package a.b.c and
  rule b.c.r in package a.

Restrictions/next steps:

- Support for ref head rules in the REPL is pretty poor so far. Anything that
  works does so rather accidentally. You should be able to work with policies
  that contain ref heads, but you cannot interactively define them.
  
  This is because before, we'd looked at REPL input like

      p.foo.bar = true

  and noticed that it cannot be a rule, so it's got to be a query. This is no
  longer the case with ref heads.

- Currently vars in Refs are only allowed in the last position. This is expected
 to change in the future.

- Also, for multi-value rules, we can not have a var at all -- so the following
  isn't supported yet:

      p.q.r[s] contains t if { ... }

-----

Most of the work happens when the RuleTree is derived from the ModuleTree -- in
the RuleTree, it doesn't matter if a rule was `p` in `package a.b.c` or `b.c.p`
in `package a`.

As such, the planner and wasm compiler hasn't seen that many adaptations:

- We're putting rules into the ruletree _including_ the var parts, so

  p.q.a = 1
  p.q.[x] = 2 { x := "b" }

  end up in two different leaves:

  p
  `-> q
       `-> a = 1
       `-> [x] = 2`

- When planing a ref, we're checking if a rule tree node's children have
  var keys, and plan "one level higher" accordingly:

  Both sets of rules, p.q.a and p.q[x] will be planned into one function
  (same as before); and accordingly return an object {"a": 1, "b": 2}

- When we don't have vars in the last ref part, we'll end up planning
  the rules separately. This will have an effect on the IR.

  p.q = 1
  p.r = 2

  Before, these would have been one function; now, it's two. As a result,
  in Wasm, some "object insertion" conflicts can become "var assignment
  conflicts", but that's in line with the now-new view of "multi-value"
  and "single-value" rules, not partial {set/obj} vs complete.
* planner: only check ref.GroundPrefix() for optimizations

In a previous commit, we've only mapped

    p.q.r[7]

as p.q.r;  and as such, also need to lookup the ref

    p.q.r[__local0__]

via p.q.r

(I think. Full disclosure: there might be edge cases here that are unaccounted
for, but right now, I'm aiming for making the existing tests green...)


New compiler stage:

In the compiler, we're having a new early rewriting step to ensure that the
RuleTree's keys are comparible. They're ast.Value, but some of them cause us
grief:

- ast.Object cannot be compared structurally; so

      _, ok := map[ast.Value]bool{ast.NewObject([2]*ast.Term{ast.StringTerm("foo"), ast.StringTerm("bar")}): true}[ast.NewObject([2]*ast.Term{ast.StringTerm("foo"), ast.StringTerm("bar")})]

  `ok` will never be true here.

- ast.Ref is a slice type, not hashable, so adding that to the RuleTree would
  cause a runtime panic:

      p[y.z] { y := input }

  is now rewritten to

    p[__local0__] { y := input; __local0__ := y.z }

This required moving the InitLocalVarGen stage up the chain, but as it's still
below ResolveRefs, we should be OK.

As a consequence, we've had to adapt `oracle` to cope with that rewriting:

1. The compiler rewrites rule head refs early because the rule tree expects
   only simple vars, no refs, in rule head refs. So `p[x.y]` becomes
   `p[local] { local = x.y }`
2. The oracle circles in on the node it's finding the definition for based
   on source location, and the logic for doing that depends on unaltered
   modules.

So here, (2.) is relaxed: the logic for building the lookup node stack can
now cope with generated statements that have been appended to the rule bodies.


There is a peculiarity about ref rules and extents:

See the added tests: having a ref rule implies that we get an empty object
in the full extent:

    package p
    foo.bar if false

makes the extent of data.p: {"foo": {}}

This is somewhat odd, but also follows from the behaviour we have right now
with empty modules:

    package p.foo
    bar if false

this also gives data.p the extent {"foo": {}}.

This could be worked around by recording, in the rule tree, when a node was
added because it's an intermediary with no values, but only children.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2022-10-14 10:15:54 +02:00
Philip Conrad 2d62aa9df3 topdown/builtins: Refactor registration functions and signatures (#5225)
* topdown/aggregates: Refactor to newer style.
* topdown/arithmetic: Refactor to newer style.
* topdown/array: Refactor to newer style.
* topdown/binary: Refactor to newer style.
* topdown/crypto: Refactor to newer style.
* topdown/casts: Refactor to newer style.
* topdown/comparison: Refactor to newer style.
* topdown/regex: Refactor to newer style.
* topdown/strings: Refactor to newer style.
* topdown/time: Refactor to newer style.
* topdown/type: Refactor to newer style.
* topdown/sets: Refactor to newer style.
* topdown/encoding: Refactor to newer style.
* topdown/type_name: Refactor to newer style.
* topdown/glob: Refactor to newer style.
* topdown/parse: Refactor to newer style.
* topdown/cidr: Refactor to newer style.

   This particular file was trickier to refactor than the others so far
   because the builtins were reused in 1-2 spots, which required
   renaming/wrapping tricks to get everything working again.

Also includes:
* builtins: Add function for extracting (Term, error) tuples.
* tests: Switch `test.sleep` examples to newer style.
* topdown: Use 'operands' over 'args' everywhere.
* topdown/builtins: Deprecate functional-style builtins.

Signed-off-by: Philip Conrad <philipaconrad@gmail.com>
2022-10-11 09:20:49 +02:00
Philip Conrad ac20ef2bf5 server+sdk+plugins: Integrate NDBCache into decision logging. (#5147)
This commit integrates the non-deterministic builtins caching system
into decision logging, both in the server and sdk packages. Some
reworking of the NDBCache's serialization format were required to
accommodate this. The feature is disabled by default, and must be
opted into by user configuration.

The feature can be enabled via a top-level config key:

    nd_builtin_cache=true

The NDBCache is exposed to the masking system under the
`/nd_builtin_cache` path, which allows masking or dropping sensitive
values from decision logs selectively.

Note: If a decision log event exceeds the `upload_size_limit_bytes`
value for the OPA instance, OPA will reattempt uploading it, after
dropping the NDBCache from the event. This behavior will trigger a log
error, and will increment the `decision_logs_nd_builtin_cache_dropped`
metrics counter.

Fixes: #1514

Signed-off-by: Philip Conrad <philipaconrad@gmail.com>
2022-10-06 16:27:54 -04:00
Philip Conrad b2d92a33c1 Add prealloc linter check + linter fixes (#5139)
This commit adds the `prealloc` linter to the list of linters for OPA, and fixes up the miscellaneous locations in the code that the linter found where we could easily preallocate slices.

Signed-off-by: Philip Conrad <philipaconrad@gmail.com>
2022-09-15 15:09:54 -04:00
Stephan Renatus 25a597bc3f ast/compile: respect unsafeBuiltinMap for 'with' replacements (#5107)
The changes are necessary for both the Compiler and the QueryCompiler. Tests
have been added to ensure that the code path through the rego package has also
been fixed.

Fixes CVE-2022-36085.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2022-09-07 20:00:18 +02:00
Stephan Renatus b7bdd61397 rego/rego_test: test with test server, not httpbin.org (#5098)
Follow-up to #5097 (parent commit).

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2022-09-07 09:39:17 +02:00
Philip Conrad 6a439c5b2c topdown: Fix key construction for NDBCache; rego: avoid NDBCache init (#5097)
* topdown/eval: Fix key construction for NDBCache.

This commit fixes the construction process for keys used to look up
entries in the non-deterministic builtins cache. The original cache
lookup process could use refs that were not fully-grounded, and this
meant that calling a builtin twice with differing parameters could
appear identical to the cache if they involved refs as parameters.

We now use fully-grounded terms for the cache keys during insertion/lookup,
meaning that non-deterministic builtin calls with different parameters
are now guaranteed to result in unique cache entries, even if hidden
behind a ref.

* rego/rego: Fix unneeded NDBCache initializations.

The NDBCache is intended as an opt-in feature, and the initializations
present in the `rego` module meant that it was forced on virtually every
eval. This commit removes those initializations, so that the only way an
NDBCache will ever make it to the evaluator is if it's provided from
outside the evaluator.

* rego/rego_test: Add ND builtin iteration test.

This commit adds a test to ensure that the NDBCache correctly
handles iterative calls of a builtin with different input parameters.

Signed-off-by: Philip Conrad <philipaconrad@gmail.com>
2022-09-07 09:18:11 +02:00
Philip Conrad 01fc9ec013 eval+rego: Support caching output of non-deterministic builtins. (#4926)
This commit includes evaluator support for an opt-in, non-deterministic
builtins caching system, designed to help with future replay of decision
logs.

The cache allows early-exit in the evaluator if the builtin is
non-deterministic, and has already cached a result. Since the cache can
be pre-populated by `rego` module users, this should make offline policy
testing and future work around decision replay more straightforward.

Fixes: #1514

Signed-off-by: Philip Conrad <philipaconrad@gmail.com>
2022-09-01 11:35:09 -04:00
Stephan Renatus 1dfa6bd723 ast: hash containers on insert/update (#4367)
* ast: hash containers at insertion/creation time

This allows us to use the Hashes for comparisons, too, since they're
cheaply available all the time.

* rego_test: add test for concurrent eval of PreparedEvalResult

Fixes #4345.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2022-02-21 10:40:12 +01:00
Stephan Renatus d7a762d529 rego: add EvalPrintHook() EvalOption
When using print() and PrepareForEval, subsequent Eval calls are now
able to supply their own `print.Hook`.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-11-30 11:19:18 -08:00
Torin Sandall 5ec67ccd3a rego: Do not rewrite/capture void function call return values
This commit prevents the rewriting step from attempting to capture the
result of void function calls. This avoids generating invalid queries
that will fail to type check.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2021-10-14 09:31:16 -07:00
koponen-styra 0b17b3903f rego: Add support for custom JSON marshaling of results. (#3755)
This is useful if one does not prefer to use the ast.JSON(WithOpt) to do the
conversion.

Signed-off-by: Teemu Koponen <koponen@styra.com>
2021-08-21 07:54:23 +02:00
Stephan Renatus 47d1cb66db rego: pass inter-query builtin cache to wasm sdk (#3721)
Found when looking into #3716.

With this change, multiple calls to a wasm-backed eval that uses http.send
would re-use the results (if caching permits).

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-08-09 19:43:36 +02:00
Stephan Renatus bac175533b rego+topdown: allow custom builtins via rego pkg to halt (#3645)
Before, functions provided via arguments to `rego.New()` hadn't been
able to halt the topdown evaluation.

Now, they do, if they return a `*rego.HaltError`.

Fixes #3534.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-07-13 17:46:14 +02:00
Stephan Renatus 8f489988ce wasm/sdk: handle random seed needed by 'uuid.rfc4122()' (#3623)
There random seed to be used with the host-provided builtin uuid.rfc4122
was missing from the BuiltinContext that's created in the dispatcher. It
hadn't been thread through from rego to the vm call.

The unit tests for the builtin now run against both targets.

Also some style adjustments to the builtin code for uuid.rfc4122.

Fixes #3622.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-07-08 20:12:43 +02:00
Torin Sandall a60577d377 rego: Expose random seeding in rego package
Fixes #3560

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2021-06-15 15:47:22 -04:00
Will Beason 3be1d08b87 Change check-lint to use golangci-lint (#3465)
golint is deprecated. The author of the code no longer supports the
codebase. golangci-lint is faster than golint, and is in use by other
opa repositories (e.g. Gatekeeper).

This commit changes tools.go to reference golangci (so it ends up in
vendor) and modifies check-lint to use golangci instead.

Breaking API Changes:

- plugins/rest/rest.go: Fix typo "AllowInsureTLS" -> "AllowInsecureTLS"
- storage/errors.go: Removed unused IndexingNotSupportedErr

Signed-off-by: Will Beason <willbeason@google.com>
2021-05-19 07:52:02 +02:00
Andre Håland 4b5f53b548 Deterministic order of rules for optimized bundles
Before this fix, an optimized bundle would get
non-deterministic order of the support rules.

One example use case where it is necessary for the optimized
bundle to be deterministic is when a hash of the bundle is
used for version tag.

Fixes: #3453

Signed-off-by: Andre Håland <andre.haland@gmail.com>
2021-05-14 12:59:49 -04:00
Stephan Renatus ee115dba41 rego+bundle: Fix issues underlying #3209 (#3444)
* bundle: cleanup path before setting it as baseDir

GetBundleDirectoryLoader will do it again, but we need the cleaned-up
`path` to avoid "file:/" parts erroneously making it into the bundle's
ModuleFile structs. GetBundleDirectoryLoader is shared with the server,
so we'll keep that as-is.

* rego: avoid (*Bundle).ParsedModules(..)

Using this will prefix a path that is already complete. Using ModuleFile's
Path instead, we get the already-resolved path.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-05-13 20:25:45 +02:00
Torin Sandall 898d010050 ast: Refactor SchemaSet to hide ByPath collection
This commit does not change any functionality it just refactors the
schema implementation a bit:

* There is no reason to expose the ByPath collection for now. This
  change simplifies things for the caller because they can just
  perform get/put operations on the SchemaSet.

* Rename setTypesWithSchema to loadSchema.

* Move schema code into a separate file with it's own test cases
  separate from the compiler.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2021-04-02 11:21:42 -04:00
Mandana Vaziri 3e3655bbaf New support to upload a directory of JSON schema file(s) via "opa eval --schema". Directory can contain schema file(s) for policy input document(s), and schema file(s) for contextual data document(s). These schema files are used then to improve static type checking and to get more precise error reports as you develop Rego code.
Also, there is new support for adding annotations on Rules to specify the schemas to be used specifically for type checking the expressions within the scope of that Rule. It helps address issues with schema overloading, and provides even more precise type error reports for a Rego developer.

Also, added support for annotation processing when loading via bundles.

Co-authored-by: @vazirim Mandana Vaziri mvaziri@us.ibm.com
Co-authored-by: @aavarghese Ansu Varghese avarghese@us.ibm.com
Co-authored-by: @tsandall Torin Sandall torinsandall@gmail.com
Signed-off-by: Mandana Vaziri <mvaziri@us.ibm.com>
2021-03-31 10:15:41 -04:00
Anders Eknert b02db2e98a Skip WASM tests on WASM_ENABLED=0
Signed-off-by: Anders Eknert <anders@eknert.com>
2021-02-24 13:24:15 +01:00
Ashutosh Narkar 2b2d73ebbf Add target flag to OPA subcommands
This commit adds a target flag to the
bench, eval, test and run (repl) commands
which allows users to exercise the wasm
rumtime.

Fixes #2878

Signed-off-by: Ashutosh Narkar <anarkar4387@gmail.com>
2021-02-05 10:16:22 -08:00
Ansu Varghese cc1cecf567 opa eval: support rego validation using input JSON schema (#3060)
New support to input a JSON schema file via "opa eval --schema" that
helps improve static type checking and returns precise error reports as
you develop Rego code.

Also, uses modified version of https://github.com/xeipuuv/gojsonschema
from internal/ to help set Rego types, using gojsonschema's Compiler
results. See README docs for more details on the feature.

Co-authored-by: Mandana Vaziri <mvaziri@us.ibm.com>
Co-authored-by: Ansu Varghese <avarghese@us.ibm.com>
Signed-off-by: Ansu Varghese <avarghese@us.ibm.com>
2021-01-27 13:32:59 +01:00
Torin Sandall 181096df4a rego: Add option to enable strict built-in errors
Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-10-23 12:28:23 -07:00
Ashutosh Narkar 7f65b04561 Add a new inter-query cache to cache responses across queries
This commit adds a new inter-query cache that built-in
functions can use to cache responses across queries.

The OPA config includes a new "caching" field that can be used
to set the size of the cache. By default there is no limit.

This change also updates `http.send` to optionally utilize the
inter-query cache.

Fixes #1753

Signed-off-by: Ashutosh Narkar <anarkar4387@gmail.com>
2020-08-06 14:33:18 -07:00
Teemu Koponen 98119fc00c ast: Introduce Array struct.
This decouples the consumers of the Array from its implementation, and
thus, paves the way for improved (more optimized) Array
operations. Note, the array memory foot print and the allocations
required with the array operations remain the same.

Signed-off-by: Teemu Koponen <koponen@styra.com>
2020-08-03 13:36:33 -04:00
Torin Sandall e7df89db62 topdown, rego: Add parameter to set wall clock time
Previously topdown did not expose a way for the caller to set the wall
clock time. This makes it impossible to reliably replay policy queries
that depend on time of day. With this change, callers can supply the
wall clock time to use for time.now_ns() calls.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-07-21 16:02:05 -04:00
Patrick East b45ab28375 rego: Plumb the newer QueryTracer through Rego API's
This will deprecate the older API's that used the `topdown.Tracer` in
favor of the newer `topdown.QueryTracer` interface. Usages of the old
API have been swapped, although some of the testing is left with them
to ensure we still support them (until we remove the deprecated API).

Signed-off-by: Patrick East <east.patrick@gmail.com>
2020-07-15 12:01:12 -07:00
Torin Sandall fceebc35a4 compile: Add support for shallow inlining
This commit plumbs the new partial evaluation mode into the compiler
and defines the new optimization levels (0=off, 1=shallow inlining,
2=aggressive inlining).

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-06-23 09:20:32 -04:00
Torin Sandall 57e7e89dff rego, server: Fix panic caused by compiler misuse
Previously the rego package would construct rules for each of the
PE query results when PartialResult() was invoked--however, it would not
check if those rules would be recursive. If the user queried for
`data` (or `data.<partialnamespace>`) then PE would return an
(essentially) unmodified copy of the query and the rego package would
happily construct a rule from it--since the rule is namespaced under
data this leads to a recursion error.

The problem is that the recursion error was caught by running the
compiler--however, since the compiler is shared by the server and
other components and since compile operations do not rollback changes
on error, this approach left OPA in an inconsistent state. Some of the
compiler data structures like the rule tree would include the PE
result but any structures built by stages after the recursion check
would be incomplete. This causes issues for the evaluator because it
(rightfully) assumes that the compiler data structures are consistent.

Since we can assume that PE results are valid and do not contain
semantic errors and we do not intend to support the lazy PE API in the
future, this commit fixes the issue/panic by modifying the rego
package to check for recursion in the rules that it constructs. This
is relatively simple since it merely has to check for prefixes in the
refs contained in the PE query result. If recursion is caught, the
rego package returns an error signalling that PE was ineffective. In
this case, the server just falls back to normal eval.

Fixes #2197

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-05-21 15:10:58 -07:00
Torin Sandall 08b28c3cf5 topdown: Expose flag to skip support namespacing
Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2020-05-18 08:32:38 -04:00