reauthorize only practically works with one unknown #1465
Labels
bug
Something isn't working. This is as high priority issue.
pending-triage
The cedar maintainers haven't looked at this yet. Automicaly added to all new issues.
Before opening, please confirm:
Bug Category
Policy Evaluation
Describe the bug
Hi! Thanks for open sourcing Cedar, I'm really excited to use it in a Kubernetes (API) context. (And yes, I've been in contact with Micah already some time :D)
One of the gotchas I ran into the other day when experimenting with partial evaluation for multi-stage authorizations, when gradually supplying more data as needed, was that practically (usually) only one unknown is supported, as the partial evaluation stops whenever it encounters a residual on the LHS of an && (#1445)
So for a policy that refers to two unknowns (
resource.first_unknown
andresource.second_unknown
) in the initial partial_evaluate stage, the following happens:partial_evaluate
without the two unknowns specified simplifies the policy the best it can, until it seesunknown("first_unknown") && resource.second_unknown && ... more concrete stuff
, and feeds this into a partial response. If evaluation would have proceeded fully, or until an error occurs (Full Evaluation Option for Policy Expressions. #1445), thenresource.second_unknown
would have evaluated tounknown("second_unknown")
, but it did not.reauthorize
with the two unknowns now specified first traverses the expression and maps unknowns to concrete values, but as partial_evaluate returned early, it is not known at this time thatresource.second_unknown
will evaluate tounknown("second_unknown")
, so second_unknown is not populated from the reauthorize mappings, onlyunknown("first_unknown")
is mapped.partial_evaluate
is invoked on the mapped expression, and is able to concretize the first unknown (let's assume, to true), thus proceeding to the second unknown, first now realizing that it is unknown. However, the reauthorize mappings are not part of this stage, thus must the PE terminate at the residualunknown("second_unknown") && ... more concrete stuff
, althoughunknown("second_unknown")
indeed was concretely known at reauthorize time.I played with some quick ways to fix this, for my own learning and exploration of the Cedar codebase. In simplicity order:
partial_evaluate
pass would make PE realize both resource fields are indeed unknowns. However, this has some limiations, especially around typing and errors.expr.substitute
and thenpartial_evaluate
in a loop until N times inreauthorize
works, but it's really hacky, inefficient, and won't work in a generic way (only until N unknowns)reauthorize
topartial_evaluate
, that is, add anOption
with the mappings hashmap as an argument to internal functions ofpartial_interpret
, and substitute the unknowns on the fly when encountering one, allowing to resolve them directly.(One detail, I here described
resource.first_unknown
andresource.second_unknown
as two different attributes, but I think they can in fact just be two expr references to the same attribute.)I have validated that option 3 works locally, and I can send a PR for it.
It could resolve the issue while RFC 95, indeed the long-term solution, is implemented.
I can send the PR later today, to show the sketch of it, to have something concrete to discuss about, but also I understand if we don't want to make the current partial evaluator more complex, and focus on the typed PE instead in the RFC 95 proposal.
Expected behavior
When
reauthorize
is called with mappings to resolve unknowns, all given unknowns will be concretized correctly.Reproduction steps
See code snippet below, using latest Cedar version.
Code Snippet
Log output
Expected "Allowed" output.
Additional configuration
No response
Operating System
No response
Additional information and screenshots
No response
The text was updated successfully, but these errors were encountered: