github open-policy-agent/opa v1.20.0

3 hours ago

v1.20.0

This release contains a mix of new features and bug fixes. Notably:

  • New Rego keywords: and and or, for combining conditions inside a single rule body
  • allow_net now restricts remote JSON Schema $ref fetching from json.match_schema and json.verify_schema
  • Coverage reports can now explain why a range is not covered
  • Much faster partial evaluation for dynamically composed policies

New Rego keywords: and and or (#7602)

Rego gains two keywords for combining conditions inside a single rule body — a long-standing
request, and one of the larger additions to the language in some time. and and or let control
flow that previously had to be split across helper rules stay where it is read.

Before, a rule body that needed to succeed on one of several conditions meant extracting a rule:

package example

allow if {
	input.method == "GET"
	admin_or_public_owner
}

admin_or_public_owner if input.user.admin

admin_or_public_owner if {
	input.user.owner
	input.resource.public
}

Now:

package example

import future.keywords.and
import future.keywords.or

# the and groups first, so this reads as:
# an admin, or an owner of a public resource
allow if {
	input.method == "GET"
	input.user.admin or input.user.owner and input.resource.public
}

Both keywords are opt-in future keywords:
import future.keywords.and, import future.keywords.or, or import future.keywords for both.

An and/or expression either succeeds or fails; it never produces a value. So you can't assign
one to a variable, pass one to a function, or use one as the head of a comprehension.

Operands can read variables from the rule body around them, but can't create new ones for the rest
of the rule to use — wrap an operand in braces to give it a body of its own, and any variables it
creates stay inside those braces. Only as much is evaluated as needed: if the left side settles the
outcome, the right side is skipped. And when both sides of an or succeed, you still get a single
result; evaluation doesn't split in two.

Further reading:

Try the new keywords in the Rego Playground, or in your
editor with the VS Code extension
or the IntelliJ IDEA plugin — see
Editor and IDE Support for others.

Authored by @johanfylling

Behavior change: allow_net applies to remote JSON Schema $refs (#8979)

The allow_net
capability restricts which hosts remote JSON Schema $refs may be fetched from, but it was only
wired up on the compile-time type-checking path. Policies using neither -s schemas nor
# METADATA schemas:
annotations never reached it, and an unset allowlist permitted every host — so
json.match_schema
and json.verify_schema,
which compile schemas at evaluation time, fetched $refs from anywhere. Their schema argument can
come from input, so the host was not necessarily under the policy author's control.

The allowlist now travels with the schema loader and is checked per caller at any nesting depth.
Every redirect hop is checked too, matching http.send, and the inter-query cache key includes the
allowlist so a permissive caller cannot populate the cache for a restrictive one.

Authored by @sspaink, reported by @charlesdaniels

Coverage reports explain why a range is not covered (#8937)

Coverage reports showed that a
range was uncovered, but not why: ranges skipped by rule indexing
or early exit looked identical to dead code.

Not-covered ranges are now tagged with a Kindindex_excluded or early_exit — determined
by re-evaluating with each optimization disabled and diffing the extra coverage data. Both
supplementary passes run by default when --coverage is set; the new --coverage-runs flag on
opa eval and opa test selects which of them to run, and an empty list disables them.

Authored by @charlieegan3

Runtime, SDK, Tooling

  • bundle: Fix roots containing percent-encoded characters (#6704) authored by @sspaink, reported by @sirpi
  • compile: Validate plan-addons exist (#9092) authored by @charlieegan3
  • config: Migrate server.encoding and server.decoding validation to Rego (#8903) authored by @sspaink
  • debug: Allow configuring variable value length limit (#8907) authored by @oh-summy
  • format: Add support for formatting and/or logical expressions (#8683) reported and authored by @johanfylling
  • format: Converge object comprehension layout (#9075) reported and authored by @hamodywe
  • format: Don't group rules that aren't written on one line (#8981) authored by @sspaink
  • format: Don't unwrap one-line rule body braces from a single set term (#8972) authored by @johanfylling
  • format: Honor line breaks before explicit and/or operand bodies (#9053) authored by @sspaink, reported by @anderseknert
  • format: Keep parens around a nested not operand (#9079) authored by @sspaink
  • format: Wrap set union | infix in parens when output would be re-interpreted as comprehension (#8977) authored by @johanfylling
  • format: Write added imports before rules (#9083) authored by @sspaink
  • loader: Fix loading absolute paths on Windows (#4521) authored by @sspaink, reported by @lcarva
  • oracle: Support and/or logical keywords (#8819) reported and authored by @johanfylling
  • plugins: Avoid predictable OCI temp store (#8853) authored by @br0x2
  • plugins: Fix overly verbose return of errors (#9090) authored by @anderseknert
  • rego: Pass capabilities to the parser in (*Rego).compileModules (#9059) authored by @anderseknert
  • repl: Add support for and/or imports (#9066) reported and authored by @johanfylling
  • repl: Allow interactive ref head rule definitions (#5498) authored by @sspaink, reported by @philipaconrad
  • runtime: Allow registering hooks, and pass them to discovery (#9064) authored by @srenatus
  • server: Decouple decision logging from request context cancellation (#9023) authored by @srenatus
  • wasm: Address regression causing memory corruption (#8995) authored by @charlieegan3

Compiler, Topdown and Rego

Docs, Website, Ecosystem

Miscellaneous

  • ast: Annotations code cleanup (#9049) authored by @anderseknert
  • ast: Enable modernize linter for golangci-lint (#8996) authored by @anderseknert
  • ast: Enable static check of consistent receiver names (#9008) authored by @anderseknert
  • ast: Move global builtin.Ref() vars to a single location (#9040) authored by @anderseknert
  • ast: Move interning experiment behind noisy tag (#9034) authored by @srenatus
  • ast: Replace use of sort package with modern alternatives (#9013) authored by @anderseknert
  • ast: Use slices.CompareFunc for imports and annotations (#9019) authored by @anderseknert
  • build/release: Create new release tool (#8959) authored by @johanfylling
  • build(go): Modernize for the Go 1.26 standard library (#9056) authored by @srenatus
  • bundle: Use util.WithPrefix (#9005) authored by @anderseknert
  • ci: Migrate proto-check to bufbuild/buf-action (#9030) authored by @srenatus
  • ci: Serialize benchmarks workflow to avoid racing writes to benchmarks branch (#9065) authored by @srenatus
  • lint: Enable all usetesting options (#9072) authored by @anderseknert
  • lint: Remove intrange linter, as it's covered by modernize (#9014) authored by @anderseknert
  • releng: Sample benchmarks from 15 processes, not 3 (#9034) authored by @srenatus
  • releng: Update post-merge benchmark regression check (#9029) authored by @srenatus
  • server_test: Adjust test to avoid flakey decision log test outcome (#9026) authored by @srenatus
  • test: Clean up irrelevant nolint directives (#9050) authored by @anderseknert
  • test: Restore print-based and/or short-circuit tests (#9057) authored by @sspaink
  • topdown: Add uri built-in compliance cases for parser edge cases (#8980) authored by @sspaink
  • topdown: Cover uuid.parse input format leniency (#9003) authored by @sspaink
  • topdown: Modernize fixes and some string building improvements (#8993) authored by @anderseknert
  • util: Don't return a nil slice from StringToByteSlice("") (#9091) authored by @srenatus
  • Dependency updates; notably:
    • build(go): Bump the build toolchain to Go 1.27, and the go.mod language version to 1.26 (#9051) authored by @srenatus
    • build(deps): Bump github.com/dgraph-io/badger/v4 from 4.9.4 to 4.9.5
    • build(deps): Bump github.com/prometheus/client_golang from 1.24.0 to 1.24.1
    • build(deps): Bump go.opentelemetry.io/proto/otlp from 1.10.0 to 1.11.0

Don't miss a new opa release

NewReleases is sending notifications on new releases.