Repository navigation
Conversation
|
This generally LGTM except the new required field on snapshots. The two failing jobs are due to a formatting issue in the prost-generated file. I’ll need to review the We’ll also need to justify the default step count, since it will be silently added to future evaluation through |
Agreed, I have no basis for deciding what the "correct" default value would be and chose something arbitrary. |
|
I think snapshots should carry the elapsed steps, as they carry elapsed time. I can handle that in a follow-up PR as needed. While experimenting on this idea, it appeared that the number of steps is not deterministic due to the use of hash-based data structures. Since there was care about deterministic step counting, I think that’s something we want to fix. We already use |
|
I’ve run the samples suite with a patch that keeps track of elapsed steps, they took between 1 and 72 steps. The example from https://doc.biscuitsec.org/recipes/role-based-access-control.html runs in 60 steps. I’ll run more tests on more realistic test cases, but I think I don’t know how far we can go on deterministic step tracking across implementations. Fact generation is exhaustive, but checks and policies can early abort, so a failing candidate being at the front or at the back of a list can have a visible effect. |
|
saoirse-a#2 explores what it could look like |
Agreed. The amount of work it takes is non-deterministic unless you define a specific order that evaluation is supposed to run in, which seems unrealistic to me. We'll need to specify this feature in a way that a particular run in a particular implementation is permitted to take fewer steps so long is it actually does less work. This could mean either because the implementation has some optimization or because the order it happened to examine candidates in in this run took fewer steps. This also means setting the step limit anywhere near where a legitimate token could hit it could mean non-deterministic failure, so it should be set pretty far above what real tokens look like. All of this is also true of the time limit of course, though the time limit has the added non-determinism added by physical hardware, language runtime, etc. If the highest any in the test corpus get is 72, 1000 doesn't seem like a bad default, some of those have more complex rule relations than I think would be common. |
Instead of iterating every visible fact to find candidate matches when querying, we index the FactSet by (name, arity). This makes finding candidate matches O(1) instead of O(facts). Move the step counter up so that we could a step for each candidate we encounter. This has the result that each step takes a roughly constant amount of work, rather than taking an amount of work determined by the number of facts there are. This makes it a more reliable limit on the amount of work performed during authorization. Also make most of the contents of datalog/mod.rs pub(crate) to avoid internal implementation details being part of the public API contract.
70a12ea to
3c21c94
Compare
This adds support for limiting the number of logical "steps" taken during biscuit authorization, as a way of limiting evaluation runtime without relying on wall clock time.
There are basically two ways a step is counted:
Steps are persisted through authorization so the same limit is used for rule evaluation and for all the checks and policies that run against the resolved world.
As a side change, we make the contents of the Datalog module mostly private to avoid leaking internal implementation details in the public API.