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

opa: pass URL query parameters to OPA policy evaluation #3207

Merged
merged 6 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions filters/openpolicyagent/internal/envoy/skipperadapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ import (

func AdaptToExtAuthRequest(req *http.Request, metadata *ext_authz_v3_core.Metadata, contextExtensions map[string]string, rawBody []byte) (*ext_authz_v3.CheckRequest, error) {

if !utf8.ValidString(req.URL.Path) {
mefarazath marked this conversation as resolved.
Show resolved Hide resolved
return nil, fmt.Errorf("invalid utf8 in path: %q", req.URL.Path)
}

headers := make(map[string]string, len(req.Header))
for h, vv := range req.Header {
// This makes headers in the input compatible with what Envoy does, i.e. allows to use policy fragments designed for envoy
Expand All @@ -25,7 +29,7 @@ func AdaptToExtAuthRequest(req *http.Request, metadata *ext_authz_v3_core.Metada
Http: &ext_authz_v3.AttributeContext_HttpRequest{
Host: req.Host,
Method: req.Method,
Path: req.URL.Path,
Path: req.URL.RequestURI(),
mefarazath marked this conversation as resolved.
Show resolved Hide resolved
Headers: headers,
RawBody: rawBody,
},
Expand All @@ -35,9 +39,5 @@ func AdaptToExtAuthRequest(req *http.Request, metadata *ext_authz_v3_core.Metada
},
}

if !utf8.ValidString(ereq.Attributes.Request.Http.Path) {
return nil, fmt.Errorf("invalid utf8 in path: %q", ereq.Attributes.Request.Http.Path)
}

return ereq, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,34 @@ func TestAuthorizeRequestFilter(t *testing.T) {
backendHeaders: make(http.Header),
removeHeaders: make(http.Header),
},
{
msg: "Allow Requests with trailing ? in URL",
filterName: "opaAuthorizeRequest",
bundleName: "somebundle.tar.gz",
regoQuery: "envoy/authz/allow",
requestPath: "/allow?",
mefarazath marked this conversation as resolved.
Show resolved Hide resolved
requestMethod: "GET",
contextExtensions: "",
expectedStatus: http.StatusOK,
expectedBody: "Welcome!",
expectedHeaders: make(http.Header),
backendHeaders: make(http.Header),
removeHeaders: make(http.Header),
},
{
msg: "Allow Requests with query parameters",
filterName: "opaAuthorizeRequest",
bundleName: "somebundle.tar.gz",
regoQuery: "envoy/authz/allow",
requestPath: "/allow-with-query?pass=yes&id=1&id=2",
requestMethod: "GET",
contextExtensions: "",
expectedStatus: http.StatusOK,
expectedBody: "Welcome!",
expectedHeaders: make(http.Header),
backendHeaders: make(http.Header),
removeHeaders: make(http.Header),
},
{
msg: "Allow Matching Context Extension",
filterName: "opaAuthorizeRequest",
Expand Down Expand Up @@ -96,6 +124,19 @@ func TestAuthorizeRequestFilter(t *testing.T) {
backendHeaders: make(http.Header),
removeHeaders: make(http.Header),
},
{
msg: "Simple Forbidden with Query Parameters",
filterName: "opaAuthorizeRequest",
bundleName: "somebundle.tar.gz",
regoQuery: "envoy/authz/allow",
requestPath: "/allow-with-query?tofail=true",
requestMethod: "GET",
contextExtensions: "",
expectedStatus: http.StatusForbidden,
expectedHeaders: make(http.Header),
backendHeaders: make(http.Header),
removeHeaders: make(http.Header),
},
{
msg: "Allow With Structured Rules",
filterName: "opaAuthorizeRequest",
Expand Down Expand Up @@ -311,6 +352,12 @@ func TestAuthorizeRequestFilter(t *testing.T) {
input.parsed_path = [ "allow" ]
}

allow {
input.parsed_path = [ "allow-with-query" ]
input.parsed_query.pass == ["yes"]
input.parsed_query.id == ["1", "2"]
}

allow_context_extensions {
input.attributes.contextExtensions["com.mycompany.myprop"] == "myvalue"
}
Expand Down
21 changes: 21 additions & 0 deletions filters/openpolicyagent/opaserveresponse/opaserveresponse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ func TestAuthorizeRequestFilter(t *testing.T) {
expectedBody: "Welcome from policy!",
expectedHeaders: map[string][]string{"X-Ext-Auth-Allow": {"yes"}},
},
{
msg: "Allow With Structured Rules and Query Params",
filterName: "opaServeResponse",
bundleName: "somebundle.tar.gz",
regoQuery: "envoy/authz/allow_object",
requestPath: "/allow/structured/with-query?pass=yes",
expectedStatus: http.StatusOK,
expectedBody: "Welcome from policy!",
expectedHeaders: map[string][]string{"X-Ext-Auth-Allow": {"yes"}},
},
{
msg: "Allow With opa.runtime execution",
filterName: "opaServeResponse",
Expand Down Expand Up @@ -164,6 +174,17 @@ func TestAuthorizeRequestFilter(t *testing.T) {
"http_status": 200
}
}

allow_object = response {
input.parsed_path = [ "allow", "structured", "with-query" ]
input.parsed_query.pass == ["yes"]
response := {
"allowed": true,
"headers": {"x-ext-auth-allow": "yes"},
"body": "Welcome from policy!",
"http_status": 200
}
}

allow_object = response {
input.parsed_path = [ "allow", "production" ]
Expand Down
Loading