Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support query_parameters_to_set in response #663

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

sedovmik
Copy link

@sedovmik sedovmik commented Feb 6, 2025

Add support for query_parameters_to_set field in response to allow setting/overwriting query parameters before sending upstream. Similar to existing query_parameters_to_remove support.

Example usage in OPA policies:

package envoy.authz

default allow = true

query_parameters_to_set = {
   "user_id": "123",
   "tenant": "acme"
}

query_parameters_to_set = {
   "role": ["admin", "user"],
   "scope": ["read", "write"]
}

query_parameters_to_set = {
   "user_id": "123",
   "role": ["admin", "user"]
}

result["allowed"] = allow
result["query_parameters_to_set"] = query_parameters_to_set

@sedovmik sedovmik force-pushed the feat/query-set branch 2 times, most recently from 517ba53 to d4ddfb9 Compare February 6, 2025 00:24
@ashutosh-narkar ashutosh-narkar requested a review from tjons February 6, 2025 22:05

default allow = true

query_parameters_to_set := [
Copy link
Contributor

Choose a reason for hiding this comment

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

Great contribution!

Could you consider the following API:

query_parameters_to_set := {
  "foo": "value1",
  "bar": "value2",
}

It leads to less iterations and less memory allocations.

Copy link
Author

Choose a reason for hiding this comment

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

Thank you for the comment! I agree that the format could be simplified. I intended to keep it aligned with Envoy's config.core.v3.QueryParameter for implementation simplicity, but your suggestion is indeed more ergonomic.

Regarding multi-value parameters - In HTTP, it's possible to have multiple values for the same query parameter (e.g., ?foo=value1&foo=value2). To properly support this, I could add support for both value types (string and array of strings):

query_parameters_to_set := {
  "foo": "value1",             # single value
  "bar": ["value1", "value2"]  # multiple values
}

What are your thoughts? I'd be happy to update the implementation accordingly.

Copy link
Contributor

Choose a reason for hiding this comment

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

I fully support both value types.

Add support for query_parameters_to_set field in response to allow
setting/overwriting query parameters before sending upstream.
Similar to existing query_parameters_to_remove support.

Signed-off-by: Mikhail Sedov <[email protected]>
Change query_parameters_to_set to use a map format. The format
supports both single values and arrays for setting multiple
query parameters with the same key.

Example usage in OPA policies:

```rego
package envoy.authz

default allow = true

query_parameters_to_set = {
   "user_id": "123",
   "tenant": "acme"
}

query_parameters_to_set = {
   "role": ["admin", "user"],
   "scope": ["read", "write"]
}

query_parameters_to_set = {
   "user_id": "123",
   "role": ["admin", "user"]
}

result["allowed"] = allow
result["query_parameters_to_set"] = query_parameters_to_set

```

Signed-off-by: Mikhail Sedov <[email protected]>
return nil, fmt.Errorf("type assertion error, expected query_parameters_to_set to be a map but got '%T'", val)
}

var result []*ext_core_v3.QueryParameter
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you preallocate the capacity to improve the performance?

Suggested change
var result []*ext_core_v3.QueryParameter
result := make([]*ext_core_v3.QueryParameter, 0, len(params))

Value: v,
})
case []interface{}:
for _, item := range v {
Copy link
Contributor

Choose a reason for hiding this comment

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

Here you also could grow the slice using slices.Grow:

Suggested change
for _, item := range v {
result = slices.Grow(result, len(v))
for _, item := range v {

@regeda
Copy link
Contributor

regeda commented Feb 19, 2025

Please add this feature to the official OPA documentation (like open-policy-agent/opa#7241)

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.

2 participants