-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Add support for rule-level tracing #2089
Comments
This is a killer feature that we definitely need. Any updates you can provide on where this falls on the roadmap? And as far as interim alternatives go, the best thing I can think of to do is to include the result of all the child rules in the output of the queried rule if there is a failure, thereby having the "reason" show up in the decision logs under "result". something like this?
Does that seem like a sane approach? It certainly makes policy more verbose... |
I think it is something we would like to do, but it isn't actively under development. No specific timeline for when it would be added. I think this feature was primarily aimed at a use-case where some authz decision wanted to include a reason for a like better UX than a generic "not authorized". For the decision log as sort of an "after the fact" thing you have more options. Assuming that you mostly were interested in the decision log, consider that you can do all the slow tracing you want later on if you are using bundles w/ revisions configured in the manifest (https://www.openpolicyagent.org/docs/latest/management/#bundle-file-format ). The decision log entry includes the full input, query path, and revision (ie bundle source pointer) so you can re-run the exact same evaluation later on with tracing enabled to see exactly what happened. For including a reason back to the user I think the most common approach is to use the "partial" rules (you'll see tons of policies around with default authz = false
authz {
count(deny) == 0
count(allow) > 0
}
allow[msg] {
employee
2fa
special_role
msg := "do_thing 1 rules all passed"
}
allow[msg] {
admin
msg := "do_thing 2 rules all passed"
}
deny[msg] {
not admin
not 2fa
msg := "non admins require 2fa"
} With something like this you can get your boolean yes/no easily by looking at I guess too as a disclaimer this is by no way a prescriptive thing, just an example of another (maybe easier) way to think about writing that type of policy. |
Being able to re-run previous queries with slow-tracing on does seem useful, but I don't think it's a full solution for us, for a couple of reasons:
I think the ideal result for us is that decision logs contain the data necessary for us to visualize the reason a policy decision was rendered. I'm not exactly sure what that could/should look like though. The snippet you posted does seem like a good approach, although if a caller just calls
The tricky part I guess will just be propagating all those "reasons" through a bunch of nested rules. Thoughts? |
That type of structured output plus limiting the query does seem like the best approach to take. While I agree that it could be tricky to fill in the reasons (depending on the policies) there are at least a few OPA users that have been successful with that type of approach. There is a lot of prior art to build on for the |
The part I'm struggling with in regard to the authz/allow/deny pattern is this: If all of the package rock
rock := { "sparkles"} package shiny
import rock
default yes = false
yes {
count(reason) > 0
}
reason[msg] {
rock["sparkles"]
msg := "the rock sparkles"
}
reason[msg] {
rock["shimmers"]
msg := "the rock shimmers"
} package rare
import rock
default yes = false
yes {
count(reason) > 0
}
reason[msg] {
rock["hard_to_find"]
msg := "the rock is hard to find"
}
reason[msg] {
rock["expensive_to_mine"]
msg := "the rock is expensive to mine"
} package valuable
import shiny
import rare
default yes = false
yes {
count(reason) > 0
}
reason[msg] {
shiny.yes
rare.yes
msg := shiny.reason | rare.reason
} In the above example, the rock is shiny but not rare, and thus not valuable. I want the caller to know why the rock isn't valuable. If I call {
"result": {
"yes": false,
"reason": "the rock is not valuable because the rock is not rare, because it is neither hard to find nor expensive to mine"
}
} Is there a way to do this? |
Today, we can't generate an explanation for why access is allowed or denied without it being encoded into the policy. In the example above, the policy provides a reason for why access is allowed -- if you wanted to provide reasons why access is denied then you would have to encode those into the policy as well. Maybe something like this would work?
You would then query for Typically we don't see people providing reasons why access is granted--they provide reasons why access was not granted. E.g.,
|
It sounds like this would handle #2897. |
This issue has been automatically marked as inactive because it has not had any activity in the last 30 days. |
It would be nice to have a cheap, efficient rule-level tracer that could be enabled in more situations than the current tracing implementation allows. The current tracing implementation operates at the expression level and requires that the evaluator to plug all of in-scope variables to produce values for the trace consumer. While this gives users complete visibility into the execution of the policy, in many cases it's more information than needed. The plug operation in particular is very expensive and means that the tracer cannot be used in latency-sensitive use cases.
A rule level tracer that simply reported the rules that exited and failed to exit would provide a decent starting place. For each rule that exited or failed to exit, the report would include the AST location. An even higher-level report would simply be the names of the virtual documents that were defined or undefined during evaluation.
Importantly, this kind of tracer should have minimal impact on policy execution performance. It should be possible for users to configure OPA to always generate these reports. This could help greatly with providing explanations about why the policy allowed or denied access.
The text was updated successfully, but these errors were encountered: