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

Confusing difference between eval --input flag and api input body #4218

Closed
LucasRoesler opened this issue Jan 12, 2022 · 10 comments
Closed

Confusing difference between eval --input flag and api input body #4218

LucasRoesler opened this issue Jan 12, 2022 · 10 comments

Comments

@LucasRoesler
Copy link

Short description

Hi, I recently started researching OPA for a project and started by creating some sample policies and writing a short introduction for my teammates.

I initially started with the

opa eval --input input.json -b .  "data.demo.authz.allow" 

to quickly iterate on my example policies.

I got everything working and overall I am pretty excited, but the same policy and input would fail when an API call

curl -X POST -H "Content-Type: application/json" -d @input.json "http://localhost:8181/v1/data/demo/authz/allow?explain=full&pretty=true"

Steps To Reproduce

To reproduce I created a demo rule

package demo.authz

default allow = false

allow {
	input.user.title == "sudo"
}

allow {
	input.user.title == "admin"
}

and this input file

{
    "user": {
        "title": "sudo"
    }
}
  • Running with the CLI produces

    $ opa eval -i input.json -b .  "data.demo.authz.allow" --format=pretty --explain=full
    query:1                 Enter data.demo.authz.allow = _
    query:1                 | Eval data.demo.authz.allow = _
    query:1                 | Index data.demo.authz.allow (matched 1 rule, early exit)
    example/demo.rego:5     | Enter data.demo.authz.allow
    example/demo.rego:6     | | Eval input.user.title = "sudo"
    example/demo.rego:5     | | Exit data.demo.authz.allow early
    query:1                 | Exit data.demo.authz.allow = _
    query:1                 Redo data.demo.authz.allow = _
    query:1                 | Redo data.demo.authz.allow = _
    example/demo.rego:5     | Redo data.demo.authz.allow
    example/demo.rego:6     | | Redo input.user.title = "sudo"
    true
    
  • But with the server using opa run -s -b . -w, the same input file fails as a request

    curl -X POST -H "Content-Type: application/json" -d @input.json "http://localhost:8181/v1/data/demo/authz/allow?explain=full&pretty=true"

    but it would return results like this

    {
        "decision_id": "5705060b-5d48-46bf-abdb-1c4ceb6e40ae",
        "explanation": [
            "query:1                 Enter data.demo.authz.allow = _",
            "query:1                 | Eval data.demo.authz.allow = _",
            "query:1                 | Index data.demo.authz.allow (matched 0 rules)",
            "example/demo.rego:3     | Enter data.demo.authz.allow",
            "example/demo.rego:3     | | Eval true",
            "example/demo.rego:3     | | Exit data.demo.authz.allow",
            "query:1                 | Exit data.demo.authz.allow = _",
            "query:1                 Redo data.demo.authz.allow = _",
            "query:1                 | Redo data.demo.authz.allow = _",
            "example/demo.rego:3     | Redo data.demo.authz.allow",
            "example/demo.rego:3     | | Redo true"
        ],
        "result": false
    }
    

Expected behavior

Ideally, I would expect the the same file to work for both opa eval and as a request to the opa server.

Alternatively, some kind of validation error or logging from the API would also have been helpful. I am not sure it is 100% possible for OPA to know my rule requires an input but certainly it could validate that I sent extra unknown fields in my request and either return an validation error or maybe some logging or perhaps some other data while tracing the request to give a hint that the request body might be wrong. It took me a long time to think about using print(input) and find out that it was undefined mostly because I missed the print function when looking for it in the reference.

Additional context

Now knowing the issue, i was able to go back and see that this is addressed in the docs For example, it is highlighted here
image
I think the issue I had is that I had already jumped into experimenting with opa eval so I was no longer following along with the Intro docs and so I thought I knew what I was doing.

This is definitely human error

@anderseknert
Copy link
Member

Thanks for the detailed writeup about your experience @LucasRoesler 👍

Yeah, this definitely comes up from time to time, and I agree that it's an easy one to miss when starting out with OPA. One thing to note here is that you can use the /v0 API for exactly this functionality. That's often used by webhooks from clients where you don't control the format of the input, such as when the Kubernetes API server sends AdmissionReview objects to OPA for validating or mutating admission control.

This is detailed in the OPA REST API documentation, but perhaps we could do better surfacing this elsewhere in the docs as well. If you have any suggestions as to where, that'd be great!

@LucasRoesler
Copy link
Author

Thank for the suggestion, I will take a look at it.

@srenatus
Copy link
Contributor

Somewhat unrelated (i.e. it won't help here), but wouldn't it be nice if --input worked a bit more like --data? I'm thinking that this should become a reality:

$ echo '{"foo": 300 }' > input.json
$ opa eval --input input:input.json input
{ "input": {"foo": 300 }}
$ opa eval --input review:input.json input
{ "review": {"foo": 300 }}
$ opa eval --input something.nested:input.json input
{ "something": {"nested": {"foo": 300 }}}

i.e. supporting prefixes to wrap the input document.

@anderseknert
Copy link
Member

Looks good to me @srenatus! I had no idea --data worked like that though! It does?

@srenatus
Copy link
Contributor

Yup. (With some caveats on windows #4174...)

$ opa eval -d nice.caps:capabilities.json -fpretty data | head
{
  "nice": {
    "caps": {
      "builtins": [
        {
          "decl": {
            "args": [
              {
                "type": "number"

@anderseknert
Copy link
Member

Cool (except for the Windows issue)! Is this documented somewhere? I didnt see it mentioned in opa eval --help.

@srenatus
Copy link
Contributor

@anderseknert
Copy link
Member

That's nice. We should copy that into the opa eval docs IMHO.

@stale
Copy link

stale bot commented Feb 13, 2022

This issue has been automatically marked as inactive because it has not had any activity in the last 30 days.

@stale stale bot added the inactive label Feb 13, 2022
@anderseknert
Copy link
Member

Alternatively, some kind of validation error or logging from the API would also have been helpful.

The OPA server will now print a warning when the input attribute is missing when sending POST requests to the v1/data API: #4386

Closing as resolved.

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

No branches or pull requests

3 participants