Commit Graph

65 Commits

Author SHA1 Message Date
Johan Fylling b6c3ac1860 ast: Enable future.keywords.not in default capabilities (#8609)
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2026-05-06 14:32:33 +02:00
Charlie Egan 343ddf583f builtins: Add uri.parse and uri.is_valid built in functions (#8578)
Examples of things this is useful for:
- Implementing policy around AI coding tool calls (permitted domains
etc)
- Validating SPIFFE IDs

Fixes https://github.com/open-policy-agent/opa/issues/8263

---------

Signed-off-by: Charlie Egan <charlie_egan@apple.com>
2026-04-29 13:08:15 +00:00
Anders Eknert d0350b326e Add array.flatten built-in function (#8232)
Originally meant to be `array.concat_n`, but this name is better
as the behavior of this function differs from `array.concat` —
namely that `array.flatten` accepts any type of valued in the
input array. Only arrays are however flattened, and the rest
are appended directly to the flattened output.

Note that this function only flattens at the topmost level of
the input array — not recursively! A cursory look
at a few other languages suggest a single level is the common case.
But if others feel we should flstten more, I'm happy to make an update.

The C code for a Wasm implementstion here is cowboy coded, and
I did not manage to run the tests on my machine due to some
`docker` <-> `container` differences. I mostly just imitated
the existing code in the array category. I doubt it'll work
on the first try, but only CI can judge me.

Also:
- Remove `opa fmt` step from the Rego CI step, as this is done by
  Regal anyway a little later in the list of tasks.
- Replace some hard-coded `docker` names in the `Makefile` with `$(DOCKER)`
- Added name of built-in function missing to the unsupportedBuiltinErr
  error, as it has happened a few times now that I've used `:=` in a
  query, and had no clue what built-in it referred to.

Fixes #8226

Signed-off-by: Anders Eknert <anders.eknert@apple.com>
2026-01-27 21:46:11 +00:00
Johan Fylling 8e410b830a String interpolation (#8109)
Adding string interpolation support to the Rego language.

An interpolated string is composed of a template-string that can contain zero or more template-expressions that interpolates values into the string generated at eval-time.

Requires the `template_strings` capability feature and `internal.template_string` built-in function.

Implements: #4733
2025-12-16 11:47:04 +01:00
Colin J Lacy 6341217206 ast: Export built-in deprecated field (#8069)
Fixes: #7912

Signed-off-by: Colin Lacy <colinjlacy@gmail.com>
2025-11-25 10:53:42 +01:00
Johan Fylling 5faa4e2e67 Adding EdDSA support for io.jwt built-ins (#7824)
Introducing the `io.jwt.verify_eddsa` built-in, and adding support to the following built-ins:

* `io.jwt.decode_verify`
* `io.jwt.encode_sign`
* `io.jwt.encode_sign_raw`

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2025-08-12 18:52:47 +02:00
Johan Fylling 817b6635a8 ast,format: Allowing keywords in Rego references (#7709)
Updating the parser and formatter to allow keywords in refs.

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2025-06-25 15:19:21 +02:00
Johan Fylling a6fcabbba6 cmd+tester: Parameterized tests (#7366)
Adding the ability to parameterize Rego `test_*` rules, effectively declaring multiple "test cases" within the rule, which is then individually reported (grouped under their parent rule) when running `opa test`.

Fixes: #2176

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2025-02-17 22:08:27 +01:00
Johan Fylling 563321d26b Rego v1 capabilities and keywords update (#7216)
* Separating v0- and v1 keywords
* Adding `rego_v1` capability feature

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2024-12-17 11:50:11 +01:00
Manish Giri c70544045b Implement a built-in function for String count
Fixes #6827

Signed-off-by: Manish Giri <manish.giri.me@gmail.com>
2024-07-03 15:50:34 -07:00
Sean Williams e0ee7418b0 topdown: Add json.marshal_with_options() builtin for indented/"pretty-printed" and/or line-prefixed JSON (#6636)
Fixes #6630

Signed-off-by: Sean Williams <72675818+sean-r-williams@users.noreply.github.com>
2024-04-05 10:11:01 +02:00
Yogesh Sinha ea0dc0209c Adding a new function crypto.x509.parse_and_verify_certificates_with_options. Fixes #5882 (#6643)
Signed-off-by: Yogesh Sinha <sinhayogi@gmail.com>
2024-03-27 13:50:44 +00:00
Rohan Vasavada d46bc9d2be feat(builtins): add a new builtin function strings.render_template to render templated strings
This adds support for rendering of templated strings utilizing Golang's text/template library.
For a given templated string and key/value mapping of template var inputs, this builtin will
inject the values into the template where they are referenced by key.

Fixes #6371
Signed-off-by: Rohan Vasavada <rohanvasavada@gmail.com>
2023-11-17 08:53:28 -08:00
Johan Fylling bcf82eb405 ast: Adding capability feature for the rego.v1 import (#6375)
Resolves: #6366
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2023-11-15 12:16:19 +01:00
Johan Fylling 56f2350d0f ast: Adding rule_head_refs capabilities feature flag (#6346)
To signal/toggle support for general refs in rule heads.

Fixes: #6334
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2023-11-15 11:24:16 +01:00
Odin Bjørnebo e15996e5a5 Builtin function to parse uuid with google/uuid library
Fixes #6173

Signed-off-by: Odin Bjørnebo <odinbjoernebo@gmail.com>
2023-09-08 12:48:40 -07:00
Sebastian Spaink c28eaf7fb4 topdown: add numbers.range_step built-in function (#6187)
Fixes: #6186
Signed-off-by: Sebastian Spaink <sebastianspaink@gmail.com>
2023-08-30 11:09:54 +02:00
Emil Volckmar Ry cfb03ca495 introduce new builtin crypto.parse_private_keys
* crypto.parse_private_keys parses private keys, returns a list of valid
keys
* consolidated getPrivateKeysFromString  with getPrivateKeysFromPEMData
for crypto.x509.parse_rsa_private_key  and crypto.parse_private_keys

* reworked crypto.x509.parse_rsa_private_key so that we no longer need
getPrivateKeysFromString  but instead determine type of key in builtin
function and added input validation checks

Co-authored-by: Charlie Egan <git@charlieegan3.com>
Signed-off-by: Emil Volckmar Ry <emilvry@gmail.com>
2023-07-19 17:54:51 -07:00
Emil Volckmar Ry 63114e925b adds builtin: crypto.x509.parse_keypair.
crypto.x509.parse_keypair(cert, key) takes PEM/DER (base64) encoded input.

if key pair is valid, returns the tls.certificate(https://pkg.go.dev/crypto/tls#Certificate) as an object.

if key pair is invalid, returns an error.
Fixes #5853

Signed-off-by: Emil Volckmar Ry <emilvry@gmail.com>
2023-05-23 12:27:33 -07:00
Sandokan D. Arantes 1731907295 topdown: Add built-in HMAC compare function
Add crypto.hmac.equal built-in function to safelly comparing hashes generated by MD5, SHA-1, SHA-256 and SHA-512 hashing algorithms.

The built-in function is a wrapped for the function Equal of package crypto/hmac.

It's useful when you need to write a policy that requires to check hash signature for request body.

Signed-off-by: Sandokan D. Arantes <sandokandias@gmail.com>
2023-04-21 10:24:07 -07:00
Yuri Kulagin 334f27e0d1 topdown: JSON Schema validation and verification (#5486)
Adding built-in functions for JSON schema validation

* json.verify_schema
* json.match_schema

Signed-off-by: Yuri Kulagin <jkulvichi@gmail.com>
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
Co-authored-by: Johan Fylling <johan.dev@fylling.se>
2023-03-02 11:54:48 +01:00
Aviral Jain 34f6939a97 time.format: new builtin to get string timestamp for ns (#5432)
Adds a builtin time.format to format time given in ns to a string timestamp for
the given timezone or UTC as default. The builtin takes in 3 types of arguments:

1. An integer value representing the time in nanoseconds since epoch
2. An array with the first value as integer representing the time in ns and second argument as string value representing the timezone. In the first case, when only an integer value is provided, UTC timezone is considered
    The function returns a string type value of the timestamp in the RFC3339Nano format. E.g. 2022-11-23T18:20:14Z
3. An array with the first value the integer ns, the second a string timezone, and third a string for the format, to use one different from RFC3339Nano.

Signed-off-by: burnerlee <avi.aviral140@gmail.com>
2022-12-19 10:32:41 +01:00
Philip Conrad ed76301eb6 builtins: Add AWS Sig v4 signing builtin. (#5376)
This commit adds initial support for AWS's SigV4 request signing system,
which will allow OPA's existing `http.send` builtin to be used to more
conveniently query cloud resources. It automates away most of the pain
around signing the request headers and body, and is designed to compose
with `http.send` directly.

Internally, this also refactors AWS SigV4 request signing, so that the
signing logic is shared between the builtin and the REST plugin for AWS.

Fixes: #3749

Signed-off-by: Philip Conrad <philipaconrad@gmail.com>
2022-11-18 15:11:47 -05:00
Kevin Swiber b6184bd258 builtins: add object.keys (#5392)
The `object.keys` function will return a set of all top-level keys on
a given object.  Since object keys in Rego don't have the same
restrictions as names in JSON name-value pairs, we also ensure
support for non-string key types.

Fixes #5363.

Signed-off-by: Kevin Swiber <kswiber@gmail.com>
2022-11-17 20:55:35 +01:00
Philip Conrad 6ec07cabfb ast+topdown: Add graphql.schema_is_valid builtin. (#5296)
This commit adds a new GraphQL builtin for validating GraphQL schemas,
applying stronger validation rules than what the current GraphQL parsing
builtins apply by default.

Fixes: #5125

Signed-off-by: Philip Conrad <philipaconrad@gmail.com>
2022-10-27 14:59:18 +02:00
Ricardo Maraschini da8afed08d builtins: add net.cidr_is_valid for validating CIDR strings (#5306)
This commit adds the `net.cidr_is_valid` builtin, which makes
validating network CIDR strings much easier in policies.

Example policy:

    allow {
        net.cidr_is_valid("192.168.0.0/24")
    }

This builtin works for both IPv4 and IPv6 CIDR strings.

Signed-off-by: Ricardo Maraschini <ricardo.maraschini@gmail.com>
2022-10-26 12:44:31 -04:00
Stephan Renatus 2f264b12f1 ast: add 'features' to capabilities, use it to check for ref heads (#5208)
Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2022-10-14 10:38:04 +02:00
Boran Seref 1d2173ba9d feat: add regex.replace(s, p, v) to builtin (#5179)
* feat: add regex.replace(s, p, v) to builtin

Signed-off-by: boranx <boran.seref@gmail.com>
2022-09-27 19:27:24 +02:00
Philip Conrad ab385e9c17 topdown/builtins: Add object support for GraphQL builtins. (#4752)
This commit adds support for AST objects to be usable in place of
strings for several of the GraphQL built-in functions, to improve
the composability of the GraphQL set of built-ins, and to dramatically
reduce the amount of redundant parsing when writing GraphQL policies.

Fixes: #4742

Signed-off-by: Philip Conrad <philipaconrad@gmail.com>
2022-09-26 11:47:40 +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
Jacob Martin e7130a888d Add any_prefix_match and any_suffix_match functions for bulk prefix and suffix matching. (#4997)
Signed-off-by: Jakub Martin <kubam@spacelift.io>
2022-08-18 21:33:59 +02:00
Phạm Hữu Vinh da4a10044b topdown: support glob.match without delimiters (#4933)
Using null for delimiters disables delimiters in glob matching. Preferable over regex on some cases for performance reasons.

Fixes #4923.

Signed-off-by: vinhph0906 <vinhph0906@gmail.com>
Co-authored-by: Stephan Renatus <stephan.renatus@gmail.com>
2022-07-25 16:51:28 +02:00
Stephan Renatus 855c6bd44a ast/builtins: fix 'type_name' type and docs (#4920)
Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2022-07-21 09:41:17 +02:00
Stephan Renatus 04a3523b22 ast+format: introduce new keywords for rule heads: if and contains
`contains` provides an alternative way to declare partial sets:

    p contains x {
      x := { "foo": "bar"
    }

which is the same as

    p[x] {
      x := { "foo": "bar"
    }

The keyword is enabled by importing `future.keywords.contains`, and
when it _is enabled_, the format will be used for all partial sets in
that file for pretty-printing.

`if` is a new keyword allowing for more readable rule definitions:

The syntax is

    NAME [if] { EXPR [EXPR...] }

and the is a shorthand allows dropping the braces around the expression
if there is only one:

    NAME if EXPR

For example, this allows expressions like

    allow if not deny
    f(xs) if every x in xs { x != "foo" }

The one exception here are partial sets: they cannot use `if` UNLESS
they use `contains`:

    p[x] { x := "foo" }            # valid
    p contains x { x := "bar" }    # valid
    p contains x if { x := "bar" } # valid
    p[x] if { x := "foo" }         # invalid

This is because we want to interpret that differently (as an object
rule defining `p.foo = true`) in the near future.

The formatter works in the same way: if `future.keywords.if` is imported, it
will be used where it can be used.

We don't want to be too eager when it comes to introducing syntactic sugar.

So this will be rewritten, because head and body expression are on the same
line:

    p := 5 if { time.day_of_week() == "Monday" }

    # => p := 5 if time.day_of_week() == "Monday"

but this won't:

    p := 5 if {
       time.day_of_week() == "Monday"
    }

The rationale here is that if the policy author decided that they want this on
an extra line, we won't mess with it.

This also sidesteps the need to check if both the head and the single body
expression have a comment.

This change includes various docs updates. Notable exceptions are the GK docs,
since it will take a while for these keywords to be come available there; and
the frontpage: merging a PR would update the frontpage immediately, and we
don't want to show something there that isn't available in the latest release.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2022-06-22 10:36:06 +02:00
Charles Daniels f2fd8f5e91 built-ins: add object.subset() builtin
This implements the new object.subset() builtin.

Based on my benchmarking, this offers a 2.77x speedup compared to
implementing the same thing in pure Rego, and is also easier to read.

Fixes #4358

Signed-off-by: Charles Daniels <charles@styra.com>
2022-06-09 13:57:54 -07:00
Philip Conrad 1fde1ad235 built-ins: Add new GraphQL builtins.
This commit vendors in github.com/vektah/gqlparser, and provides the
implementation for the following graphql built-ins:

 - graphql.parse
 - graphql.parse_and_verify
 - graphql.parse_query
 - graphql.parse_schema
 - graphql.is_valid

The test suite is comprised of the classic "Star Wars" examples from the
official GraphQL docs, along with a host of syntax examples ported over
from the underlying GraphQL parser's test suite.

AST objects returned by the parse_x APIs are currently pruned for brevity.

Fixes #4283

Signed-off-by: Philip Conrad <philipaconrad@gmail.com>
2022-05-27 10:26:42 -07:00
Philip Conrad 53cb5f40f9 topdown: Add units.parse builtin (#4676)
This function works on all base decimal and binary SI units of the set:

    m, K/Ki, M/Mi, G/Gi, T/Ti, P/Pi, and E/Ei

Note: Unlike `units.parse_bytes`, this function is case sensitive.

Fixes open-policy-agent#1802.

Signed-off-by: Philip Conrad <philipaconrad@gmail.com>
2022-05-11 16:54:51 +02:00
Johan Fylling c6226621c4 ast: Adding rego.metadata.* built-in functions (#4537)
New functions:
* rego.metadata.chain(): returns the chain of metadata, starting from the active rule, going outward
* rego.metadata.rule(): returns the metadata for the active rule

Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2022-04-13 11:46:11 +02:00
Stephan Renatus a96e1779f3 ast+format: unveil future keywords 'every', forbit negation, copy *Every
Importing `future.keywords.every` will ALSO import `future.keywords.in`,
since the latter is required for the former.

This includes the formatting of the expression itself, and adding
the "future.keywors.every" import if necessary:

This would happen when pretty-printing an AST that was parsed
with ast.ParserOptions enabling the required future keyword:
The import would not be present in the *ast.Module, but it would
be required to parse the pretty-printed result.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2022-02-11 11:22:19 +01:00
Anders Eknert caffcec07b builtins: add object.union_n
Fixes: #4012

Signed-off-by: Anders Eknert <anders@eknert.com>
2022-01-23 20:24:57 +01:00
Justin Lindh 258501134d built-ins: add graph.reachable_paths (#4205)
This new built-in functionality allows callers to find all reachable
paths in a graph based on an array or set of root nodes. See the
updates to policy-reference.md for more details and usage information.

Signed-off-by: Justin Lindh <justin.lindh@webfilings.com>
2022-01-17 09:31:31 +01:00
Shuhei Kitagawa 52ddfd9149 topdown: Support indexof_n built-in function (#4172)
Fixes https://github.com/open-policy-agent/opa/issues/4155

Signed-off-by: shuheiktgw <s-kitagawa@mercari.com>
2022-01-06 09:58:27 +01:00
Kristian Svalland 6f81c4a620 Add array.reverse(array) and strings.reverse(string) built-in functions. (#4161)
The function `array.reverse` takes an array as an argument, and returns an array with a reversed order of elements.
The function `strings.reverse` takes a string as an argument, and returns a string with a reversed order of unicode code points.
WASM support is included for both built-ins.

Fixes #3736

Signed-off-by: Kristian Svalland <kristian.svalland@gmail.com>
2021-12-27 12:47:39 +01:00
Johan Fylling 76547e55d1 topdown: Add built-in HMAC functions (#4100)
Add crypto.hmac.* built-in functions for the MD5, SHA-1, SHA-256 and SHA-512 hashing algorithms.

Add documentation for how to contribute new built-in functions.

Fixes: #1740
Signed-off-by: Johan Fylling <johan.dev@fylling.se>
2021-12-09 13:48:17 +01:00
Stephan Renatus 8a1aab376f ast+topdown: add net.lookup_ip_addr built-in function (#3995)
Since the golang stdlib function doesn't do any caching, we add the result
to the BuiltinContext.Cache so it's cached, and consistent, within a single
policy evaluation.

There is no decision made here about using netgo or netcgo: we're following
suit wrt how golang expects you to do it: From my understanding, using the
OS means for DNS resolution is the preferred way: it gives you per-host
caching, and it allows the user to affect how DNS resolution works in many
ways.

This means the same logic that applies to all other places where we resolve
domain names into addresses (notably `http.send`) applies to this built-in,
too.

Also:

* workflow/pull_request: don't fail-fast for matrix jobs

Even if one platform fails it would be interesting to see what happens
on the others.

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-11-16 07:39:14 +01:00
Torin Sandall 04ead1d638 ast: Add future keywords to capabilities
This commit updates the capabilities structure to include the set of
supported future keywords and enhances the parser to accept the
capabilities structure so that callers can restrict what keywords can
be opted into in the first place. This ensures that callers can verify
that policies will parse for a particular version of OPA.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2021-10-20 14:16:52 -07:00
Stephan Renatus f8286be64e ast, topdown: add 'in' operator via internal builtins and future imports
There are four variants to this: with or without 'some', and with
only one or two lhs arguments:

 a) x in xs
 b) k, v in xs
 c) some x in xs
 d) some k, v in xs

(a) and (b) are handled in the parser, and end up in the AST as
calls to `internal.member_2` and `internal.member_3`:

 a) internal.member_2(x, xs)
 b) internal.member_4(k, v, xs)

The backing builtin functions iterate over their last arguments,
trying to find a match. If they do, they will return `true`.
In all other cases -- no match, or a type in the last argument that
can't be iterated over (not an array, object or set), it will
return `false`.

As such, they can be used with `not` without any restrictions.

(c) and (d) are rewritten in the compiler, where x', v', and k' are
fresh local vars:

 c) x' = xs[_]
 d) v' = xs[k']

Since `in` is a new keyword, it's enabled gradually: for now, a new
mechanism of future keyword imports is added. There are new option
arguments in the parser methods, and there's a hook in the parser
code updating its set of enabled future keywords whenever it
encounters an import statement like

    import future.keywords.in # enables only "in"
    import future.keywords    # enables all future keywords

Functionally, these are identical right now: there is only one
future keyword, "in".

Signed-off-by: Stephan Renatus <stephan.renatus@gmail.com>
2021-10-14 19:21:52 +02:00
Torin Sandall 8c77e5cb7c ast, topdown: Add print built-in function
The print built-in function has special-case handling in two ways:

1. Print arguments are wrapped in comprehensions at compile-time to
ensure that undefined values do not short-circuit evaluation. The
evaluator is aware of this rewriting and extracts the actual values
during evaluation.

2. Print arguments cannot contain unsafe/undeclared variables, i.e.,
vars appearing in refs inside of print args _must_ be assigned in
a previous expression in the body. This ensures that print statements
do not affect the semantics of the rule.

Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2021-10-14 09:31:16 -07:00
Torin Sandall f4d9c2225d types: Sort any elements during construction (#3805)
* types: Sort any elements during construction

This changes updates the implementation of the any type to sort
elements during construction. This way the Compare() function does not
have to sort elements before recursing (which can result in data races
if global type instances from the built-in function declarations or
elsewhere are compared.)

Fixes #3793

* capabilities.json: changed ordering
* internal/presentation: fix json error output

Co-authored-by: Torin Sandall <torinsandall@gmail.com>
Co-authored-by: Stephan Renatus <stephan.renatus@gmail.com>
Signed-off-by: Torin Sandall <torinsandall@gmail.com>
2021-09-20 11:46:02 +02:00
Cris He 22d505fd9e built-ins: decode a RSA private key into JWK format (#3783)
This will help users for JWT signing using RSA key, because currently
OPA only accepts RSA key in the JWK format.

Fixes: #3765

Signed-off-by: cris-he <cruztiempo@hotmail.com>
2021-09-17 07:03:16 +02:00