Skip to content

Conversation

@ma-ts
Copy link

@ma-ts ma-ts commented Jul 26, 2025

Add json.patch builtin support

Fixes: #95

Implements the json.patch builtin function according to the OPA specification, enabling RFC6902 JSON Patch operations on objects.

Changes

  • Added dependency: json-patch crate v4.0.0 with optional jsonpatch feature
  • New builtin: json.patch(object, patches) function that applies JSON Patch operations atomically
  • Comprehensive tests: Added test cases covering all patch operations (add, remove, replace, move, copy, test)

Features

  • Supports all RFC6902 patch operations
  • Atomic application - if any patch fails, result is undefined
  • Works with nested objects, arrays, and special characters in keys
  • Proper error handling in both strict and non-strict modes

Usage

# Add a new field
json.patch({"a": {"foo": 1}}, [{"op": "add", "path": "/a/bar", "value": 2}])
# Result: {"a": {"foo": 1, "bar": 2}}

# Multiple operations
json.patch(obj, [
  {"op": "add", "path": "/a/bar", "value": 2},
  {"op": "replace", "path": "/a/foo", "value": 42}
])

@microsoft-github-policy-service

@ma-ts the command you issued was incorrect. Please try again.

Examples are:

@microsoft-github-policy-service agree

and

@microsoft-github-policy-service agree company="your company"

@anakrish
Copy link
Collaborator

@ma-ts Thanks for the contribution. Do also add v0/jsonpatch and v1/jsonpatch to https://github.com/microsoft/regorus/blob/main/tests/opa.passing to ensure that the OPA jsonpatch tests get run.

I happened to see that you have also created feature request in the Azure Policy repo. We are working on some interesting projects involving Azure Policy and Regorus. Hence, I'm curious whether you are already using Regorus.

@ma-ts
Copy link
Author

ma-ts commented Jul 26, 2025

Hi @anakrish, I will do that! And yes, all of this is part of a big policy overhaul in our organisation, and actually we are already using it in some services.

I am soon going to be open sourcing a project as well to provide a Rust-based ingress controller that uses Regorus and integrates natively with OIDC, and has special support for Entra ID

Copy link
Collaborator

@anakrish anakrish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ensure_args_count(span, name, params, args, 2)?;

let object_str = args[0].to_json_str()?;
let mut object: serde_json::Value = serde_json::from_str(&object_str)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let mut object: serde_json::Value = serde_json::from_str(&object_str)
let mut object: serde_json::Value = serde_json::to_value(&args[0])

ensure_array(name, &params[1], args[1].clone())?;

let patches_str = args[1].to_json_str()?;
let patches_json: serde_json::Value = serde_json::from_str(&patches_str)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let patches_json: serde_json::Value = serde_json::from_str(&patches_str)
let patches_json: serde_json::Value = serde_json::to_value(&args[1])


match json_patch::patch(&mut object, &patch) {
Ok(_) => {
let result_str = serde_json::to_string(&object)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let result_str = serde_json::to_string(&object)
let value : regorus::Value = serde_json::from_value&object)

@anakrish
Copy link
Collaborator

Hey @ma-ts, just a gentle ping on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Lib] Implement json.patch builtin

2 participants